Utiliser IPv6 avec Microk8s
La configuration du Microk8s à double pile est beaucoup plus facile que prévu.

Pour une partie de mon application qui consiste en plusieurs projets Docker-Compose, j'avais besoin d'accéder à des services externes exclusivement IPv6. Dans les posts précédents, j'ai écrit que j'avais déjà déplacé une partie de mon application de Docker vers Microk8s (Kubernetes). C'est la partie qui nécessite l'accès aux services IPv6 externes. L'application Docker communique avec l'application Microk8s en utilisant un NodePort ou Ingress Controller.
Ma machine de développement se trouve sur un réseau local IPv4 uniquement, et ma connexion internet est également IPv4. Je ne veux certainement pas changer ma connexion ISP d'IPv4 à IPv6.
Dans ce billet, nous créons un environnement de test IPv6, en fait un environnement dual-stack, où nous pouvons exécuter une application dans Microk8s qui peut accéder à un service fictif IPv6 fonctionnant sur une machine virtuelle créée avec VirtualBox.
Comme toujours, je fais cela sur Ubuntu 22.04 Desktop.
A propos des adresses IPv6
Bien qu'elles ne soient pas très complexes, de bonnes explications sur IPv6 peuvent être trouvées dans "IPv6 Explained for Beginners" (IPv6 expliqué pour les débutants), voir les liens ci-dessous, très utiles.
En bref, une adresse IPv6 se compose de 128 bits. Ceux-ci sont divisés en une partie réseau et une partie nœud, chacune ayant 64 bits. Dans le réseau, les 48 bits supérieurs sont utilisés pour le routage sur l'internet.
Nous utilisons ici la documentation IPv6 prefix, 2001:db8::/32. Extrait du document "Understanding the IPv6 Documentation Prefix : 2001:db8::/32", voir les liens ci-dessous : Il s'agit d'une plage d'adresses IPv6 réservée à la documentation, aux exemples et au matériel éducatif. Cette prefix a été choisie pour s'assurer que les adresses qui l'utilisent ne sont pas accidentellement acheminées sur l'internet, évitant ainsi les conflits avec les adresses IPv6 du monde réel.
Cela signifie que la partie réseau est de 32 bits. Pour notre réseau, nous ajoutons "abcd:0012".
Exemple d'adresse d'un nœud sur notre réseau :
2001:db8:abcd:12::1
Ce qui est l'abréviation de "abcd:0012" :
2001:0db8:abcd:0012:0000:0000:0000:0001
Le "préfixe" est comme le masque dans IPv4.
Activation et désactivation d'IPv6 sur Ubuntu
Dans Ubuntu , nous pouvons activer et désactiver les paramètres IPv6 à l'aide de la commande sysctl. Pour afficher les paramètres :
sysctl -a 2>/dev/null | grep disable_ipv6
Il y a longtemps, j'ai désactivé IPv6 sur ma machine de développement. J'ai ajouté ce qui suit :
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.tun0.disable_ipv6 = 1
dans le fichier :
/etc/sysctl.conf
Je dois maintenant commenter à nouveau ces lignes.
Nous pouvons également définir ces valeurs de manière temporaire, par exemple :
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0
Pour recharger tous les paramètres, nous lançons la commande :
sudo sysctl --system
Toutes les valeurs de 'disable_ipv6' doivent être à '0'.
Assurez-vous également que le fichier :
/etc/hosts
contienne les lignes suivantes, où ::1 est l'adresse de bouclage :
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Machine de développement et configuration de VirtualBox
La machine de développement, Ubuntu Desktop, utilisait déjà IPv4, j'ai juste eu besoin d'ajouter IPv6. Nous n'avons pas de passerelle ou de serveur DNS, nous avons donc simplement mis des adresses aléatoires.
En utilisant VirtualBox, nous créons un serveur Ubuntu 22.04. Nous attribuons les adresses suivantes à la machine de développement et à la nouvelle machine virtuelle :
Ubuntu 220.04 Desktop
Address: 2001:db8:abcd:12::1
Prefix: 64
Gateway: 2001:db8:abcd:12::2
DNS: Automatic
Routes: Automatic
Ubuntu 220.04 Server (Virtualbox)
Address: 2001:db8:abcd:12::1:1/64
Prefix: 64
Gateway: 2001:db8:abcd:12::2
DNS: Automatic
Routes: Automatic
Sur notre serveur VirtualBox Ubuntu 22.04, nous utilisons l'"adaptateur ponté" pour le réseau. Dans le serveur Ubuntu 22.04, nous éditons la configuration réseau dans :
/etc/netplan/00-installer-config.yaml
Contenu :
network:
ethernets:
enp0s3:
dhcp4: no
dhcp6: no
addresses:
- 192.168.1.26/24
- 2001:db8:abcd:12::1:1/64
nameservers:
addresses:
- 192.168.1.2
- 2606:4700:4700::1111
routes:
- to: default
via: 192.168.1.1
- to: default
via: "2001:db8:abcd:12::2"
version: 2
Notez que j'ai inclus les paramètres IPv4 ici. Je ne sais pas si les paramètres par défaut du serveur SSH incluent IPv6. Maintenant, nous pouvons nous connecter au moins via IPv4. Lorsque c'est fait, nous le réactivons :
sudo netplan apply
Sur les deux machines, nous pouvons vérifier les adresses IPv6 :.
Sur la machine de développement :
ip a | grep inet6
Résultat :
inet6 ::1/128 scope host
inet6 2001:db8:abcd:12::1/64 scope global noprefixroute
inet6 fe80::fe11:314e:9bb4:73c1/64 scope link noprefixroute
...
Sur la machine virtuelle :
ip a | grep inet6
Résultat : Sur la machine virtuelle : Résultat : Sur la machine de développement : Résultat : Sur la machine virtuelle : Résultat :
inet6 ::1/128 scope host
inet6 2001:db8:abcd:12::1:1/64 scope global
inet6 fe80::a00:27ff:feda:7026/64 scope link
...
Vérifier IPv6 sur les deux machines et si elles peuvent communiquer
Sur les deux machines, nous pouvons exécuter :
ping6 ::1
Résultat : Sur la machine de développement, nous envoyons un ping à la machine virtuelle :
64 bytes from ip6-localhost: icmp_seq=0 ttl=64 time=0,078 ms
64 bytes from ip6-localhost: icmp_seq=1 ttl=64 time=0,048 ms
64 bytes from ip6-localhost: icmp_seq=2 ttl=64 time=0,048 ms
Sur la machine de développement, nous envoyons un ping à la machine virtuelle :
ping6 2001:db8:abcd:12::1:1
Sur la machine virtuelle, nous envoyons un ping à la machine de développement :
ping6 2001:db8:abcd:12::1
Enfin, nous vérifions si nous pouvons exécuter un service sur la machine virtuelle et si nous pouvons accéder à ce service.
Sur la machine virtuelle, nous démarrons 'netcat', et le lions à l'adresse IPv6 :
nc -l 2001:db8:abcd:12::1:1 3492
Sur la machine de développement, nous démarrons 'telnet', tapons 'hello' et vérifions s'il y a un écho :
telnet -6 2001:db8:abcd:12::1:1 3492
Résultat :
Trying 2001:db8:abcd:12::1:1...
Connected to 2001:db8:abcd:12::1:1.
Escape character is '^]'.
hello
^]
telnet> quit
Connection closed.
Fonctionne, c'est bien.
Installation de Microk8s avec une double pile
Cela s'est avéré beaucoup plus facile que prévu. J'ai suivi les instructions de l'article 'How to configure network Dual-stack', voir les liens ci-dessous.
Sur la machine de développement, nous créons d'abord un fichier :
/var/snap/microk8s/common/.microk8s.yaml
avec le contenu suivant :
---
version: 0.1.0
extraCNIEnv:
IPv4_SUPPORT: true
IPv4_CLUSTER_CIDR: 10.3.0.0/16
IPv4_SERVICE_CIDR: 10.153.183.0/24
IPv6_SUPPORT: true
IPv6_CLUSTER_CIDR: fd02::/64
IPv6_SERVICE_CIDR: fd99::/108
extraSANs:
- 10.153.183.1
addons:
- name: dns
Note(s) :
- Nous activons 'dns' ici. Si vous ne le faites pas ici, vous devez le faire après avoir installé Microk8s !
- Nous attribuons ici des Local Addresses uniques (ULA), qui ne peuvent pas être acheminés sur l'internet public.
Ensuite, nous installons Microk8s :
snap install microk8s --classic
Vérifier si les pods reçoivent une adresse IPv4 et une adresse IPv6, par exemple en exécutant :
microk8s kubectl -n kube-system describe pod
Cela devrait donner quelque chose comme ceci pour chaque pod :
...
IPs:
IP: 10.3.105.121
IP: fd02::332e:7684:ac2:6979
...
Maintenant, nous lançons BusyBox dans Microk8s :
kubectl run -i -t busybox --image=busybox --restart=Never
Une fois l'exécution terminée, nous pouvons vérifier si une adresse IPv6 a été attribuée :
cat /etc/hosts
Résultat :
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.3.105.122 busybox
fd02::332e:7684:ac2:697a busybox
Tests IPv6 avec Microk8s
Sur la machine de développement, démarrez un listener 'netcat' :
nc -l 2001:db8:abcd:12::1 3491
Puis dans le terminal BusyBox, nous essayons de nous connecter, et nous tapons un message :
telnet -6 2001:db8:abcd:12::1 3491
Résultat :
Connected to 2001:db8:abcd:12::1
hello
^]
Console escape. Commands are:
l go to line mode
c go to character mode
z suspend telnet
e exit telnet
e
Lancez maintenant l'auditeur 'netcat' sur la machine virtuelle :
nc -l 2001:db8:abcd:12::1:1 3492
De nouveau, dans BusyBox sur la machine de développement, nous essayons de nous connecter :
telnet 2001:db8:abcd:12::1:1 3492
Il ne se connecte pas ! C'était à prévoir. Le trafic IPv6 sortant est bloqué.
Extrait de l'article "Enabling IPv6 for SC4SNMP", voir les liens ci-dessous : Le CNI par défaut utilisé pour microk8s est Calico. Pour que les pods puissent atteindre Internet via IPv6, vous devez activer le paramètre natOutgoing dans la configuration ipv6 ip pool de Calico. Pour le définir, créez le fichier yaml avec le contenu suivant:
# calico-ippool.yaml
---
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-ipv6-ippool
spec:
natOutgoing: true
Pour activer :
microk8s kubectl apply -f calico-ippool.yaml
Arrêtez et démarrez Microk8s :
microk8s stop
microk8s start
Maintenant, enlevez et redémarrez le pod BusyBox :
kubectl delete pod busybox
kubectl run -i -t busybox --image=busybox --restart=Never
De nouveau, dans BusyBox sur la machine de développement, nous essayons de nous connecter au lister dans la machine virtuelle et de taper un message :
telnet 2001:db8:abcd:12::1:1 3492
Résultat :
Connected to 2001:db8:abcd:12::1:1
hello
^]
Console escape. Commands are:
l go to line mode
c go to character mode
z suspend telnet
e exit telnet
e
Super, ça marche !
En savoir plus sur Calico et les pools d'adresses IP
Calico (Project Calico Documentation) est une open source solution de mise en réseau et de sécurité réseau pour les conteneurs, les machines virtuelles et les charges de travail natives basées sur l'hôte.
A partir de 'Microk8s - Configure Calico', voir les liens ci-dessous : Dans la plupart des cas [], la façon de changer la configuration de Calico est de patcher le cni.yaml déployé et de le réappliquer au cluster.
Pour vérifier les ressources apico de Calico :
kubectl api-resources | grep 'projectcalico.org'
Resultat :
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration
bgppeers crd.projectcalico.org/v1 false BGPPeer
blockaffinities crd.projectcalico.org/v1 false BlockAffinity
caliconodestatuses crd.projectcalico.org/v1 false CalicoNodeStatus
clusterinformations crd.projectcalico.org/v1 false ClusterInformation
felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration
globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy
globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet
hostendpoints crd.projectcalico.org/v1 false HostEndpoint
ipamblocks crd.projectcalico.org/v1 false IPAMBlock
ipamconfigs crd.projectcalico.org/v1 false IPAMConfig
ipamhandles crd.projectcalico.org/v1 false IPAMHandle
ippools crd.projectcalico.org/v1 false IPPool
ipreservations crd.projectcalico.org/v1 false IPReservation
kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration
networkpolicies crd.projectcalico.org/v1 true NetworkPolicy
networksets crd.projectcalico.org/v1 true NetworkSet
Pour obtenir les pools d'IP :
kubectl get ippools
Résultat :
NAME AGE
default-ipv4-ippool 11d
default-ipv6-ippool 11d
Pour décrire les pools d'adresses IP :
kubectl describe IPPool
Résultat : Pour décrire les pools d'adresses IP : Résultat : Pour décrire les pools d'adresses IP
Name: default-ipv4-ippool
Namespace:
Labels:
Annotations: projectcalico.org/metadata: {"uid":"421fa69c-6657-4bd3-8bba-a06681c33c82","creationTimestamp":"2024-11-21T14:11:25Z"}
API Version: crd.projectcalico.org/v1
Kind: IPPool
Metadata:
Creation Timestamp: 2024-11-21T14:11:25Z
Generation: 1
Resource Version: 108882
UID: 50e3ccfc-627d-42f8-aaa3-a61e6553f8ed
Spec:
Allowed Uses:
Workload
Tunnel
Block Size: 26
Cidr: 10.3.0.0/16
Ipip Mode: Never
Nat Outgoing: true
Node Selector: all()
Vxlan Mode: Always
Events:
Name: default-ipv6-ippool
Namespace:
Labels:
Annotations: projectcalico.org/metadata: {"uid":"8377dd46-681d-4dbd-88a4-86e04a1d52c3","creationTimestamp":"2024-11-21T14:11:25Z"}
API Version: crd.projectcalico.org/v1
Kind: IPPool
Metadata:
Creation Timestamp: 2024-11-21T14:11:25Z
Generation: 2
Resource Version: 1506748
UID: 49501699-831f-4317-9c9f-2d2b15168547
Spec:
Allowed Uses:
Workload
Tunnel
Block Size: 122
Cidr: fd02::/64
Ipip Mode: Never
Nat Outgoing: true
Node Selector: all()
Vxlan Mode: Always
Events:
Notez que 'Nat Outgoing' est 'true' à la fois pour 'default-ipv4-ippool' et 'default-ipv6-ippool'.
Nous pouvons également utiliser calicoctl. Mais nous devons d'abord l'installer.
Pour obtenir la version actuelle de Calico, installez-la dans Microk8s :
kubectl -n kube-system describe pod calico-kube-controllers-759cd8b574-wscp9 | grep Image
Résultat :
Image: docker.io/calico/kube-controllers:v3.25.1
Image ID: docker.io/calico/kube-controllers@sha256:02c1232ee4b8c5a145c401ac1adb34a63ee7fc46b70b6ad0a4e068a774f25f8a
Cela signifie que la version actuelle de Calico est :
v3.25.1
Pour obtenir le manifeste calicoctl :
wget https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calicoctl.yaml
Pour l'activer :
kubectl apply -f calicoctl.yaml
Pour vérifier qu'il fonctionne :
kubectl get pods -A
Résultat :
NAMESPACE NAME READY STATUS RESTARTS AGE
...
kube-system calicoctl 1/1 Running 0 2m17s
...
Pour obtenir les profils calico :
kubectl exec -ti -n kube-system calicoctl -- /calicoctl get profiles -o wide
Résultat :
NAME LABELS
projectcalico-default-allow
kns.default pcns.kubernetes.io/metadata.name=default,pcns.projectcalico.org/name=default
kns.ingress pcns.kubernetes.io/metadata.name=ingress,pcns.projectcalico.org/name=ingress
kns.kube-node-lease pcns.kubernetes.io/metadata.name=kube-node-lease,pcns.projectcalico.org/name=kube-node-lease
...
Pour créer un alias calicoctl :
alias calicoctl="kubectl exec -i -n kube-system calicoctl -- /calicoctl"
Nous pouvons maintenant exécuter la commande ci-dessus comme suit :
calicoctl get profiles -o wide
Nous pouvons également utiliser calicoctl pour obtenir les pools d'adresses IP :
calicoctl get ippools
Résultat :
NAME CIDR SELECTOR
default-ipv4-ippool 10.3.0.0/16 all()
default-ipv6-ippool fd02::/64 all()
Pour en savoir plus :
calicoctl get IPPool default-ipv6-ippool -o wide
Résultat :
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv6-ippool fd02::/64 true Never Always false false all()
Nous pouvons supprimer et créer un pool d'adresses IP :
calicoctl delete ippool <ippool-to-delete>
cat <<EOF | calicoctl create -f -
- apiVersion: v1
kind: ipPool
metadata:
cidr: fd0e:c226:9228:fd1a::/64
spec: {}
EOF
Ou remplacer un pool d'adresses IP existant. Exemple :
calicoctl replace -f - << EOF
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv6-ippool
spec:
blockSize: 122
cidr: fd01::/64
ipipMode: Never
nodeSelector: all()
vxlanMode: Never
natOutgoing: true
EOF
Résumé
Nous avons créé un environnement de test IPv6 pour les applications Microk8s qui doivent accéder à des services externes IPv6. En utilisant VirtualBox , nous avons créé une machine virtuelle serveur Ubuntu et activé IPv6 à la fois sur la machine de développement et sur la machine virtuelle. Nous avons ensuite installé la double pile Microk8s sur la machine de développement et activé le trafic IPv6 sortant. Maintenant nous pouvons 'telnet' à l'intérieur de Microk8s sur la machine de développement vers un service IPv6 fonctionnant sur la machine virtuelle.
Liens / crédits
Building a multi-node IPv6-enabled bare-metal kubernetes cluster with microk8s, metallb, longhorn and VyOS
https://blog.mowoe.com/building-a-multi-node-ipv6-enabled-bare-metal-kubernetes-cluster-with-microk8s-metallb-longhorn-and-vyos.html
calicoctl user reference
https://docs.tigera.io/calico/latest/reference/calicoctl/overview
How to configure network Dual-stack
https://discuss.kubernetes.io/t/how-to-configure-network-dual-stack/24784
IPv6 Explained for Beginners
http://www.steves-internet-guide.com/ipv6-guide
IPv6 masquerading for egress on microk8s on EC2
https://www.checklyhq.com/blog/ipv6-masquerading-for-egress-on-microk8s-on-ec2
Kubernetes - IPv4/IPv6 dual-stack
https://kubernetes.io/docs/concepts/services-networking/dual-stack
Microk8s - Configure Calico
https://microk8s.io/docs/change-cidr
Understanding the IPv6 Documentation Prefix: 2001:db8::/32
https://ipv6.net/blog/understanding-the-ipv6-documentation-prefix-2001db8-32
En savoir plus...
Kubernetes Microk8s Networking
Récent
- Graphique de séries temporelles avec Flask, Bootstrap et Chart.js
- Utiliser IPv6 avec Microk8s
- Utilisation de Ingress pour accéder à RabbitMQ sur un cluster Microk8s
- Galerie vidéo simple avec Flask, Jinja, Bootstrap et JQuery
- Planification de base des tâches avec APScheduler
- Un commutateur de base de données avec HAProxy et HAProxy Runtime API
Les plus consultés
- Utiliser PyInstaller et Cython pour créer un exécutable Python
- Utilisation des Python's pyOpenSSL pour vérifier les certificats SSL téléchargés d'un hôte
- Connexion à un service sur un hôte Docker à partir d'un conteneur Docker
- Graphique de séries temporelles avec Flask, Bootstrap et Chart.js
- SQLAlchemy : Utilisation de Cascade Deletes pour supprimer des objets connexes
- Utiliser UUIDs au lieu de Integer Autoincrement Primary Keys avec SQLAlchemy et MariaDb