Dockerとネットワークネームスペースの関係
前回はDockerCEのインストールを行いました。
https://qiita.com/sugimount/items/0b14b8d544ab1d95e219
今回は、Dockerとネットワークネームスペースの関係を見ていきます。
コンテナ実行前の各種状態を確認
Dockerに関係している関連技術について、コンテナ実行前のタイミングで各種状態を確認していきます。
DockerImageの現在のものを一覧
[root@sugi-docker-registory ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest f2a91732366c 3 months ago 1.85kB
LinuxBridgeの確認
Defaultで作成されている docker0 という名前のブリッジには、何もinterfaceが接続されていません
[root@sugi-docker-registory ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242ac6ec522 no
ipコマンドでインターフェースを確認
[root@sugi-docker-registory ~]# ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:50:56:98:57:73 brd ff:ff:ff:ff:ff:ff promiscuity 0
inet 192.168.120.210/24 brd 192.168.120.255 scope global ens192
valid_lft forever preferred_lft forever
inet6 fe80::98a0:413d:6b71:8fbd/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:ac:6e:c5:22 brd ff:ff:ff:ff:ff:ff promiscuity 0
bridge forward_delay 1500 hello_time 200 max_age 2000 ageing_time 30000 stp_state 0 priority 32768 vlan_filtering 0 vlan_protocol 802.1Q bridge_id 8000.2:42:ac:6e:c5:22 designated_root 8000.2:42:ac:6e:c5:22 root_port 0 root_path_cost 0 topology_change 0 topology_change_detected 0 hello_timer 0.00 tcn_timer 0.00 topology_change_timer 0.00 gc_timer 0.28 vlan_default_pvid 1 group_fwd_mask 0 group_address 01:80:c2:00:00:00 mcast_snooping 1 mcast_router 1 mcast_query_use_ifaddr 0 mcast_querier 0 mcast_hash_elasticity 4 mcast_hash_max 512 mcast_last_member_count 2 mcast_startup_query_count 2 mcast_last_member_interval 100 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000 mcast_startup_query_interval 3125
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe6e:c522/64 scope link
valid_lft forever preferred_lft forever
iptablesでNAPTしているので、natテーブルを確認
docker0のブリッジがIPマスカレードするルールが存在しています
[root@sugi-docker-registory ~]# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere 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 -- anywhere !loopback/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 anywhere
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
filterテーブルも確認
[root@sugi-docker-registory ~]# iptables -L -t filter
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (1 references)
target prot opt source destination
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
ローカルレジストリをコンテナとして実行
以下コマンドを実行して、ローカルレジストリをコンテナとして実行します
オプションの説明
-d : コンテナ実行をバックグラウンドで実行する。また、コンテナーIDを表示する。
-p : コンテナのポートをホストに公開します。 ホスト側のポート:コンテナ側のポート
--restart : コンテナが存在しているときの、restartのポリシーを設定します
--name : コンテナに名前を指定します
registory:2 : コンテナを実行する際に指定するイメージ名の指定。存在しない場合はDockerHubからダウンロードする
docker run -d -p 5000:5000 --restart=always --name registry registry:2
実行例
[root@sugi-docker-registory ~]# docker run -d -p 5000:5000 --restart=always --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
81033e7c1d6a: Pull complete
b235084c2315: Pull complete
c692f3a6894b: Pull complete
ba2177f3a70e: Pull complete
a8d793620947: Pull complete
Digest: sha256:672d519d7fd7bbc7a448d17956ebeefe225d5eb27509d8dc5ce67ecb4a0bce54
Status: Downloaded newer image for registry:2
e03c7a5b8ded2a9b68a045eba91eccb15c7567ef51d464719528c1757cecda43
registryコンテナが稼働している
[root@sugi-docker-registory ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e03c7a5b8ded registry:2 "/entrypoint.sh /etc…" 2 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp registry
コンテナ実行後の各種状態を確認
コンテナのネットワークは以下の画像のような接続になっています
docker0に、veth25382cfという名前のvethが接続されています
[root@sugi-docker-registory ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242ac6ec522 no veth25382cf
ipコマンドでインターフェースを確認
veth25382cf が veth として存在していることが確認できます
veth25382cf の対向のインターフェース番号16のものは、ホスト側からは確認できません
ネットワークネームスペースを使用してネットワークが分離されているため、ホスト側からでは確認することが出来ません
[root@sugi-docker-registory ~]# ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:50:56:98:57:73 brd ff:ff:ff:ff:ff:ff promiscuity 0
inet 192.168.120.210/24 brd 192.168.120.255 scope global ens192
valid_lft forever preferred_lft forever
inet6 fe80::98a0:413d:6b71:8fbd/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:6e:c5:22 brd ff:ff:ff:ff:ff:ff promiscuity 0
bridge forward_delay 1500 hello_time 200 max_age 2000 ageing_time 30000 stp_state 0 priority 32768 vlan_filtering 0 vlan_protocol 802.1Q bridge_id 8000.2:42:ac:6e:c5:22 designated_root 8000.2:42:ac:6e:c5:22 root_port 0 root_path_cost 0 topology_change 0 topology_change_detected 0 hello_timer 0.00 tcn_timer 0.00 topology_change_timer 0.00 gc_timer 195.44 vlan_default_pvid 1 group_fwd_mask 0 group_address 01:80:c2:00:00:00 mcast_snooping 1 mcast_router 1 mcast_query_use_ifaddr 0 mcast_querier 0 mcast_hash_elasticity 4 mcast_hash_max 512 mcast_last_member_count 2 mcast_startup_query_count 2 mcast_last_member_interval 100 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000 mcast_startup_query_interval 3125
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe6e:c522/64 scope link
valid_lft forever preferred_lft forever
17: veth25382cf@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether be:b6:f6:2b:62:43 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 1
veth
bridge_slave state forwarding priority 32 cost 2 hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8001 port_no 0x1 designated_port 32769 designated_cost 0 designated_bridge 8000.2:42:ac:6e:c5:22 designated_root 8000.2:42:ac:6e:c5:22 hold_timer 0.00 message_age_timer 0.00 forward_delay_timer 0.00 topology_change_ack 0 config_pending 0 proxy_arp off proxy_arp_wifi off mcast_router 1 mcast_fast_leave off mcast_flood on
inet6 fe80::bcb6:f6ff:fe2b:6243/64 scope link
valid_lft forever preferred_lft forever
iptablesのnatテーブルを確認
registryコンテナ用のマスカレード、DNAT用のルールが追加されています。
[root@sugi-docker-registory ~]# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere 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 -- anywhere !loopback/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 anywhere
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:commplex-main ←追加されている
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
DNAT tcp -- anywhere anywhere tcp dpt:commplex-main to:172.17.0.2:5000 ←追加されている
registryコンテナのインターフェースを確認します
eth0@if17 が存在していて、docker0ブリッジと同一のセグメントに接続されています。
veth「veth25382cf」のもう片方側が、registryコンテナ内(ネットワークネームスペース内)に接続されています
[root@sugi-docker-registory ~]# docker exec -it registry ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
コンテナのネットワークネームスペースに潜り込む
コンテナを普通に起動しただけでは、ip netns コマンドでは、ネットワークネームスペースを確認することが出来ません
ip netnsコマンドは、/var/run/netns配下のファイルを使用して表示していますが、
Dockerを使用してコンテナを作成すると、ここのディレクトリにはファイルが作成されません。
Dockerでは、/proc/16360/ns/net にネットワーク識別子のシンボリックリンクが作成されています。
まずは、registryコンテナのPIDを確認します
[root@sugi-docker-registory ~]# docker inspect registry --format '{{.State.Pid}}'
16360
念のためpsコマンドでも確認
[root@sugi-docker-registory ~]# ps aux | grep 16360
root 16360 0.0 0.1 22028 7752 ? Ssl 00:07 0:00 registry serve /etc/docker/registry/config.yml
上記プロセスが使用しているネットワーク識別子を確認します
[root@sugi-docker-registory ~]# ls -la /proc/16360/ns/net
lrwxrwxrwx 1 root root 0 Mar 10 00:07 /proc/16360/ns/net -> net:[4026532447]
/proc/16360/ns/net を /var/run/netns 配下に置くと、ip netns コマンドで認識することが出来ます
以下のようにシンボリックリンクを作成します
mkdir -p /var/run/netns/
ln -s /proc/16360/ns/net /var/run/netns/registry-netns
これにより、ip netnsコマンドでネットワークネームスペースを認識することが出来ました
ここまで出来ると、OpenStackのNeutronでデバッグしてきたノウハウが使用できます
[root@sugi-docker-registory ~]# ip netns
registry-netns (id: 0)
ネットワークネームスペースでbashを起動します
ip netns exec registry-netns bash
インターフェースを確認します。
registryコンテナ用に分離されているネームスペース内でインターフェースを確認できます
[root@sugi-docker-registory ~]# ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0
veth
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
ルーティングテーブルを確認します
[root@sugi-docker-registory ~]# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
余談ですが・・・現在ログインしているネットワークネームスペース名を以下コマンドで確認することが出来ます
registry-netns用のネームスペース内で実行
ログインしているネームスペースの名前が表示されます
[root@sugi-docker-registory ~]# ip netns identify
registry-netns
ホストOS側で実行
何も表示されません
[root@sugi-docker-registory ~]# ip netns identify
[root@sugi-docker-registory ~]#
間違ってホストOS側に居ることに気が付かずにexitしてしまうあるあるを、回避することが出来ますね。
IPマスカレードのパケットを確認
registryコンテナから、外部ネットワークのGWへpingを行います
docker exec -it registry ping 192.168.120.254
通信イメージは以下の通り
コンテナ側のeth0でtcpdump
GWと通信が出来ています。
MacAddressを見ると、コンテナ側のeth0と、ホスト側のdocker0で通信を行っています。
[root@sugi-docker-registory ~]# ip netns exec registry-netns tcpdump -e -s 0 -nn -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
01:34:46.653792 02:42:ac:11:00:02 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 192.168.120.254: ICMP echo request, id 22272, seq 51, length 64
01:34:46.654201 02:42:ac:6e:c5:22 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.2: ICMP echo reply, id 22272, seq 51, length 64
01:34:47.654200 02:42:ac:11:00:02 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 192.168.120.254: ICMP echo request, id 22272, seq 52, length 64
01:34:47.654666 02:42:ac:6e:c5:22 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.2: ICMP echo reply, id 22272, seq 52, length 64
01:34:48.654465 02:42:ac:11:00:02 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 192.168.120.254: ICMP echo request, id 22272, seq 53, length 64
01:34:48.654809 02:42:ac:6e:c5:22 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.2: ICMP echo reply, id 22272, seq 53, length 64
01:34:49.654694 02:42:ac:11:00:02 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 192.168.120.254: ICMP echo request, id 22272, seq 54, length 64
01:34:49.655135 02:42:ac:6e:c5:22 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.2: ICMP echo reply, id 22272, seq 54, length 64
01:34:50.654929 02:42:ac:11:00:02 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 192.168.120.254: ICMP echo request, id 22272, seq 55, length 64
01:34:50.655262 02:42:ac:6e:c5:22 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.2: ICMP echo reply, id 22272, seq 55, length 64
ホスト側の物理NICでtcpdump
IPマスカレードが行われており、物理NICのens192のIPアドレスを使用して通信されています
MacAddressを見ると、ホスト側のens192とGWで通信を行っています。
[root@sugi-docker-registory ~]# tcpdump -e -s 0 -nn -i ens192 not port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes
01:33:00.470572 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 21248, seq 161, length 64
01:33:00.470898 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 21248, seq 161, length 64
01:33:01.470760 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 21248, seq 162, length 64
01:33:01.471002 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 21248, seq 162, length 64
01:33:02.470960 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 21248, seq 163, length 64
01:33:02.471199 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 21248, seq 163, length 64
01:33:03.471189 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 21248, seq 164, length 64
01:33:03.471407 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 21248, seq 164, length 64
01:33:04.471379 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 21248, seq 165, length 64
01:33:04.471620 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 21248, seq 165, length 64
01:33:05.471573 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 21248, seq 166, length 64
01:33:05.471801 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 21248, seq 166, length 64
01:33:06.471879 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 21248, seq 167, length 64
01:33:06.472236 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 21248, seq 167, length 64
2個目のコンテナを作成し、ネットワークの接続を確認
2個目のコンテナを作成します
適当にcentosイメージをDockerHubからダウンロードします
docker pull centos
実行例
[root@sugi-docker-registory ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
5e35d10a3eba: Pull complete
Digest: sha256:dcbc4e5e7052ea2306eed59563da1fec09196f2ecacbe042acbdcd2b44b05270
Status: Downloaded newer image for centos:latest
docker image に追加されている
[root@sugi-docker-registory ~]#
[root@sugi-docker-registory ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 2d194b392dd1 3 days ago 195MB ←追加されている
registry 2 d1fd7d86a825 8 weeks ago 33.3MB
hello-world latest f2a91732366c 3 months ago 1.85kB
2個目のコンテナを作成します
docker run -d -p 5001:5001 --name test_centos -it centos /bin/bash
実行例
[root@sugi-docker-registory ~]# docker run -d --name test_centos -it centos /bin/bash
2fec8a04d74bbe8c5e6f4824a1a091922a2160d3f530fc4194fa8a7e2a2befd8
CentOSのDockerイメージには、ipコマンドがインストールされていないので、インストールを行う
ついでにtcpdumpもインストールを行う
docker exec -it test_centos yum install iproute tcpdump
2個目のコンテナ実行後の各種状態を確認
コンテナのネットワークは以下の画像のような接続になっています
docker0に、 vetha8f91f8 という名前のvethが接続されています
[root@sugi-docker-registory ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242ac6ec522 no veth25382cf
vetha8f91f8 ←追加
ipコマンドでインターフェースを確認
vetha8f91f8 が veth として新たに存在していることが確認できます
vetha8f91f8 の対向のインターフェース番号24のものは、ホスト側からは確認できません
ネットワークネームスペースを使用してネットワークが分離されているため、ホスト側からでは確認することが出来ません
[root@sugi-docker-registory ~]# ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:50:56:98:57:73 brd ff:ff:ff:ff:ff:ff promiscuity 0
inet 192.168.120.210/24 brd 192.168.120.255 scope global ens192
valid_lft forever preferred_lft forever
inet6 fe80::98a0:413d:6b71:8fbd/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:6e:c5:22 brd ff:ff:ff:ff:ff:ff promiscuity 0
bridge forward_delay 1500 hello_time 200 max_age 2000 ageing_time 30000 stp_state 0 priority 32768 vlan_filtering 0 vlan_protocol 802.1Q bridge_id 8000.2:42:ac:6e:c5:22 designated_root 8000.2:42:ac:6e:c5:22 root_port 0 root_path_cost 0 topology_change 0 topology_change_detected 0 hello_timer 0.00 tcn_timer 0.00 topology_change_timer 0.00 gc_timer 269.16 vlan_default_pvid 1 group_fwd_mask 0 group_address 01:80:c2:00:00:00 mcast_snooping 1 mcast_router 1 mcast_query_use_ifaddr 0 mcast_querier 0 mcast_hash_elasticity 4 mcast_hash_max 512 mcast_last_member_count 2 mcast_startup_query_count 2 mcast_last_member_interval 100 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000 mcast_startup_query_interval 3125
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe6e:c522/64 scope link
valid_lft forever preferred_lft forever
17: veth25382cf@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether be:b6:f6:2b:62:43 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 1
veth
bridge_slave state forwarding priority 32 cost 2 hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8001 port_no 0x1 designated_port 32769 designated_cost 0 designated_bridge 8000.2:42:ac:6e:c5:22 designated_root 8000.2:42:ac:6e:c5:22 hold_timer 0.00 message_age_timer 0.00 forward_delay_timer 0.00 topology_change_ack 0 config_pending 0 proxy_arp off proxy_arp_wifi off mcast_router 1 mcast_fast_leave off mcast_flood on
inet6 fe80::bcb6:f6ff:fe2b:6243/64 scope link
valid_lft forever preferred_lft forever
25: vetha8f91f8@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether c6:b8:c4:ac:5e:22 brd ff:ff:ff:ff:ff:ff link-netnsid 1 promiscuity 1
veth
bridge_slave state forwarding priority 32 cost 2 hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8002 port_no 0x2 designated_port 32770 designated_cost 0 designated_bridge 8000.2:42:ac:6e:c5:22 designated_root 8000.2:42:ac:6e:c5:22 hold_timer 0.00 message_age_timer 0.00 forward_delay_timer 0.00 topology_change_ack 0 config_pending 0 proxy_arp off proxy_arp_wifi off mcast_router 1 mcast_fast_leave off mcast_flood on
inet6 fe80::c4b8:c4ff:feac:5e22/64 scope link
valid_lft forever preferred_lft forever
iptablesのnatテーブルを確認
test_centosコンテナ用のマスカレード、DNAT用のルールが追加されています。
[root@sugi-docker-registory ~]# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere 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 -- anywhere !loopback/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 anywhere
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:commplex-main
MASQUERADE tcp -- 172.17.0.3 172.17.0.3 tcp dpt:commplex-link ←追加されている
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
DNAT tcp -- anywhere anywhere tcp dpt:commplex-main to:172.17.0.2:5000
DNAT tcp -- anywhere anywhere tcp dpt:commplex-link to:172.17.0.3:5001 ←追加されている
test_centosコンテナのインターフェースを確認します
eth0@if25 が存在していて、docker0ブリッジと同一のセグメントに接続されています。
[root@sugi-docker-registory ~]# docker exec -it test_centos ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0
veth
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
コンテナ同士の通信を確認
test_centos → registry コンテナへPingが届きます。
docker0 ブリッジに接続されているので、互いにL2で通信が可能です
[root@sugi-docker-registory ~]# docker exec -it test_centos ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.164 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.084 ms
tcpdumpを実行します
MacAddressでみても、コンテナ同士で直に通信を行っています
[root@sugi-docker-registory ~]# docker exec -it test_centos tcpdump -e -s0 -nn -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:47:31.104219 02:42:ac:11:00:03 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 172.17.0.2: ICMP echo request, id 190, seq 26, length 64
17:47:31.104283 02:42:ac:11:00:02 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 172.17.0.3: ICMP echo reply, id 190, seq 26, length 64
17:47:32.104234 02:42:ac:11:00:03 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 172.17.0.2: ICMP echo request, id 190, seq 27, length 64
17:47:32.104296 02:42:ac:11:00:02 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 172.17.0.3: ICMP echo reply, id 190, seq 27, length 64
17:47:33.104286 02:42:ac:11:00:03 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 172.17.0.2: ICMP echo request, id 190, seq 28, length 64
17:47:33.104389 02:42:ac:11:00:02 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 172.17.0.3: ICMP echo reply, id 190, seq 28, length 64
17:47:34.104236 02:42:ac:11:00:03 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 172.17.0.2: ICMP echo request, id 190, seq 29, length 64
17:47:34.104299 02:42:ac:11:00:02 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 172.17.0.3: ICMP echo reply, id 190, seq 29, length 64
17:47:35.104208 02:42:ac:11:00:03 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 172.17.0.2: ICMP echo request, id 190, seq 30, length 64
17:47:35.104251 02:42:ac:11:00:02 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 172.17.0.3: ICMP echo reply, id 190, seq 30, length 64
test_centos → GW へ通信を行う
通信のイメージは以下の通り
test_centos → GW へpingを行う
docker exec -it test_centos ping 192.168.120.254
test_centos の eth0 で tcpdump
MacAddressは、同様に、コンテナ内のeth0とホスト側のdocker0で通信を行っています
[root@sugi-docker-registory ~]# docker exec -it test_centos tcpdump -e -s0 -nn -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:49:41.564237 02:42:ac:11:00:03 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 192.168.120.254: ICMP echo request, id 210, seq 7, length 64
17:49:41.564586 02:42:ac:6e:c5:22 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.3: ICMP echo reply, id 210, seq 7, length 64
17:49:42.564207 02:42:ac:11:00:03 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 192.168.120.254: ICMP echo request, id 210, seq 8, length 64
17:49:42.564562 02:42:ac:6e:c5:22 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.3: ICMP echo reply, id 210, seq 8, length 64
17:49:43.564284 02:42:ac:11:00:03 > 02:42:ac:6e:c5:22, ethertype IPv4 (0x0800), length 98: 172.17.0.3 > 192.168.120.254: ICMP echo request, id 210, seq 9, length 64
17:49:43.564597 02:42:ac:6e:c5:22 > 02:42:ac:11:00:03, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 172.17.0.3: ICMP echo reply, id 210, seq 9, length 64
ホスト側の物理NIC ens192 で tcpdump
同様に、ens192 のIPアドレスでマスカレードされています
[root@sugi-docker-registory ~]# tcpdump -e -s 0 -nn -i ens192 not port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes
02:51:10.693235 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 218, seq 20, length 64
02:51:10.693442 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 218, seq 20, length 64
02:51:11.693249 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 218, seq 21, length 64
02:51:11.693573 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 218, seq 21, length 64
02:51:12.693235 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 218, seq 22, length 64
02:51:12.693572 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 218, seq 22, length 64
02:51:13.693234 00:50:56:98:57:73 > 00:50:56:aa:36:d5, ethertype IPv4 (0x0800), length 98: 192.168.120.210 > 192.168.120.254: ICMP echo request, id 218, seq 23, length 64
02:51:13.693589 00:50:56:aa:36:d5 > 00:50:56:98:57:73, ethertype IPv4 (0x0800), length 98: 192.168.120.254 > 192.168.120.210: ICMP echo reply, id 218, seq 23, length 64
参考URL
Dockerとnetnsの関係
http://enakai00.hatenablog.com/entry/20140424/1398321672
https://qiita.com/ukinau/items/92740bd0bafc1e7427c5
既存コンテナのbashへ接続方法 attachとexecの違い
https://qiita.com/RyoMa_0923/items/9b5d2c4a97205692a560
DockerRegistryの構築
https://docs.docker.com/registry/