Tráfego UDP não encaminhado de contêineres do Docker - > host do Docker

Eu tenho um contêiner docker e não consigo executar pesquisas de DNS de dentro dos contêineres, embora funcione bem no host docker.

O código de gerenciamento de configuração que constrói o host Docker é conhecido por funcionar em uma imagem RHEL 7 padrão do marketplace, portanto, o problema é conhecido por ser algo dentro da imagem SOE RHEL 7.

RHEL 7.2 / Docker versão 1.12.6, compilação 88a4867 / 1.12.6. O recipiente é RHEL 7.3. SELinux no modo habilitado / permissivo. O host Docker é uma instância do Amazon EC2.

Alguma configuração:

# /etc/sysconfig/dockerOPTIONS='--dns=10.0.0.10 --dns=10.0.0.11 --dns-search=example.com'DOCKER_CERT_PATH=/etc/dockerADD_REGISTRY='--add-registry registry.example.com'no_proxy=169.254.169.254,localhost,127.0.0.1,registory.example.comhttp_proxy=http://proxy.example.com:8080https_proxy=http://proxy.example.com:8080ftp_proxy=http://proxy.example.com:8080

A configuração do resolvedor no contêiner e no host é a mesma:

# /etc/resolv.confsearch example.comnameserver 10.0.0.10nameserver 10.0.0.11

Se eu reiniciar o daemon docker com --debug Eu vejo o seguinte em journalctl -u docker.service:

Aug 08 11:44:23 myhost.example.com dockerd-current[17341]: time="2017-08-08T11:44:23.430769581+10:00" level=debug msg="Name To resolve: http://proxy.example.com."Aug 08 11:44:23 myhost.example.com dockerd-current[17341]: time="2017-08-08T11:44:23.431488213+10:00" level=debug msg="Query http://proxy.example.com.[1] from 172.18.0.6:38189, forwarding to udp:10.162.182.101"Aug 08 11:44:27 myhost.example.com dockerd-current[17341]: time="2017-08-08T11:44:27.431772666+10:00" level=debug msg="Read from DNS server failed, read udp 172.18.0.6:38189->10.162.182.101:53: i/o timeout"

Após essa observação, posso fazer com que alguma rede funcione se especificar um endereço IP em vez do nome DNS do proxy; embora isso realmente seja apenas uma maneira de evitar o uso do DNS e não uma correção real.

Realmente, (atualização #3) acontece que posso evitar o problema completamente simplesmente configurando o DNS para usar TCP em vez de UDP, ou seja,

# head -1 /etc/sysconfig/dockerOPTIONS="--dns=10.0.0.10 --dns=10.0.0.11 --dns-search=example.com --dns-opt=use-vc"

(Adicionando uma linha use-vc diz ao resolvedor para usar TCP em vez de UDP.)

Eu observei algumas regras de aparência suspeita no iptables, mas estas acabaram sendo normais:

# iptables -n -L DOCKER-ISOLATION -v --line-numbersChain DOCKER-ISOLATION (1 references)num   pkts bytes target     prot opt in     out     source               destination         1        0     0 DROP       all  --  br-1d6a05c10468 docker0  0.0.0.0/0            0.0.0.0/0           2        0     0 DROP       all  --  docker0 br-1d6a05c10468  0.0.0.0/0            0.0.0.0/0           3    34903   11M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Depois de excluir essas duas regras de queda, continuei a ver o problema.

Total iptables:

# iptables -nL -vChain INPUT (policy ACCEPT 2518 packets, 1158K bytes) pkts bytes target     prot opt in     out     source               destination         Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target     prot opt in     out     source               destination         23348 9674K DOCKER-ISOLATION  all  --  *      *       0.0.0.0/0            0.0.0.0/0               0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0               0     0 ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED    0     0 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0               0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           23244 9667K DOCKER     all  --  *      br-1d6a05c10468  0.0.0.0/0            0.0.0.0/0           23232 9667K ACCEPT     all  --  *      br-1d6a05c10468  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED  104  6230 ACCEPT     all  --  br-1d6a05c10468 !br-1d6a05c10468  0.0.0.0/0            0.0.0.0/0              12   700 ACCEPT     all  --  br-1d6a05c10468 br-1d6a05c10468  0.0.0.0/0            0.0.0.0/0           Chain OUTPUT (policy ACCEPT 2531 packets, 414K bytes) pkts bytes target     prot opt in     out     source               destination         Chain DOCKER (2 references) pkts bytes target     prot opt in     out     source               destination             0     0 ACCEPT     tcp  --  !br-1d6a05c10468 br-1d6a05c10468  0.0.0.0/0            172.18.0.2           tcp dpt:443    0     0 ACCEPT     tcp  --  !br-1d6a05c10468 br-1d6a05c10468  0.0.0.0/0            172.18.0.2           tcp dpt:80    0     0 ACCEPT     tcp  --  !br-1d6a05c10468 br-1d6a05c10468  0.0.0.0/0            172.18.0.3           tcp dpt:389Chain DOCKER-ISOLATION (1 references) pkts bytes target     prot opt in     out     source               destination             0     0 DROP       all  --  br-1d6a05c10468 docker0  0.0.0.0/0            0.0.0.0/0               0     0 DROP       all  --  docker0 br-1d6a05c10468  0.0.0.0/0            0.0.0.0/0           23348 9674K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Configuração da ponte

# ip addr show docker04: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN     link/ether 02:42:a8:73:db:bb brd ff:ff:ff:ff:ff:ff    inet 172.17.0.1/16 scope global docker0       valid_lft forever preferred_lft forever# ip addr show br-1d6a05c104683: br-1d6a05c10468: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP     link/ether 02:42:d5:b6:2d:f5 brd ff:ff:ff:ff:ff:ff    inet 172.18.0.1/16 scope global br-1d6a05c10468       valid_lft forever preferred_lft forever

e

# docker network inspect bridge [    {        "Name": "bridge",        "Id": "e159ddd37386cac91e0d011ade99a51f9fe887b8d32d212884beace67483af44",        "Scope": "local",        "Driver": "bridge",        "EnableIPv6": false,        "IPAM": {            "Driver": "default",            "Options": null,            "Config": [                {                    "Subnet": "172.17.0.0/16",                    "Gateway": "172.17.0.1"                }            ]        },        "Internal": false,        "Containers": {},        "Options": {            "com.docker.network.bridge.default_bridge": "true",            "com.docker.network.bridge.enable_icc": "true",            "com.docker.network.bridge.enable_ip_masquerade": "true",            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",            "com.docker.network.bridge.name": "docker0",            "com.docker.network.driver.mtu": "1500"        },        "Labels": {}    }]

Nos logs:

Aug 04 17:33:32 myhost.example.com systemd[1]: Starting Docker Application Container Engine...Aug 04 17:33:33 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:33.056770003+10:00" level=info msg="libcontainerd: new containerd process, pid: 2140"Aug 04 17:33:34 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:34.740346421+10:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"Aug 04 17:33:34 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:34.741164354+10:00" level=info msg="Loading containers: start."Aug 04 17:33:34 myhost.example.com dockerd-current[2131]: .........................time="2017-08-04T17:33:34.903371015+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:35 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:35.325581993+10:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address" Aug 04 17:33:36 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:36+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:37 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:37+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:37 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:37+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:38 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:38+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:39 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:39+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:40 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:40+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:40 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:40+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:42 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:42+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:42 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:42+10:00" level=info msg="Firewalld running: true"Aug 04 17:33:43 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:43.541905145+10:00" level=info msg="Loading containers: done."Aug 04 17:33:43 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:43.541975618+10:00" level=info msg="Daemon has completed initialization"Aug 04 17:33:43 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:43.541998095+10:00" level=info msg="Docker daemon" commit="88a4867/1.12.6" graphdriver=devicemapper version=1.12.6Aug 04 17:33:43 myhost.example.com dockerd-current[2131]: time="2017-08-04T17:33:43.548508756+10:00" level=info msg="API listen on /var/run/docker.sock"Aug 04 17:33:43 myhost.example.com systemd[1]: Started Docker Application Container Engine.

A partir do contêiner, posso fazer ping no gateway padrão, mas a resolução de todos os nomes falha.

Notei uma coisa estranha no log (Atualização #2 Agora eu sei que este é um arenque vermelho-veja a discussão abaixo):

# journalctl -u docker.service |grep insmod > /tmp/log # \n's replaced belowJul 26 23:59:02 myhost.example.com dockerd-current[3185]: time="2017-07-26T23:59:02.056295890+10:00" level=warning msg="Running modprobe bridge br_netfilter failed with message: insmod /lib/modules/3.10.0-514.26.2.el7.x86_64/kernel/net/bridge/bridge.ko sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-arptables: No such file or directorysysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directorysysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directorymodprobe: ERROR: Error running install command for bridgemodprobe: ERROR: could not insert 'bridge': Unknown error 253insmod /lib/modules/3.10.0-514.26.2.el7.x86_64/kernel/net/llc/llc.ko insmod /lib/modules/3.10.0-514.26.2.el7.x86_64/kernel/net/802/stp.ko install /sbin/modprobe --ignore-install bridge && /sbin/sysctl -q -w net.bridge.bridge-nf-call-arptables=0 net.bridge.bridge-nf-call-iptables=0 net.bridge.bridge-nf-call-ip6tables=0 insmod /lib/modules/3.10.0-514.26.2.el7.x86_64/kernel/net/bridge/br_netfilter.ko , error: exit status 1"

Atualização #1: e isso está vindo de:

# tail -2 /etc/modprobe.d/dist.conf# Disable netfilter on bridges when the bridge module is loadedinstall bridge /sbin/modprobe --ignore-install bridge && /sbin/sysctl -q -w net.bridge.bridge-nf-call-arptables=0 net.bridge.bridge-nf-call-iptables=0 net.bridge.bridge-nf-call-ip6tables=0

Tambem:

# cat /proc/sys/net/bridge/bridge-nf-call-{arp,ip,ip6}tables111

No entanto, mesmo depois de fazer isso:

# for i in /proc/sys/net/bridge/bridge-nf-call-{arp,ip,ip6}tables ; do echo 0 > $i ; done 

Ainda sem sorte.

Passei um dia inteiro nisso, então puxando meu cabelo para fora agora. Quaisquer pensamentos sobre o que mais eu poderia tentar ou o que mais o problema pode ser muito apreciado.

Atualização #4

>Realizei alguns experimentos usando Netcat e provei que todos os pacotes UDP não são encaminhados se enviados de qualquer host de contêiner. Tentei usar várias portas, incluindo 53, 2115 e 50000. Pacotes TCP estão bem no entanto. Isso ainda é verdade se eu liberar as regras iptables com iptables -F.

>Além disso, posso enviar pacotes UDP de um contêiner para outro - apenas o tráfego UDP do contêiner - host não é encaminhado.

Para configurar o teste:

No host, que tem IP 10.1.1.10:

# nc -u -l 50000

No recipiente:

# echo "foo" | nc -w1 -u 10.1.1.10 50000

Durante uma captura de despejo TCP, vejo:

17:20:36.761214 IP (tos 0x0, ttl 64, id 48146, offset 0, flags [DF], proto UDP (17), length 32)    172.17.0.2.41727 > 10.1.1.10.50000: [bad udp cksum 0x2afa -> 0x992f!] UDP, length 4        0x0000:  4500 0020 bc12 4000 4011 53de ac11 0002  E.....@.@.S.....        0x0010:  0aa5 7424 a2ff c350 000c 2afa 666f 6f0a  ..t$...P..*.foo.        0x0020:  0000 0000 0000 0000 0000 0000 0000 0000  ................17:20:36.761214 IP (tos 0x0, ttl 64, id 48146, offset 0, flags [DF], proto UDP (17), length 32)    172.17.0.2.41727 > 10.1.1.10.50000: [bad udp cksum 0x2afa -> 0x992f!] UDP, length 4        0x0000:  4500 0020 bc12 4000 4011 53de ac11 0002  E.....@.@.S.....        0x0010:  0aa5 7424 a2ff c350 000c 2afa 666f 6f0a  ..t$...P..*.foo.        0x0020:  0000 0000 0000 0000 0000 0000 0000 0000  ................

Tentei, sem sucesso, corrigir as somas de verificação UDP ruins por meio de presente.

>>Observei, no entanto, que as somas de verificação UDP ruins são vistas mesmo durante a transmissão bem - sucedida de pacotes UDP (host - host) e container-container.

Em resumo, agora sei:

  • roteamento é bom

  • iptables é lavado

  • SELinux é permissivo

  • todo TCP funciona em todas as direções

  • >todo o UDP do recipiente-recipiente é fino

  • >todo o UDP do host-host está bem

  • >todo o UDP do host-container está bem

  • MAS> Nenhum pacote UDP do container-host é encaminhado

Eu descobri.

Tínhamos um agente Trend Micro (antivírus) rodando no SOE que eu não conhecia.

Consertá-lo era tão simples quanto:

# systemctl stop ds_agent.service# pkill ds_agent

Não tenho certeza exatamente neste momento por que ele está bloqueando UDP de contêineres ou como pará-lo.

Tive problemas com o resolvedor DNS em nossos contêineres docker. Eu tentei um monte de coisas diferentes, e no final, eu só percebi que o meu VPS em O Hostgator não instalou por padrão NetworkManager-tui (nmtui), Acabei de instalar e reiniciá-lo.

sudo yum install NetworkManager-tui

E reconfigurou o meu resolv.conf com DNS padrão como 8.8.8.8.

nano /etc/resolv.conf

@ Orphans, atualizado com os resultados dos meus experimentos netcat. Basicamente, todo UDP de container → host é perdido, mas TCP é bom, e UDP também é bom de container → container e de host → container. E tudo verdade após iptables-F.

Isso ajuda? How do I publish a UDP Port on Docker? - Stack Overflow

Obrigado, mas não, isso é sobre encaminhamento de porta-encaminhamento de uma porta em um contêiner para que um cliente possa se conectar a ele em um endereço no host Docker. No meu caso, o contêiner está tentando enviar pacotes UDP de saída.

Em qual interface você executou ’ tcpdump? Você deve executá-lo na interface docker0`, na interface de saída do host e no servidor de nomes para ver onde os pacotes são descartados (provavelmente por causa da soma de verificação UDP ruim). Você pode executar ‘iptables-t mangle - a POSTROUTING-o docker0-p udp-j CHECKSUM --checksum-fill’ para ver se ele corrige seu problema? Se o seu host for uma VM e o comando anterior não corrigir o problema, faça-o também na interface de saída.

Seu comando iptables ' sugerido não teve nenhum efeito que eu possa observar. Meu host é uma instância do Amazon EC2, com uma interface eth0. Se eu executar ' tcpdump-I eth0 port 53, Os pacotes não serão vistos, o que significa que foram descartados na ponte. Intuitivamente, não posso acreditar que as somas de verificação UDP ruins sejam o problema, considerando que elas estão presentes em todas as direções, mas o tráfego só é descartado na direção container → host.

Seus contêineres podem falar na porta 53?
telnet 8.8.8.8 53

Não consigo chegar à porta 8.8.8.8 (TCP) 53 porque 8.8.8.8 está bloqueado por um firewall da empresa. No entanto, posso me conectar ao meu servidor DNS local na porta TCP 53-veja minha atualização. De manhã, pretendo descobrir uma maneira de usar o netcat para tentar provar (o que atualmente acredito) que o problema é realmente que esses contêineres simplesmente não encaminham o tráfego UDP de saída.