Falha HTTP no contêiner do Docker hospedado no OpenStack

1

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.

    
por Mac 28.09.2016 / 05:13

1 resposta

0

TL; DR

Adapte o sinalizador MTU dockerd ao MTU da sua VM.

Exemplo

Um dos sistemas operacionais da instância do My OpenStack é o ubuntu16.04.

  1. Verifique o MTU do seu vm com ifconfig (1450 no meu caso)
  2. cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
  3. vi /etc/systemd/system/docker.service
  4. ExecStart=/usr/bin/docker daemon -H fd:// --mtu 1450
  5. systemctl daemon-reload
  6. service docker restart
por 16.03.2017 / 11:29