Saya mengalami kesulitan mengakses antarmuka pribadi host (ip) dari wadah buruh pelabuhan. Saya cukup yakin bahwa itu terkait dengan aturan Iptables saya (atau mungkin perutean). Ketika saya menambahkan --net=host
bendera docker run
, semuanya berfungsi seperti yang diharapkan. Demikian pula ketika saya menentukan bahwa kebijakan INPUT mengikuti liberal -P INPUT ACCEPT
, hal-hal juga berfungsi seperti yang saya harapkan. Namun ini adalah opsi yang tidak diinginkan dan tidak aman yang ingin saya hindari.
Karena ini tidak khusus untuk layanan saya (DNS), saya mengecualikannya dari masalah, karena mencari itu dalam kombinasi dengan hasil buruh pelabuhan di area masalah (populer) yang berbeda, menambahkan suara ke hasil pencarian.
Juga menautkan wadah Docker bukan opsi yang layak, karena wadah tertentu perlu dijalankan dengan opsi --net = host, mencegah penautan dan saya ingin membuat situasi yang konsisten jika memungkinkan.
Saya memiliki aturan Iptables berikut. Kombinasi CoreOS, Digital Ocean, dan Docker, saya kira.
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
Antarmuka host (relevan) saya:
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 10.129.112.210/16 brd 10.129.255.255 scope global eth1
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
Dan saya menjalankan wadah buruh pelabuhan:
$ docker run --rm -it --dns=10.129.112.210 debian:jessie # Specifying the DNS is so that the public DNS servers aren't used.
Pada titik ini saya ingin dapat menggunakan layanan lokal, terikat pada 10.129.112.210:53. Sehingga yang berikut harus menghasilkan balasan:
$ ping google.com
^C
$ ping user.skydns.local
^C
Ketika saya menjalankan perintah yang sama dari host saya:
$ ping photo.skydns.localPING photo.skydns.local (10.129.112.206) 56(84) bytes of data.
64 bytes from 10.129.112.206: icmp_seq=1 ttl=64 time=0.790 ms
^C
Resolv.conf saya
$ cat /etc/resolv.conf
nameserver 10.129.112.210
nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4
Intinya di sini bukan untuk mengakses host publik, tetapi yang internal, menggunakan layanan DNS lokal yang tersedia di host (melalui instance buruh pelabuhan lain).
Untuk mengilustrasikannya lebih jauh (Keahlian desain ascii art saya melampaui iptables fu saya, sehingga harus dikatakan cukup pada titik ini):
______________________________________________
| __________________________ Host |
| | Docker DNS container | |
| ``````````````````````|``` |
| | |
| ,----------,---( private n. interface ) |
| | | |
| | | ( public n. interface )---
| | | |
| | | ( loopbck n. interface ) |
| | | |
| | | |
| | __|_______________________ |
| | | Docker service container | |
| | `````````````````````````` |
| | |
| | |
| [ Local host service using DNS. ] |
| |
|______________________________________________|
private (host) network interface: eth1 (10.129.0.0/16)
Docker network interface: docker0 (172.17.0.0/16)
Saya telah mencari, membaca, dan menerapkan berbagai contoh konfigurasi Iptables, tetapi saya tahu terlalu sedikit tentang aturan Iptables yang lebih "canggih" untuk memahami apa yang terjadi dan dengan demikian mendapatkan hasil yang diinginkan.
Output dari iptables -t nat -nL
:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
target prot opt source destination
Output dari cat /proc/sys/net/ipv4/ip_forward
:
1
iptables -t nat -nL
? Apakah Anda melakukan analisis paket, katakan lakukan ping dari wadah sumber dan gunakan tcpdump untuk menangkap paket di host.$ cat /proc/sys/net/ipv4/ip_forward -> 1
dan-A INPUT -i eth1 -j ACCEPT
menerima semua koneksi pada antarmuka pribadi . Aturan apa yang Anda lewatkan?-A INPUT -i docker0 -j ACCEPT
Jawaban:
Container berkomunikasi dengan host menggunakan
docker0
antarmuka. Untuk mengizinkan lalu lintas dari wadah, tambahkan:sumber
iptables -A INPUT -j LOG
. CapIN=docker0
akan sangat berguna dalam menentukan aturan tweak apa yang dibutuhkan. Tidak mengambil dari pekerjaan Laurentiu, yang sangat bagus - +1 dari saya!Saya telah mengalami situasi yang sangat mirip tetapi menambahkan
-A INPUT -i docker0 -j ACCEPT
akan membuka semua akses melalui antarmuka eth0 saya dari host docker ke kontainer yang sama sekali tidak seperti yang saya maksudkan.Dan karena saya perhatikan bahwa kontainer saya hanya memiliki akses terbatas (katakan saja port 22) ke antarmuka host daripada benar-benar dimatikan dari jaringan host, saya meninjau aturan iptables saya dan menemukan aturan dalam rantai IN_public_allow yang harus bertanggung jawab untuk ini. Aturannya adalah
-A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
. Jadi saya menambahkan aturan serupa untuk memungkinkan wadah saya mengakses port host lain yang diinginkan, yang menurut saya bisa menjadi cara yang lebih tepat untuk membuka akses jaringan host ke kontainer.sumber
-i docker0
harus memastikan bahwa ini tidak akan mempengaruhi lalu lintas yang tidak datang melalui jaringan docker0. Tata bahasamu tidak jelas. Mungkin Anda mengatakan bahwa akses keluar dari host buruh pelabuhan via eth0 diaktifkan, yang mungkin benar. Saya setuju bahwa aturan yang lebih bertarget dimungkinkan untuk dibuka hanya sebanyak yang Anda butuhkan.