docker

メモ:Dockerのネットワーク(ブリッジネットワーク)

概要

  • Dockerのネットワークまわりについて調べる
  • Dockerのブリッジネットワークでどのように通信が行われるのか調べる
  • リンク機能については触れない

Dockerコンテナ・ネットワーク

まず、Dockerをインストールすると、デフォルトで3つのネットワークが作成され(ここでいう「ネットワーク」は、Docker内部の概念)、docker runしたときのデフォルトは、docker0というブリッジネットワークが使われる。

# デフォルトで作成される3つのネットワーク
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
d4d0e07e3979        bridge              bridge              local
ba38d64470bd        host                host                local
d1f35877f0fd        none                null                local
# ネットワークの詳細を確認
$ docker network inspect bridge
…出力は省略

docker0はifconfigで確認ができる。

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:82ff:feeb:c7b5  prefixlen 64  scopeid 0x20<link>
        ether 02:42:82:eb:c7:b5  txqueuelen 0  (イーサネット)
        RX packets 7519  bytes 409824 (409.8 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16155  bytes 18364515 (18.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

同じブリッジネットワークに属するコンテナ同士はそれぞれ通信可能なため、セキュリティ的に問題がある場合は新しくネットワークを作成し、所属するネットワークを分ける。

このブリッジはbrctlコマンドでも確認が可能であり、Linuxの標準機能で実現されていることがわかる。

$ brctl show
bridge name bridge id       STP enabled interfaces
docker0     8000.024282ebc7b5   no  

起動したコンテナがこのネットワークに属していることを確認するには、docker network inspect bridgeもしくはbrctl showを実行する。

コンテナ起動時に作成されるリソース、設定

構成

コンテナを起動すると下記のようなネットワーク構成が作られる。コンテナと外部の通信はvethによって実現され、仮想ブリッジから外へはiptablesの力を借りる。

image.png

引用元:https://www.kaitoy.xyz/2015/07/25/how-to-capture-packets-on-a-local-network-with-pcap4j-container/

veth

Linuxが提供する機能。コンテナごとに仮想NICのペアを作成し、一つはコンテナ内部に入れ(LinuxのNetwork namespaceを使う)、もう一つは仮想ブリッジと接続する。

コンテナ内部の仮想NICはeth0として作成され、ブリッジと同じサブネットのIPアドレスが自動的に割り振られる。仮想ブリッジと接続される仮想NICは、ホストOSからifconfigにより確認できる。

veth6f26945: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::fc41:30ff:fe01:3c56  prefixlen 64  scopeid 0x20<link>
        ether fe:41:30:01:3c:56  txqueuelen 0  (イーサネット)
        RX packets 6  bytes 516 (516.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 31  bytes 3191 (3.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

iptables

外部ネットワークとコンテナとの通信は、iptablesによりIPマスカレードにより実現する。

dockerにより追加された設定を確認する。iptables-saveで見てもいいが、ここではiptables -Lで見ている。

natテーブル

「MASQUERADE」の行がポイント。

# 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         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0     

filterテーブル

特に面白い設定はないが、filterテーブルにも設定は入る。

# iptables -t filter -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-ISOLATION  all  --  0.0.0.0/0            0.0.0.0/0           
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

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  --  0.0.0.0/0            0.0.0.0/0  

ブリッジネットワーク追加時

次のようにブリッジネットワークを追加可能。

$ docker network create --driver bridge my_bridge_nw

このときiptablesの設定も追加される。

参考