IPv6 en Docker y Kubernetes: Guía de Redes de Contenedores
Configura IPv6 para aplicaciones contenedorizadas. Cubre configuración del daemon Docker, dual-stack de Kubernetes, plugins CNI y exposición de servicios.
Las redes de contenedores usan IPv4 por defecto. Eso es un problema si estás ejecutando cargas de trabajo de producción en 2024.
TL;DR - Resumen rápido
Puntos clave:
- Docker y Kubernetes usan IPv4 por defecto; IPv6 requiere configuración explícita
- Docker necesita cambios en daemon.json y redes personalizadas con flag
--ipv6 - Kubernetes 1.23+ soporta dual-stack estable con pods y servicios IPv6
- Los plugins CNI (Calico, Cilium, Flannel) manejan dual-stack de manera diferente
Ir a: Configuración Docker | Dual-Stack Kubernetes | Plugins CNI | Pruebas
Por Qué IPv6 en Contenedores#
Tus contenedores podrían ser solo IPv4 mientras el resto de Internet se mueve a IPv6. Las redes móviles, ISPs y proveedores cloud son IPv6-first. Si tus servicios contenedorizados no soportan IPv6, estás añadiendo latencia a través de gateways NAT64 o peor: perdiendo clientes por completo.
Las plataformas de orquestación de contenedores (Docker, Kubernetes, ECS, Nomad) fueron construidas durante la era IPv4. El soporte IPv6 llegó después como una idea tardía. Los valores predeterminados todavía asumen redes solo IPv4.
Habilitar IPv6 no es difícil, pero requiere configuración explícita en múltiples capas: daemon, red, contenedor y servicio. Falla una capa y tendrás conectividad parcial que se rompe misteriosamente.
Configuración IPv6 de Docker#
El daemon de Docker no habilita IPv6 por defecto. Necesitas configurarlo en /etc/docker/daemon.json.
Configuración del Daemon#
Crea o modifica /etc/docker/daemon.json:
{
"ipv6": true,
"fixed-cidr-v6": "fd00::/80",
"experimental": false,
"ip6tables": true
}Desglosando esto:
"ipv6": truehabilita soporte IPv6"fixed-cidr-v6"establece la subred para contenedores (usar prefijo ULA o GUA)"ip6tables": truehabilita reglas de firewall IPv6 (Docker 20.10+)
Para producción con direcciones globalmente enrutables, usa el prefijo asignado por tu proveedor:
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1234::/64"
}Reinicia Docker para aplicar cambios:
sudo systemctl restart dockerVerifica que IPv6 esté habilitado:
docker network inspect bridge | grep IPv6Deberías ver "EnableIPv6": true.
Red Bridge Predeterminada#
La red bridge predeterminada no obtiene IPv6 automáticamente incluso después de la configuración del daemon. Crea una red personalizada:
docker network create --ipv6 \
--subnet=172.20.0.0/16 \
--subnet=fd00:dead:beef::/48 \
mynetworkEjecuta contenedores en esta red:
docker run -d --network mynetwork nginxLos contenedores ahora reciben direcciones tanto IPv4 como IPv6.
Docker Compose IPv6#
Docker Compose requiere configuración IPv6 explícita en la definición de red.
Ejemplo docker-compose.yml:
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
ports:
- "80:80"
- "[::]:8080:80" # Enlazar IPv6 explícitamente
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::/64La bandera enable_ipv6: true es requerida por red. La configuración IPAM (IP Address Management) asigna subredes tanto IPv4 como IPv6.
Sintaxis de enlace de puertos para IPv6:
ports:
- "80:80" # IPv4 e IPv6
- "0.0.0.0:8080:80" # Solo IPv4
- "[::]:8081:80" # Solo IPv6
- "127.0.0.1:8082:80" # IPv4 localhost
- "[::1]:8083:80" # IPv6 localhostDual-Stack de Kubernetes#
Kubernetes soporta redes dual-stack comenzando con la versión 1.21 (beta) y 1.23 (estable).
Prerrequisitos#
- Kubernetes 1.23 o posterior
- Plugin CNI que soporte dual-stack (Calico, Cilium, Flannel, Weave)
- kube-proxy con modo dual-stack
- Soporte del proveedor cloud (para servicios LoadBalancer)
Habilitar Dual-Stack#
Para clusters nuevos, habilita dual-stack durante la inicialización. Con 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"Inicializa el cluster:
kubeadm init --config kubeadm-config.yamlRedes de Pods#
Los pods reciben direcciones de ambas familias automáticamente. No se necesita configuración especial en la mayoría de casos.
Ejemplo de pod:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: nginx
image: nginxDesplegar y verificar direcciones:
kubectl apply -f pod.yaml
kubectl get pod test-pod -o jsonpath='{.status.podIPs}'La salida muestra tanto IPv4 como IPv6:
[{"ip":"10.244.1.5"},{"ip":"fd00:10:244:1::5"}]Configuración de Servicios#
Los servicios pueden ser solo IPv4, solo IPv6 o dual-stack. Controla esto con los campos ipFamilyPolicy e ipFamilies.
Servicio dual-stack (predeterminado en clusters dual-stack):
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ipFamilyPolicy: RequireDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app: myapp
ports:
- port: 80
targetPort: 8080Servicio solo IPv4:
apiVersion: v1
kind: Service
metadata:
name: myservice-v4
spec:
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv4
selector:
app: myapp
ports:
- port: 80Verificar IPs de servicio:
kubectl get svc myservice -o jsonpath='{.spec.clusterIPs}'Salida:
["10.96.100.5","fd00:10:96::a5"]Consideraciones de Plugin CNI#
Diferentes plugins CNI manejan dual-stack de manera diferente.
Calico#
Calico soporta dual-stack con 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()Habilitar IPv6 en 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 tiene soporte nativo dual-stack. Habilitar durante instalación:
helm install cilium cilium/cilium \
--namespace kube-system \
--set ipv4.enabled=true \
--set ipv6.enabled=true \
--set tunnel=disabled \
--set autoDirectNodeRoutes=trueTrampas Comunes#
Enlace de Aplicaciones#
Las aplicaciones deben enlazar explícitamente a direcciones IPv6. Enlazar a 0.0.0.0 solo escucha en IPv4.
Incorrecto:
server.bind(("0.0.0.0", 8080)) # Solo IPv4Correcto:
server.bind(("::", 8080)) # IPv6 (e IPv4 si IPV6_V6ONLY=0)Muchos lenguajes usan IPv4 por defecto. Verifica la documentación de tu framework.
Resolución DNS#
Las consultas DNS en entornos dual-stack devuelven tanto registros A como AAAA. Las aplicaciones deben intentar ambos, prefiriendo IPv6.
Algunas bibliotecas antiguas solo consultan registros A. Actualiza dependencias o configura resolución DNS explícitamente.
Reglas de Firewall#
Los firewalls de contenedores (iptables/ip6tables) necesitan reglas para ambas familias. Docker y Kubernetes lo manejan automáticamente si se configura correctamente, pero las reglas personalizadas pueden bloquear IPv6.
Verificar reglas de firewall IPv6:
sudo ip6tables -L -n -vConectividad Externa#
Los contenedores con IPv6 necesitan enrutamiento apropiado a redes externas. Si tu host no tiene conectividad IPv6, los contenedores tampoco.
Probar IPv6 del host primero:
ping6 google.comSi eso falla, corrige las redes del host antes de resolver problemas de contenedores.
Probar Despliegues Dual-Stack#
Desplegar una aplicación de prueba:
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: 80Aplicar y probar:
kubectl apply -f test-app.yaml
# Obtener IPs de servicio
kubectl get svc test-svc
# Probar IPv4
curl http://<ipv4-external-ip>
# Probar IPv6
curl -6 http://[<ipv6-external-ip>]Desde dentro de un pod, probar conectividad dual-stack:
kubectl run -it --rm debug --image=alpine --restart=Never -- sh
# Dentro del pod
apk add curl bind-tools
nslookup test-svc
curl -4 http://test-svc # IPv4
curl -6 http://test-svc # IPv6Consideraciones de Producción#
- Monitorear ambas familias de direcciones en herramientas de observabilidad
- Probar comportamiento de failover cuando una familia no está disponible
- Configurar health checks para IPv4 e IPv6
- Documentar topología de red incluyendo prefijos IPv6
- Planificar asignación de direcciones IP para evitar conflictos
- Habilitar IPv6 en pipelines CI/CD para pruebas
- Entrenar al equipo en resolución de problemas dual-stack
Artículos Relacionados#
- IPv6 para Desarrolladores - Implementación de IPv6 a nivel de aplicación
- IPv6 en AWS, Azure y GCP - Configuración IPv6 de plataformas cloud
- Habilitar IPv6 en Tu Red - Despliegue IPv6 en toda la infraestructura
Verificar Conectividad de Contenedores
Usa nuestra Herramienta Ping y Validador IPv6 para probar que tus servicios contenedorizados son alcanzables sobre IPv6.