Atualmente, tenho o Docker em execução em algumas VMs hospedadas no OpenStack.
Ao tentar fazer solicitações HTTP de contêineres nessas máquinas, a solicitação quase sempre fica pendente à espera de uma resposta. Ao fazer solicitações HTTPS, a solicitação invariavelmente expira porque não consegue concluir o handshake TLS. Em ambos os casos, parece que as solicitações estão falhando depois de receber apenas algumas centenas de bytes de dados de resposta (se houver). As mesmas solicitações são concluídas sem nenhum problema da máquina host (ou seja, não é um firewall em nível de host que é o problema).
Eu encontrei este (e alguns posts relacionados) que sugerem que pode ser devido à ponte de rede do Docker ter uma MTU diferente para a interface de rede do host, mas eu verifiquei que ambos os MTUs são os mesmos (1500 bytes em cada caso). Eu também tentei brincar com a opção --mtu
para o daemon do Docker para ver se eu poderia fazê-lo funcionar, sem sucesso.
Também encontrei alguns casos semelhantes que sugerem que isso pode ser devido à soma de verificação TCP e / ou ao descarregamento de segmentação (por exemplo, aqui ), mas nenhuma quantidade de brincar com ethtool -K {interface} tx off rx off
ou similar produz qualquer resultado positivo.
O comportamento parece ser específico para a ponte de rede - usar --net=host
ao executar contêineres resolve o problema. No entanto, por motivos de segurança, evito ter que usar essa solução alternativa em nosso sistema de produção.
Note também que exatamente a mesma configuração (mesma versão do Docker, mesmos parâmetros de configuração) funciona bem na minha máquina de desenvolvimento ou quando executada em uma instância hospedada no AWS - seja qual for o problema, ela só se manifesta quando executada no OpenStack .
Para referência, estou usando o seguinte comando para testes:
docker run -it alpine:3.3 wget http://ipv4.download.thinkbroadband.com/5MB.zip
Isso deve (em teoria) fazer o download de um arquivo de teste de 5MB quando executado. No entanto, o comando wget
simplesmente trava. Também é provavelmente importante notar que não é o sistema operacional convidado que é o problema - usar uma imagem do Ubuntu (por exemplo) ainda exibe o mesmo comportamento.
Um colega e eu também fizemos alguns testes transferindo arquivos usando o netcat. Nesses testes, conseguimos transferir com êxito os arquivos do contêiner para o nosso servidor de teste, mas a tentativa de transferir na direção oposta falhou. Também usamos tcpdump
para capturar a atividade da rede durante esses testes - durante os testes com falha, os logs mostraram alguns pacotes sendo recebidos, mas significativamente menos do que o esperado.
Além disso, caso seja relevante, aqui está a saída de docker version
no sistema em questão:
Client:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:22:43 2016
OS/Arch: linux/amd64
Server:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:22:43 2016
OS/Arch: linux/amd64
A saída de uname -a
no host é a seguinte:
Linux docker-builder-1 4.4.0-38-generic #57~14.04.1-Ubuntu SMP Tue Sep 6 17:20:43 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
UPDATE
Acontece que tudo funciona como esperado se o Docker estiver hospedado em uma imagem do Ubuntu 16.04.
Neste ponto, posso avançar reconstruindo todas as minhas VMs para usar uma imagem do Ubuntu 16.04, mas ainda não sei qual era o problema original. Ainda estou interessado em ouvir qualquer sugestão sobre qual foi a causa do problema original e como corrigi-lo.