Mengapa wadah Docker yang menjalankan server mengekspos port ke dunia luar meskipun port tersebut diblokir oleh iptables?

Saya mengalami masalah dengan MySQL yang berjalan di dalam wadah Docker. Gambar pengujian saya dibangun dari Dockerfile berikut:

# See: https://index.docker.io/u/brice/mysql/FROM ubuntu:12.10MAINTAINER Joni Kahara <joni.kahara@async.fi> # Because docker replaces /sbin/init: https://github.com/dotcloud/docker/issues/1024RUN dpkg-divert --local --rename --add /sbin/initctlRUN ln -s /bin/true /sbin/initctlRUN apt-get updateRUN apt-get upgrade -yRUN apt-get -y install mysql-serverRUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnfRUN /usr/bin/mysqld_safe & \    sleep 10s && \    mysql -e "GRANT ALL ON *.* to 'root'@'%'; FLUSH PRIVILEGES;"EXPOSE 3306VOLUME ["/var/lib/mysql", "/var/log/mysql"]CMD ["mysqld_safe"]

Setelah membangun gambar dari file di atas, saya menjalankannya dengan:

docker run -p 3306:3306 asyncfi/magento-mysql

Setelah itu semuanya membengkak dan saya dapat masuk ke instance MySQL ini dari mesin lokal. Namun, saya juga bisa masuk dari mesin lain.

Saya telah menyiapkan firewall saya untuk memfilter semuanya kecuali lalu lintas yang masuk ke port tertentu (SSH"tersembunyi", HTTP, HTTPS), dan pemfilteran ini sebenarnya tampaknya berfungsi; jika saya misalnya menjalankan server pengembangan Django pada port 1234 maka saya dapat terhubung dari mesin lokal, tetapi tidak dari luar. Jadi firewall tampaknya memfilter paket ketika mereka ditakdirkan ke server yang berjalan sebagai proses "biasa", tetapi tidak ketika server berjalan di dalam wadah.

iptables-L - v -- line-numbers mengatakan sebagai berikut:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)num   pkts bytes target     prot opt in     out     source               destination1     2265  107K ACCEPT     all  --  lo     any     anywhere             anywhere2     240K  319M ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED3       14  1040 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:<REDACTED>4       21  1092 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:http5        6   360 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:https6      538 34656 LOG        all  --  any    any     anywhere             anywhere             limit: avg 5/min burst 5 LOG level debug prefix "iptables DROP: "7      551 35424 DROP       all  --  any    any     anywhere             anywhereChain FORWARD (policy ACCEPT 5 packets, 296 bytes)num   pkts bytes target     prot opt in     out     source               destination1        0     0 ACCEPT     all  --  docker0 docker0  anywhere             anywhere2     6752  396K ACCEPT     all  --  docker0 !docker0  anywhere             anywhere3     125K  188M ACCEPT     all  --  any    docker0  anywhere             anywhere             ctstate RELATED,ESTABLISHEDChain OUTPUT (policy ACCEPT 51148 packets, 14M bytes)num   pkts bytes target     prot opt in     out     source               destination

Versi Docker adalah:

Client version: 0.7.3Go version (client): go1.2Git commit (client): 8502ad4Server version: 0.7.3Git commit (server): 8502ad4Go version (server): go1.2Last stable version: 0.7.3

Mengapa Port MySQL terpapar ke dunia luar?

Terima kasih kepada pengguna saluran #docker IRC Michael Crosby dan Paul Czar saya sekarang dapat menjawab pertanyaan saya sendiri. Masalahnya terletak pada kenyataan bahwa saya menjalankan wadah seperti ini:

docker run -p 3306:3306 asyncfi/magento-mysql

Ini menerbitkan pelabuhan kontainer untuk semua antarmuka dari mesin host, yang jelas bukan yang saya cari saat ini. Untuk mengikat hanya ke localhost, perlu untuk menjalankan wadah sebagai berikut:

docker run -p 127.0.0.1:3306:3306 asyncfi/magento-mysql

Juga EXPOSE baris di Dockerfile tidak diperlukan karena mekanisme" expose " digunakan untuk wadah tautan.