IPv6 no Docker e Kubernetes: Guia de Rede de Contêineres
Configure IPv6 para aplicações em contêineres. Cobre configurações do daemon Docker, dual-stack do Kubernetes, plugins CNI e exposição de serviços.
A rede de contêineres assume IPv4 por padrão. Isso é um problema se está a executar cargas de trabalho de produção em 2024.
TL;DR - Resumo rápido
Pontos-chave:
- Docker e Kubernetes assumem IPv4-only por padrão; IPv6 requer configuração explícita
- Docker precisa de alterações em daemon.json e redes personalizadas com flag
--ipv6 - Kubernetes 1.23+ suporta dual-stack estável com IPv6 para pods e serviços
- Plugins CNI (Calico, Cilium, Flannel) lidam com dual-stack de forma diferente
Ir para: Configuração Docker | Dual-Stack Kubernetes | Plugins CNI | Testes
Por Que IPv6 em Contêineres#
Os seus contêineres podem estar apenas em IPv4 enquanto o resto da Internet migra para IPv6. Redes móveis, ISPs e fornecedores de cloud são IPv6-first. Se os seus serviços em contêineres não suportam IPv6, está a adicionar latência através de gateways NAT64 ou pior — a perder clientes completamente.
Plataformas de orquestração de contêineres (Docker, Kubernetes, ECS, Nomad) foram construídas durante a era IPv4. O suporte IPv6 chegou mais tarde como uma reflexão tardia. Os padrões ainda assumem rede apenas IPv4.
Ativar IPv6 não é difícil, mas requer configuração explícita em múltiplas camadas: daemon, rede, contêiner e serviço. Falhe numa camada e terá conectividade parcial que quebra misteriosamente.
Configuração IPv6 do Docker#
O daemon Docker não ativa IPv6 por padrão. Precisa de o configurar em /etc/docker/daemon.json.
Configuração do Daemon#
Crie ou modifique /etc/docker/daemon.json:
{
"ipv6": true,
"fixed-cidr-v6": "fd00::/80",
"experimental": false,
"ip6tables": true
}Analisando isto:
"ipv6": trueativa o suporte IPv6"fixed-cidr-v6"define a sub-rede para contêineres (use prefixo ULA ou GUA)"ip6tables": trueativa regras de firewall IPv6 (Docker 20.10+)
Para produção com endereços globalmente roteáveis, use o prefixo atribuído pelo seu fornecedor:
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1234::/64"
}Reinicie o Docker para aplicar as alterações:
sudo systemctl restart dockerVerifique se IPv6 está ativado:
docker network inspect bridge | grep IPv6Deve ver "EnableIPv6": true.
Rede Bridge Padrão#
A rede bridge padrão não obtém IPv6 automaticamente mesmo após a configuração do daemon. Crie uma rede personalizada:
docker network create --ipv6 \
--subnet=172.20.0.0/16 \
--subnet=fd00:dead:beef::/48 \
mynetworkExecute contêineres nesta rede:
docker run -d --network mynetwork nginxOs contêineres agora recebem endereços IPv4 e IPv6.
Redes Definidas pelo Utilizador#
Redes bridge definidas pelo utilizador suportam 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 \
appnetworkContêineres nesta rede podem comunicar 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 container1O resolvedor DNS embutido do Docker retorna registos AAAA para nomes de contêineres quando IPv6 está ativado.
NAT IPv6 e Roteamento#
Por padrão, o Docker usa NAT para IPv4 mas pode não fazer NAT para IPv6. Isto depende da sua configuração fixed-cidr-v6.
Com prefixos ULA (fd00::/8), precisa de NAT para acesso à Internet:
# Ativar encaminhamento IPv6
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Adicionar regra masquerade
sudo ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADECom prefixos GUA (globalmente roteáveis), roteie diretamente sem NAT:
# Adicionar rota para sub-rede de contêineres
sudo ip -6 route add 2001:db8:1234::/64 via <docker-host-ipv6>Configure o roteador upstream para rotear a sua sub-rede de contêineres para o host Docker.
Docker Compose IPv6#
Docker Compose requer configuração explícita de IPv6 na definição de rede.
Exemplo docker-compose.yml:
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
ports:
- "80:80"
- "[::]:8080:80" # Vincular IPv6 explicitamente
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::/64A flag enable_ipv6: true é necessária por rede. A configuração IPAM (IP Address Management) atribui sub-redes IPv4 e IPv6.
Sintaxe de vinculação de portas para IPv6:
ports:
- "80:80" # IPv4 e IPv6
- "0.0.0.0:8080:80" # Apenas IPv4
- "[::]:8081:80" # Apenas IPv6
- "127.0.0.1:8082:80" # IPv4 localhost
- "[::1]:8083:80" # IPv6 localhostInicie os serviços:
docker-compose up -dVerifique se os contêineres têm IPv6:
docker-compose exec web ip -6 addr showDual-Stack do Kubernetes#
O Kubernetes suporta rede dual-stack a partir da versão 1.21 (beta) e 1.23 (estável).
Pré-requisitos#
- Kubernetes 1.23 ou posterior
- Plugin CNI que suporte dual-stack (Calico, Cilium, Flannel, Weave)
- kube-proxy com modo dual-stack
- Suporte do fornecedor de cloud (para serviços LoadBalancer)
Ativar Dual-Stack#
Para novos clusters, ative dual-stack durante a inicialização. Com 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"Inicialize o cluster:
kubeadm init --config kubeadm-config.yamlPara Kubernetes gerido (EKS, GKE, AKS), ative dual-stack durante a criação do 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,IPv6Verifique se dual-stack está ativado:
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDRs}'Deve ver CIDRs IPv4 e IPv6.
Rede de Pods#
Os pods recebem endereços de ambas as famílias automaticamente. Nenhuma configuração especial necessária na maioria dos casos.
Exemplo de pod:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: nginx
image: nginxImplemente e verifique os endereços:
kubectl apply -f pod.yaml
kubectl get pod test-pod -o jsonpath='{.status.podIPs}'A saída mostra IPv4 e IPv6:
[{"ip":"10.244.1.5"},{"ip":"fd00:10:244:1::5"}]As aplicações dentro dos pods devem vincular-se a :: (todos os endereços) ou 0.0.0.0 especificamente:
# Exemplo Python - vincular a IPv4 e 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 vincule a 0.0.0.0 para IPv4 e :: para IPv6 separadamente.
Configuração de Serviços#
Os serviços podem ser apenas IPv4, apenas IPv6 ou dual-stack. Controle isto com os campos ipFamilyPolicy e ipFamilies.
Serviço dual-stack (padrão em clusters dual-stack):
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ipFamilyPolicy: RequireDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app: myapp
ports:
- port: 80
targetPort: 8080Serviço apenas IPv4:
apiVersion: v1
kind: Service
metadata:
name: myservice-v4
spec:
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv4
selector:
app: myapp
ports:
- port: 80Serviço apenas IPv6:
apiVersion: v1
kind: Service
metadata:
name: myservice-v6
spec:
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv6
selector:
app: myapp
ports:
- port: 80Verifique os IPs do serviço:
kubectl get svc myservice -o jsonpath='{.spec.clusterIPs}'Saída:
["10.96.100.5","fd00:10:96::a5"]Serviços LoadBalancer#
Os serviços LoadBalancer provisionam balanceadores de carga em cloud com frontends dual-stack (se o fornecedor de cloud suportar).
apiVersion: v1
kind: Service
metadata:
name: web-lb
spec:
type: LoadBalancer
ipFamilyPolicy: RequireDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app: web
ports:
- port: 80
targetPort: 8080Verifique os IPs externos:
kubectl get svc web-lbSaída:
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/TCPNem todos os fornecedores de cloud suportam balanceadores de carga dual-stack ainda. Verifique o suporte para a sua plataforma.
Controladores Ingress#
O suporte Ingress para IPv6 depende da implementação do controlador.
Controladores populares com suporte IPv6:
- nginx-ingress: Suporta dual-stack, escuta em IPv4 e IPv6
- Traefik: Suporte completo dual-stack
- HAProxy Ingress: Suporta IPv6
- Contour: Capaz de dual-stack
Configure nginx-ingress para 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: httpsOs recursos Ingress não precisam de configuração especial IPv6 — funcionam automaticamente se o controlador o suportar.
Políticas de Rede#
Os recursos NetworkPolicy suportam blocos 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 # Bloquear ULARegras IPv4 e IPv6 podem coexistir na mesma política.
Considerações sobre Plugins CNI#
Plugins CNI diferentes lidam com dual-stack de forma diferente.
Calico#
O Calico suporta dual-stack com pools de 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()Ative IPv6 no Calico:
kubectl set env daemonset/calico-node -n kube-system IP6=autodetect
kubectl set env daemonset/calico-node -n kube-system FELIX_IPV6SUPPORT=trueCilium#
O Cilium tem suporte dual-stack nativo. Ative durante a instalação:
helm install cilium cilium/cilium \
--namespace kube-system \
--set ipv4.enabled=true \
--set ipv6.enabled=true \
--set tunnel=disabled \
--set autoDirectNodeRoutes=trueFlannel#
O Flannel requer modo dual-stack na configuração do 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#
O Weave suporta dual-stack com ambos os modos 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"Armadilhas Comuns#
Vinculação de Aplicações#
As aplicações devem escutar explicitamente em endereços IPv6. Vincular a 0.0.0.0 apenas escuta em IPv4.
Errado:
server.bind(("0.0.0.0", 8080)) # Apenas IPv4Correto:
server.bind(("::", 8080)) # IPv6 (e IPv4 se IPV6_V6ONLY=0)Muitas linguagens assumem IPv4 por padrão. Consulte a documentação da sua framework.
Resolução DNS#
Consultas DNS em ambientes dual-stack retornam registos A e AAAA. As aplicações devem tentar ambos, preferindo IPv6.
Algumas bibliotecas antigas apenas consultam registos A. Atualize dependências ou configure a resolução DNS explicitamente.
Regras de Firewall#
Firewalls de contêineres (iptables/ip6tables) precisam de regras para ambas as famílias. Docker e Kubernetes lidam com isto automaticamente se configurados corretamente, mas regras personalizadas podem bloquear IPv6.
Verifique regras de firewall IPv6:
sudo ip6tables -L -n -vConectividade Externa#
Contêineres com IPv6 precisam de roteamento adequado para redes externas. Se o seu host não tem conectividade IPv6, os contêineres também não terão.
Teste IPv6 do host primeiro:
ping6 google.comSe isso falhar, corrija a rede do host antes de resolver problemas nos contêineres.
Serviços Headless de StatefulSet#
StatefulSets com serviços headless retornam endereços IPv4 e IPv6 para nomes DNS de pods:
nslookup web-0.myservice.default.svc.cluster.localAplicações conectando-se a pods StatefulSet devem lidar com múltiplos endereços graciosamente.
Testar Implementações Dual-Stack#
Implemente uma aplicação de teste:
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: 80Aplique e teste:
kubectl apply -f test-app.yaml
# Obter IPs do serviço
kubectl get svc test-svc
# Testar IPv4
curl http://<ipv4-external-ip>
# Testar IPv6
curl -6 http://[<ipv6-external-ip>]Dentro de um pod, teste conectividade dual-stack:
kubectl run -it --rm debug --image=alpine --restart=Never -- sh
# Dentro do pod
apk add curl bind-tools
nslookup test-svc
curl -4 http://test-svc # IPv4
curl -6 http://test-svc # IPv6Considerações de Produção#
- Monitorize ambas as famílias de endereços em ferramentas de observabilidade
- Teste comportamento de failover quando uma família não está disponível
- Configure verificações de saúde para IPv4 e IPv6
- Documente topologia de rede incluindo prefixos IPv6
- Planeie alocação de endereços IP para evitar conflitos
- Ative IPv6 em pipelines CI/CD para testes
- Treine equipa em resolução de problemas dual-stack
Artigos Relacionados#
- IPv6 para Programadores - Implementação IPv6 a nível de aplicação
- IPv6 em AWS, Azure e GCP - Configuração IPv6 em plataformas cloud
- Ativar IPv6 na Sua Rede - Implementação IPv6 em toda a infraestrutura
Verificar Conectividade de Contêineres
Use a nossa Ferramenta Ping e Validador IPv6 para testar se os seus serviços em contêineres estão acessíveis via IPv6.