
Estou escrevendo um servidor que se liga a várias portas locais (incluindo 80
e 443
). Sempre que eu o executo no Google Computer Engine (GCE), usando seu Container-Optimized OS (COS) e um contêiner Docker, as portas são vinculadas ao IPv6, e não ao IPv4.
$ netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:36265 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp6 0 0 :::80 :::* LISTEN
tcp6 0 0 :::443 :::* LISTEN
udp 0 0 10.128.0.33:68 0.0.0.0:*
Esta é uma distinção importante, porque existe uma lógica no meu programa que tenta se conectar diretamente à interface local usando o endereço IPv4 de 127.0.0.1
.
Como posso especificar que minha instância GCE use uma porta IPv4?
Responder1
Editar
Uma coisa importante a ser observada (conforme apontado nos comentários)- embora possa ser vinculado a uma interface que usa IPv4 e IPv6, o roteamento IPv6 não funcionará no Google Cloud (ainda não compatível internamente).
Portanto, esse é um "recurso" confuso na forma como o Docker faz a rede e ainda deve permitir conexões IPv4 e IPv6.
Veresta resposta do StackOverflowpara mais detalhes. Citei a resposta abaixo para o bem da posteridade:
...github.com/docker/docker/issues/2174trata-se de mostrar a ligação apenas ao IPv6 no
netstat
, mas isso não é um problema. Como afirma o problema do github:Ao configurar o proxy, o Docker solicita o endereço de loopback '127.0.0.1', o Linux percebe que este é um endereço que existe no IPv6 (como ::0) e abre em ambos (mas é formalmente um soquete IPv6). Quando você executa o netstat, ele vê isso e informa que é um IPv6 - mas ainda está escutando no IPv4. Se você brincou um pouco com suas configurações, pode ter desabilitado esse truque que o Linux faz - definindo net.ipv6.bindv6only = 1.
Em outras palavras, só porque você o vê apenas como IPv6, ele ainda é capaz de se comunicar em IPv4, a menos que você tenha o IPv6 configurado para vincular apenas em IPv6 com a configuração net.ipv6.bindv6only. Para ficar claro, net.ipv6.bindv6only deve ser 0 - você pode executar
sysctl net.ipv6.bindv6only
para verificar.