Lalu lintas UDP tidak diteruskan dari kontainer Docker - > host Docker

Saya memiliki wadah buruh pelabuhan dan saya tidak dapat menjalankan pencarian DNS dari dalam wadah, meskipun berfungsi dengan baik dari host buruh pelabuhan.

Kode manajemen konfigurasi yang membangun host Docker diketahui bekerja pada gambar RHEL 7 standar dari marketplace, oleh karena itu masalahnya diketahui sebagai sesuatu di dalam gambar SOE RHEL 7.

RHEL 7.2 / Docker versi 1.12.6, membangun 88a4867/1.12.6. Wadah adalah RHEL 7.3. SELinux dalam mode diaktifkan / permisif. Host Docker adalah instans Amazon EC2.

Beberapa konfigurasi:

# /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

Resolver config dalam wadah dan host adalah sama:

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

Jika saya me-restart daemon docker dengan --debug Saya melihat yang berikut ini di 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"

Setelah pengamatan lebih lanjut, ternyata saya bisa mendapatkan beberapa jaringan untuk bekerja jika saya menentukan alamat IP alih-alih nama DNS proxy; meskipun itu benar-benar hanya cara untuk menghindari penggunaan DNS dan bukan perbaikan nyata.

Sesungguhnya (pembaruan # 3) ternyata saya dapat menghindari masalah sepenuhnya hanya dengan mengonfigurasi DNS untuk menggunakan TCP alih-alih UDP, yaitu.

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

(Menambahkan baris use-vc memberitahu resolver untuk menggunakan TCP bukan UDP.)

Saya mencatat beberapa aturan yang tampak mencurigakan di iptables, tetapi ini ternyata normal:

# 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           

Setelah menghapus dua aturan DROP itu, saya terus melihat masalahnya.

Iptables penuh:

# 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           

Bridge config

# 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

dan

# 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": {}    }]

Dalam log:

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.

Dari wadah, saya dapat melakukan ping ke gateway default tetapi semua resolusi nama gagal.

Saya melihat satu hal aneh di log (Pembaruan # 2 Saya sekarang tahu bahwa ini adalah ikan haring merah-lihat diskusi di bawah):

# 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"

Pembaruan #1: dan ini berasal dari:

# 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

Juga:

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

Namun, bahkan setelah saya melakukan ini:

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

Masih tidak beruntung.

Saya menghabiskan sepanjang hari untuk ini sehingga menarik rambut saya sekarang. Setiap pemikiran tentang apa lagi yang bisa saya coba atau apa lagi masalahnya mungkin sangat dihargai.

Pembaruan # 4

>Saya melakukan beberapa percobaan menggunakan Netcat dan saya telah membuktikan bahwa semua paket UDP tidak diteruskan jika dikirim dari host kontainer mana pun. Saya mencoba menggunakan beberapa port termasuk 53, 2115, dan 50000. Namun paket TCP baik-baik saja. Ini masih benar jika saya menyiram aturan iptables dengan iptables -F.

>Selain itu, saya dapat mengirim paket UDP dari satu wadah ke wadah lain - hanya lalu lintas UDP dari wadah - host tidak diteruskan.

Untuk mengatur tes:

Pada host, yang memiliki IP 10.1.1.10:

# nc -u -l 50000

Pada wadah:

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

Selama penangkapan dump TCP saya melihat:

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  ................

Saya mencoba gagal untuk memperbaiki checksum UDP yang buruk melalui ini.

>>Saya mencatat, bagaimanapun, bahwa checksum UDP yang buruk terlihat bahkan selama transmisi paket UDP yang berhasil (host - host) dan container - container.

Singkatnya, saya sekarang tahu:

  • routing baik-baik saja

  • iptables memerah

  • SELinux adalah permisif

  • semua TCP bekerja ke segala arah

  • >semua UDP dari kontainer-kontainer baik-baik saja

  • >semua UDP dari host-host baik-baik saja

  • >semua UDP dari host-container baik-baik saja

  • Tapi> tidak ada paket UDP dari container-host yang diteruskan

Aku menemukan jawabannya.

Kami memiliki agen Trend Micro (anti-virus) yang berjalan di BUMN yang tidak saya ketahui.

Memperbaiki itu yang sederhana seperti:

# systemctl stop ds_agent.service# pkill ds_agent

Tidak begitu yakin pada titik ini mengapa itu memblokir UDP dari wadah atau bagaimana menghentikannya.

Sepertinya Anda memiliki modprobe install direktif yang tidak dapat bekerja. Mungkin itu hasil dari pembaruan yang tidak lengkap ke RHEL 7.2 atau beberapa perbaikan manual.

Coba grep -r bridge /etc/modprobe.d /lib/modprobe.d sebagai permulaan, atau menggali sekitar /etc/modprobe.d atau /lib/modprobe.d dan mencoba untuk menemukan di mana itu mendefinisikan install aturan yang memanggil sysctl -q -w net.bridge.bridge-nf-call-arptables=0 net.bridge.bridge-nf-call-iptables=0 net.bridge.bridge-nf-call-ip6tables=0

Ini sysctl jelas di tempat yang salah. Hal ini baik berlebihan atau harus muncul setelah br_netfilter, Tidak sebelumnya. Mengapa? Baru-baru ini /proc/sys/net/bridge penanganan telah dipindahkan dari bridge modul ke br_netfilter modul. Ini terjadi dengan beberapa versi kernel*.rpm, sedangkan isi dari modprobe.d direktori didistribusikan dengan paket individual lainnya. Saya telah memverifikasi RHEL 7.2 saya:

# modprobe bridge# sysctl -q -w net.bridge.bridge-nf-call-iptables=0sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory# modprobe br_netfilter# sysctl -q -w net.bridge.bridge-nf-call-iptables=0    # ok now

Saya tidak melihat aturan "rusak" ini pada vanilla RHEL 7.1 saya dan asal mereka misterius bagi saya. Saya sudah mencoba:

# modprobe -n -vvv bridgemodprobe: INFO: custom logging function 0x40a130 registeredinsmod /lib/modules/3.10.0-229.11.1.el7.x86_64/kernel/net/llc/llc.koinsmod /lib/modules/3.10.0-229.11.1.el7.x86_64/kernel/net/802/stp.koinsmod /lib/modules/3.10.0-229.11.1.el7.x86_64/kernel/net/bridge/bridge.komodprobe: INFO: context 0xf1c270 released# echo "install bridge echo example_of_a_modprobe_rule" > /etc/modprobe.d/zzz5.conf# modprobe -n -vvv bridgemodprobe: INFO: custom logging function 0x40a130 registeredinsmod /lib/modules/3.10.0-229.11.1.el7.x86_64/kernel/net/llc/llc.koinsmod /lib/modules/3.10.0-229.11.1.el7.x86_64/kernel/net/802/stp.koinstall echo example_of_a_modprobe_rulemodprobe: INFO: context 0xeaa270 released# rm /etc/modprobe.d/zzz5.conf

Pembaruan: Sepertinya xenserver menggunakan hack modprobe serupa. Ini adalah bug yang buruk untuk mengubah perilaku modul kernel secara global untuk semua orang apakah Anda benar-benar menjalankan xenserver atau tidak; dan bug tersebut telah membalas kami.

Pembaruan 2: Sekarang, Anda telah menemukan bahwa /etc/modprobe.d/dist.conf menyebabkan masalah ini dan bukan buruh pelabuhan. Apakah Anda memiliki docker atau tidak, modprobe bridge akan selalu kembali 1 dan kesalahan cetak. Biasanya dist.conf adalah bagian dari module-init-tools paket pada RHEL6. File ini tidak seharusnya digunakan pada RHEL7. Ini bukan pada sistem RHEL7 saya dan mereka berjalan dengan baik. Dalam RHEL7 paket adalah kmod dan itu tidak mengandung dist.conf. Saya akan:

rpm -qf /etc/modprobe.d/dist.conf  # what package owns this file?

Jika dist.conf tidak dimiliki oleh paket, Cadangkan dan hapus baris apa pun yang tidak memberi Anda manfaat yang jelas (bahkan mungkin menghapus file sama sekali).

Jika dist.conf dimiliki oleh sebuah paket, pertimbangkan untuk menghapus/memperbarui paket itu, karena itu menjadi jelas buggy dalam hal kompatibilitas RHEL 7.2.

Saya memiliki masalah dengan penyelesai DNS di wadah buruh pelabuhan kami. Saya mencoba banyak hal yang berbeda, dan pada akhirnya, saya baru tahu bahwa VPS saya masuk Hostgator tidak diinstal secara default NetworkManager - tui (nmtui), Saya baru saja menginstal dan reboot.

sudo yum install NetworkManager-tui

Dan ulang saya resolv.conf dengan DNS default sebagai 8.8.8.8.

nano /etc/resolv.conf

@ Orphans, diperbarui dengan hasil dari eksperimen netcat saya. Pada dasarnya, semua UDP dari container - > host hilang, tetapi TCP baik-baik saja, dan UDP juga baik-baik saja dari container - > container dan dari host - > container. Dan semua benar setelah iptables-F.

Apakah ini membantu? How do I publish a UDP Port on Docker? - Stack Overflow

Terima kasih, tapi tidak, itu tentang penerusan port-meneruskan port dalam wadah sehingga klien dapat menghubungkannya di alamat di host buruh pelabuhan. Dalam kasus saya, wadah mencoba mengirim paket UDP keluar.

Di antarmuka mana Anda menjalankan ‘tcpdump’? Anda harus menjalankannya di antarmuka ‘docker0’, antarmuka keluar host Anda dan di server nama untuk melihat di mana paket dijatuhkan (mungkin karena checksum UDP yang buruk). Dapatkah Anda menjalankan ’ iptables-t mangle-a POSTROUTING-o docker0-p udp-J CHECKSUM --checksum-fill` untuk melihat apakah itu memperbaiki masalah Anda? Jika host Anda adalah VM dan perintah sebelumnya tidak memperbaiki masalah Anda, lakukan juga pada antarmuka keluar.

Perintah iptables yang Anda sarankan tidak memiliki efek apa pun yang dapat saya amati. Host saya adalah instance Amazon EC2, dengan satu antarmuka eth0. Jika saya menjalankan ‘tcpdump-I eth0 port 53’, paket tidak terlihat, artinya mereka dijatuhkan di jembatan. Secara intuitif, saya tidak percaya checksum UDP yang buruk adalah masalahnya, mengingat mereka ada di semua arah, tetapi lalu lintas hanya dijatuhkan di wadah → arah host.

Bisakah kontainer Anda berbicara di port 53?
telnet 8.8.8.8 53

Saya tidak bisa sampai ke port 8.8.8.8 (TCP) 53 karena 8.8.8.8 diblokir oleh firewall perusahaan. Namun, saya dapat terhubung ke server DNS lokal saya di port TCP 53 – Lihat pembaruan saya. Di pagi hari saya bermaksud mencari cara untuk menggunakan netcat untuk mencoba membuktikan (apa yang saya yakini saat ini) bahwa masalahnya sebenarnya adalah wadah ini tidak meneruskan lalu lintas UDP keluar.