デフォルトでは、Dockerは仮想ブリッジ_docker0
_を作成し、すべてのコンテナネットワークが_docker0
_にリンクされていることを知っています。
上記のように:
eth0
_はvethXXX
とペアになっていますvethXXX
は、スイッチにリンクされたマシンと同じ_docker0
_にリンクされますしかし、_docker0
_とホスト_eth0
_の関係は何ですか?すなわち:
質問2は少しわかりにくいかもしれませんが、それをそのままにして、もう少し説明します。
eth0
_に送信されます。どのようにコンテナに転送されますか?つまり、情報を保存する場所があるはずです。どうすれば確認できますか?前もって感謝します!
答えと公式のネットワーク記事を読んだ後、次の図は、_docker0
_と_eth0
_に直接リンクがなく、代わりにパケットを転送できることを示しています。
http://dockerone.com/uploads/article/20150527/e84946a8e9df0ac6d109c35786ac4833.png
デフォルトのdocker0
ブリッジとホストイーサネットデバイスの間に直接リンクはありません。コンテナに--net=Host
オプションを使用すると、ホストとコンテナのネットワークスタックがリンクされます。
パケットがコンテナからdocker0に流れるとき、どのようにそれがeth0に転送されてから外部の世界に転送されるかをどのように知るのですか?
docker0
ブリッジには、それに割り当てられたDockerネットワークの.1
アドレスがあります。これは通常、172.17または172.18の周りのものです。
$ ip address show dev docker0
8: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:03:47:33:c1 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
コンテナには、docker0
ブリッジに接続されたvethインターフェイスが割り当てられます。
$ bridge link
10: vethcece7e5 state UP @(null): <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2
デフォルトのDockerネットワークで作成されたコンテナは、デフォルトルートとして.1
アドレスを受け取ります。
$ docker run busybox ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 src 172.17.0.3
Dockerは、そこからのアウトバウンドトラフィックにNAT MASQUERADEを使用し、ホストの標準アウトバウンドルーティングに従います。デフォルトではeth0
である場合とそうでない場合があります。
$ iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
iptablesは、接続の追跡とリターントラフィックを処理します。
外部パケットがeth0に到着したとき、なぜdocker0に転送され、その後container処理する代わりに、またはドロップしますか?
戻りのアウトバウンドトラフィックについて尋ねる場合は、上記のiptablesを参照してください。
新しい着信トラフィックを意味する場合、パケットはデフォルトでコンテナに転送されません。これを達成する標準的な方法は、 ポートマッピング をセットアップすることです。 Dockerは、ポートXのホストでリッスンし、ポートYのコンテナーに転送するデーモンを起動します。
なぜNATがインバウンドトラフィックにも使用されなかったのか。多数のポートをコンテナにマップしようとすると、 現実世界のインターフェイス を完全にコンテナにマッピングする。
コンテナからのネットワークインターフェイスiflink
およびホストマシン上のifindex
によって関係を検出できます。
コンテナからiflink
を取得します。
$ docker exec ID cat /sys/class/net/eth0/iflink
17253
次に、ホストマシンのインターフェイスでこのifindex
を見つけます。
$ grep -l 17253 /sys/class/net/veth*/ifindex
/sys/class/net/veth02455a1/ifindex