angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Utiliser IPv6 avec Microk8s

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

3 décembre 2024
post main image
https://www.pexels.com/@sedanur-kunuk-78972032

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

Laissez un commentaire

Commentez anonymement ou connectez-vous pour commenter.

Commentaires

Laissez une réponse

Répondez de manière anonyme ou connectez-vous pour répondre.