IPv6 dans Docker et Kubernetes : guide du réseau de conteneurs
Configurez IPv6 pour les applications conteneurisées. Couvre les paramètres du démon Docker, le dual-stack Kubernetes, les plugins CNI et l'exposition de services.
Le réseau de conteneurs utilise IPv4 par défaut. C'est un problème si vous exécutez des charges de travail de production en 2024.
TL;DR - Résumé rapide
Points clés :
- Docker et Kubernetes utilisent IPv4 uniquement par défaut ; IPv6 nécessite une configuration explicite
- Docker nécessite des modifications de daemon.json et des réseaux personnalisés avec le flag
--ipv6 - Kubernetes 1.23+ prend en charge le dual-stack stable avec IPv6 pour pods et services
- Les plugins CNI (Calico, Cilium, Flannel) gèrent le dual-stack différemment
Aller à : Configuration Docker | Dual-Stack Kubernetes | Plugins CNI | Tests
Pourquoi IPv6 dans les conteneurs#
Vos conteneurs peuvent être IPv4 uniquement tandis que le reste d'Internet passe à IPv6. Les réseaux mobiles, les FAI et les fournisseurs de cloud sont IPv6-first. Si vos services conteneurisés ne supportent pas IPv6, vous ajoutez de la latence via les passerelles NAT64 ou pire, vous manquez complètement des clients.
Les plateformes d'orchestration de conteneurs (Docker, Kubernetes, ECS, Nomad) ont été construites pendant l'ère IPv4. Le support IPv6 est venu plus tard comme une réflexion après coup. Les paramètres par défaut supposent toujours un réseau IPv4 uniquement.
Activer IPv6 n'est pas difficile, mais cela nécessite une configuration explicite à plusieurs couches : démon, réseau, conteneur et service. Manquez une couche et vous aurez une connectivité partielle qui casse mystérieusement.
Configuration IPv6 de Docker#
Le démon Docker n'active pas IPv6 par défaut. Vous devez le configurer dans /etc/docker/daemon.json.
Configuration du démon#
Créez ou modifiez /etc/docker/daemon.json :
{
"ipv6": true,
"fixed-cidr-v6": "fd00::/80",
"experimental": false,
"ip6tables": true
}Décomposition :
"ipv6": trueactive le support IPv6"fixed-cidr-v6"définit le sous-réseau pour les conteneurs (utiliser le préfixe ULA ou GUA)"ip6tables": trueactive les règles de pare-feu IPv6 (Docker 20.10+)
Pour la production avec des adresses globalement routables, utilisez le préfixe assigné par votre fournisseur :
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1234::/64"
}Redémarrez Docker pour appliquer les changements :
sudo systemctl restart dockerVérifiez qu'IPv6 est activé :
docker network inspect bridge | grep IPv6Vous devriez voir "EnableIPv6": true.
Réseau bridge par défaut#
Le réseau bridge par défaut n'obtient pas automatiquement IPv6 même après la configuration du démon. Créez un réseau personnalisé :
docker network create --ipv6 \
--subnet=172.20.0.0/16 \
--subnet=fd00:dead:beef::/48 \
mynetworkExécutez des conteneurs sur ce réseau :
docker run -d --network mynetwork nginxLes conteneurs reçoivent maintenant des adresses IPv4 et IPv6.
Réseaux définis par l'utilisateur#
Les réseaux bridge définis par l'utilisateur supportent le dual-stack :
docker network create --ipv6 \
--subnet=10.1.0.0/24 \
--gateway=10.1.0.1 \
--subnet=fd00:cafe::/64 \
--gateway=fd00:cafe::1 \
appnetworkLes conteneurs sur ce réseau peuvent communiquer via IPv6 :
# Terminal 1
docker run -it --rm --network appnetwork --name container1 alpine sh
# Terminal 2
docker run -it --rm --network appnetwork alpine sh
ping6 container1Le résolveur DNS intégré de Docker renvoie des enregistrements AAAA pour les noms de conteneurs lorsqu'IPv6 est activé.
NAT et routage IPv6#
Par défaut, Docker utilise NAT pour IPv4 mais peut ne pas faire de NAT IPv6. Cela dépend de votre configuration fixed-cidr-v6.
Avec les préfixes ULA (fd00::/8), vous avez besoin de NAT pour l'accès Internet :
# Activer le transfert IPv6
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Ajouter une règle de masquage
sudo ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADEAvec les préfixes GUA (globalement routables), routez directement sans NAT :
# Ajouter une route pour le sous-réseau de conteneurs
sudo ip -6 route add 2001:db8:1234::/64 via <docker-host-ipv6>Configurez le routeur en amont pour router votre sous-réseau de conteneurs vers l'hôte Docker.
Docker Compose IPv6#
Docker Compose nécessite une configuration IPv6 explicite dans la définition du réseau.
Exemple docker-compose.yml :
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
ports:
- "80:80"
- "[::]:8080:80" # Lier IPv6 explicitement
app:
image: myapp:latest
networks:
- frontend
- backend
db:
image: postgres:14
networks:
- backend
environment:
POSTGRES_HOST_AUTH_METHOD: trust
networks:
frontend:
enable_ipv6: true
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
- subnet: fd00:1::/64
gateway: fd00:1::1
backend:
enable_ipv6: true
ipam:
config:
- subnet: 172.21.0.0/16
- subnet: fd00:2::/64Le drapeau enable_ipv6: true est requis par réseau. La configuration IPAM (IP Address Management) assigne les sous-réseaux IPv4 et IPv6.
Syntaxe de liaison de port pour IPv6 :
ports:
- "80:80" # IPv4 et IPv6
- "0.0.0.0:8080:80" # IPv4 uniquement
- "[::]:8081:80" # IPv6 uniquement
- "127.0.0.1:8082:80" # IPv4 localhost
- "[::1]:8083:80" # IPv6 localhostDémarrez les services :
docker-compose up -dVérifiez que les conteneurs ont IPv6 :
docker-compose exec web ip -6 addr showDual-stack Kubernetes#
Kubernetes supporte le réseau dual-stack à partir de la version 1.21 (bêta) et 1.23 (stable).
Prérequis#
- Kubernetes 1.23 ou ultérieur
- Plugin CNI qui supporte le dual-stack (Calico, Cilium, Flannel, Weave)
- kube-proxy avec le mode dual-stack
- Support du fournisseur cloud (pour les services LoadBalancer)
Activer le dual-stack#
Pour les nouveaux clusters, activez le dual-stack pendant l'initialisation. Avec kubeadm :
# kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
networking:
podSubnet: "10.244.0.0/16,fd00:10:244::/56"
serviceSubnet: "10.96.0.0/16,fd00:10:96::/112"Initialisez le cluster :
kubeadm init --config kubeadm-config.yamlPour les Kubernetes gérés (EKS, GKE, AKS), activez le dual-stack pendant la création du cluster :
# EKS
eksctl create cluster \
--name mycluster \
--ip-family ipv4,ipv6
# GKE
gcloud container clusters create mycluster \
--enable-ip-alias \
--stack-type=IPV4_IPV6
# AKS
az aks create \
--resource-group myResourceGroup \
--name mycluster \
--network-plugin azure \
--ip-families IPv4,IPv6Vérifiez que le dual-stack est activé :
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDRs}'Vous devriez voir les CIDR IPv4 et IPv6.
Réseau de pods#
Les pods reçoivent des adresses des deux familles automatiquement. Aucune configuration spéciale n'est nécessaire dans la plupart des cas.
Exemple de pod :
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: nginx
image: nginxDéployez et vérifiez les adresses :
kubectl apply -f pod.yaml
kubectl get pod test-pod -o jsonpath='{.status.podIPs}'La sortie affiche IPv4 et IPv6 :
[{"ip":"10.244.1.5"},{"ip":"fd00:10:244:1::5"}]Les applications dans les pods doivent se lier à :: (toutes les adresses) ou 0.0.0.0 spécifiquement :
# Exemple Python - lier à IPv4 et IPv6
import socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
sock.bind(("::", 8080))
sock.listen(5)Ou lier à 0.0.0.0 pour IPv4 et :: pour IPv6 séparément.
Configuration de service#
Les services peuvent être IPv4 uniquement, IPv6 uniquement ou dual-stack. Contrôlez cela avec les champs ipFamilyPolicy et ipFamilies.
Service dual-stack (par défaut dans les clusters dual-stack) :
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ipFamilyPolicy: RequireDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app: myapp
ports:
- port: 80
targetPort: 8080Service IPv4 uniquement :
apiVersion: v1
kind: Service
metadata:
name: myservice-v4
spec:
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv4
selector:
app: myapp
ports:
- port: 80Service IPv6 uniquement :
apiVersion: v1
kind: Service
metadata:
name: myservice-v6
spec:
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv6
selector:
app: myapp
ports:
- port: 80Vérifiez les IP de service :
kubectl get svc myservice -o jsonpath='{.spec.clusterIPs}'Sortie :
["10.96.100.5","fd00:10:96::a5"]Services LoadBalancer#
Les services LoadBalancer provisionnent des équilibreurs de charge cloud avec des frontends dual-stack (si le fournisseur cloud le supporte).
apiVersion: v1
kind: Service
metadata:
name: web-lb
spec:
type: LoadBalancer
ipFamilyPolicy: RequireDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app: web
ports:
- port: 80
targetPort: 8080Vérifiez les IP externes :
kubectl get svc web-lbSortie :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
web-lb LoadBalancer 10.96.100.10 203.0.113.10,2001:db8:1234::10 80:30123/TCPTous les fournisseurs cloud ne supportent pas encore les équilibreurs de charge dual-stack. Vérifiez le support pour votre plateforme.
Contrôleurs Ingress#
Le support Ingress pour IPv6 dépend de l'implémentation du contrôleur.
Contrôleurs populaires avec support IPv6 :
- nginx-ingress : Supporte le dual-stack, écoute sur IPv4 et IPv6
- Traefik : Support dual-stack complet
- HAProxy Ingress : Supporte IPv6
- Contour : Capable dual-stack
Configurez nginx-ingress pour le dual-stack :
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: LoadBalancer
ipFamilyPolicy: RequireDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app.kubernetes.io/name: ingress-nginx
ports:
- name: http
port: 80
targetPort: http
- name: https
port: 443
targetPort: httpsLes ressources Ingress n'ont pas besoin de configuration IPv6 spéciale, elles fonctionnent automatiquement si le contrôleur le supporte.
Politiques réseau#
Les ressources NetworkPolicy supportent les blocs CIDR IPv6 :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ipv6
spec:
podSelector:
matchLabels:
app: myapp
ingress:
- from:
- ipBlock:
cidr: 2001:db8::/32
- ipBlock:
cidr: fd00::/8
egress:
- to:
- ipBlock:
cidr: ::/0
except:
- fc00::/7 # Bloquer ULALes règles IPv4 et IPv6 peuvent coexister dans la même politique.
Considérations sur les plugins CNI#
Différents plugins CNI gèrent le dual-stack différemment.
Calico#
Calico supporte le dual-stack avec des pools IP :
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: ipv4-pool
spec:
cidr: 10.244.0.0/16
ipipMode: Never
natOutgoing: true
nodeSelector: all()
---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: ipv6-pool
spec:
cidr: fd00:10:244::/56
natOutgoing: false
nodeSelector: all()Activez IPv6 dans Calico :
kubectl set env daemonset/calico-node -n kube-system IP6=autodetect
kubectl set env daemonset/calico-node -n kube-system FELIX_IPV6SUPPORT=trueCilium#
Cilium a un support dual-stack natif. Activez lors de l'installation :
helm install cilium cilium/cilium \
--namespace kube-system \
--set ipv4.enabled=true \
--set ipv6.enabled=true \
--set tunnel=disabled \
--set autoDirectNodeRoutes=trueFlannel#
Flannel nécessite le mode dual-stack dans la configuration DaemonSet :
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-flannel-cfg
namespace: kube-system
data:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"IPv6Network": "fd00:10:244::/56",
"Backend": {
"Type": "vxlan"
}
}Weave#
Weave supporte le dual-stack avec les deux modes IPAM :
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.IPALLOC_RANGE=10.244.0.0/16&env.IPALLOC_RANGE=fd00:10:244::/56"Pièges courants#
Liaison d'application#
Les applications doivent explicitement écouter sur les adresses IPv6. Se lier à 0.0.0.0 écoute uniquement sur IPv4.
Incorrect :
server.bind(("0.0.0.0", 8080)) # IPv4 uniquementCorrect :
server.bind(("::", 8080)) # IPv6 (et IPv4 si IPV6_V6ONLY=0)De nombreux langages utilisent par défaut IPv4 uniquement. Vérifiez la documentation de votre framework.
Résolution DNS#
Les requêtes DNS dans les environnements dual-stack renvoient les enregistrements A et AAAA. Les applications doivent essayer les deux, en préférant IPv6.
Certaines bibliothèques plus anciennes interrogent uniquement les enregistrements A. Mettez à jour les dépendances ou configurez la résolution DNS explicitement.
Règles de pare-feu#
Les pare-feu de conteneurs (iptables/ip6tables) nécessitent des règles pour les deux familles. Docker et Kubernetes gèrent cela automatiquement s'ils sont configurés correctement, mais les règles personnalisées peuvent bloquer IPv6.
Vérifiez les règles de pare-feu IPv6 :
sudo ip6tables -L -n -vConnectivité externe#
Les conteneurs avec IPv6 nécessitent un routage approprié vers les réseaux externes. Si votre hôte n'a pas de connectivité IPv6, les conteneurs non plus.
Testez d'abord l'IPv6 de l'hôte :
ping6 google.comSi cela échoue, corrigez le réseau de l'hôte avant de dépanner les conteneurs.
Services headless StatefulSet#
Les StatefulSets avec services headless renvoient les adresses IPv4 et IPv6 pour les noms DNS de pods :
nslookup web-0.myservice.default.svc.cluster.localLes applications se connectant aux pods StatefulSet doivent gérer gracieusement plusieurs adresses.
Test des déploiements dual-stack#
Déployez une application de test :
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app
spec:
replicas: 2
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: test-svc
spec:
type: LoadBalancer
ipFamilyPolicy: RequireDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app: test
ports:
- port: 80Appliquez et testez :
kubectl apply -f test-app.yaml
# Obtenir les IP de service
kubectl get svc test-svc
# Test IPv4
curl http://<ipv4-external-ip>
# Test IPv6
curl -6 http://[<ipv6-external-ip>]Depuis l'intérieur d'un pod, testez la connectivité dual-stack :
kubectl run -it --rm debug --image=alpine --restart=Never -- sh
# Dans le pod
apk add curl bind-tools
nslookup test-svc
curl -4 http://test-svc # IPv4
curl -6 http://test-svc # IPv6Considérations de production#
- Surveiller les deux familles d'adresses dans les outils d'observabilité
- Tester le comportement de basculement lorsqu'une famille est indisponible
- Configurer les contrôles de santé pour IPv4 et IPv6
- Documenter la topologie réseau y compris les préfixes IPv6
- Planifier l'allocation d'adresses IP pour éviter les conflits
- Activer IPv6 dans les pipelines CI/CD pour les tests
- Former l'équipe au dépannage dual-stack
Articles connexes#
- IPv6 pour les développeurs - Implémentation IPv6 au niveau application
- IPv6 dans AWS, Azure et GCP - Configuration IPv6 des plateformes cloud
- Activer IPv6 sur votre réseau - Déploiement IPv6 à l'échelle de l'infrastructure
Vérifiez la connectivité des conteneurs
Utilisez notre outil Ping et validateur IPv6 pour tester que vos services conteneurisés sont accessibles via IPv6.