Dockerのデフォルトbridgeネットワーク(docker0)について調べたメモ

Pocket

Dockerのネットワークについてまずはデフォルトのネットワークbridge(ネットワーク・インターフェース名:docker0)について、実際に試しながら調べた内容をメモします。

前提

  • DockerをUbuntuにインストール
    • Ubuntu: 20.04.4 LTS
    • Docker: 20.10.16

Ref

bridgeネットワークの概要

  • コンテナはネットワークを指定しない場合はデフォルトのbridgeネットワークに接続
    • デフォルトのbridgeネットワークのネットワーク・インターフェースがdocker01
    • デフォルトのbridgeネットワークに接続されたコンテナ間はIPアドレスで通信可能
    • デフォルトのbridgeネットワークに接続されたコンテナ間はコンテナ名で通信不可(内蔵DNSサーバを持たないため)
  • 新規に作成したbridgeネットワークに接続したコンテナ間はコンテナ名で通信可能
  • Docker Composeは、自動で新しくbridgeネットワークが作成されるのでservice名で通信可能

デフォルトネットワーク

Dockerのインストール時にデフォルトでNameがbridgehostnullのネットワークが作成されます。

$ sudo docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
abf0a3a6242a   bridge    bridge    local     <--- このネットワークのネットワーク・インターフェースがLinuxはdocker0、Macはbridge0
5647050e2ccb   host      host      local
f17799accf48   none      null      local

デフォルトで作成されるbridgeネットワークのネットワーク・インターフェースがdoker0になります(Linuxの場合2)。

Docker のインストールは、自動的に3つのネットワークを作成します。

https://docs.docker.jp/engine/userguide/networking/dockernetworks.html

Docker をインストールした全ての環境には、 docker0 と表示されるブリッジ( bridge )ネットワークが現れます。オプションで docker run –net=<ネットワーク名> を指定しない限り、Docker デーモンはデフォルトでこのネットワークにコンテナを接続します。ホスト上で ifconfig コマンドを使えば、ホストネットワーク上のスタックの一部として、このブリッジを見ることができます。

https://docs.docker.jp/engine/userguide/networking/dockernetworks.html

デフォルトのbridgeネットワーク

  • デフォルトのbridgeネットワークのネットワーク・インターフェースはLinuxではdocker0になります
  • コンテナ起動時にネットワークを指定しなければ、コンテナはデフォルトのbridgeネットワークに接続されます

ネットワークインターフェース

ホストは以下のネットワーク・インターフェースを持つと仮定します。

  • eth0:ホストのデフォルトのネットワーク・インターフェース
  • docker0:デフォルトのbridgeネットワークのネットワーク・インターフェース

コンテナ同士の通信

IPアドレス3を使ったコンテナ間通信においてdocker0に発生するデータをキャプチャしてみます。

$ docker run -itd --name alpine1 alpine:latest
$ docker run -itd --name alpine2 alpine:latest

コンテナのIPアドレスを確認します。

$ sudo docker exec -it alpine1 /bin/sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          ...

alpine1のIPアドレスは172.17.0.2です。
同様にalpine2のIPアドレスは172.17.0.3とします。

コンテナ間通信はdocker0送信されていることを確認します。

$ sudo tcpdump -tnl -i docker0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes

alpine1からalpine2pingを発行します。

$ docker exec -it alpine /bin/sh
/ # ping -c 1 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.110 ms

予想どおりdocker0に通信が発生しています。

$ sudo tcpdump -tnl -i docker0 icmp                                                                                                                        [15/84]
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes

.....
IP 172.17.0.2 > 172.17.0.3: ICMP echo request, id 12, seq 0, length 64
IP 172.17.0.3 > 172.17.0.2: ICMP echo reply, id 12, seq 0, length 64

コンテナとインターネットの通信

外部との通信します。
Googleが提供するフルサービスリゾルバ8.8.8.8pingを発行します。

$ sudo docker exec -it alpine1 /bin/sh
/ # ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=101 time=3.000 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 3.000/3.000/3.000 ms

docker0に通信が発生しています。

$ sudo tcpdump -tnl -i docker0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes

.....
IP 172.17.0.2 > 8.8.8.8: ICMP echo request, id 27, seq 0, length 64
IP 8.8.8.8 > 172.17.0.2: ICMP echo reply, id 27, seq 0, length 64

加えてホストのデフォルトのネットワーク・インターフェースeth0にも通信が発生していることが分かります。

$ sudo tcpdump -tnl -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

...
IP 10.3.0.183 > 8.8.8.8: ICMP echo request, id 27, seq 0, length 64
IP 8.8.8.8 > 10.3.0.183: ICMP echo reply, id 27, seq 0, length 64

外部からのアクセス

まとめとして、httpd:latestを稼働しているホストに外部からアクセスした際の通信をみます。

前提

  • ホスト
    • グローバルIPアドレス:203.0.113.1/24
    • プレイベートIPアドレス:192.0.2.1/24
    • ネットワーク・インターフェース
      • eth0
      • docker0
  • コンテナ
    • プライベートIPアドレス:172.17.0.4
    • ネットワーク・インターフェース
      • eth0
  • クライアント
    • グローバルIPアクセス:203.0.113.150/24

コンテナ稼働

$ sudo docker run -d -p 8000:80 --name httpd httpd

通信を確認

クライアントのブラウザで http://203.0.113.1:8000 にアクセスします。

ホストのeth0の通信をみます。
クライアントとホストはポート8000番で通信しています。

$ sudo tcpdump -tnl -i eth0 tcp port 8000                                                                                                           [19/1972]
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

IP 203.0.113.150.64640 > 192.0.2.1.8000: Flags [S], seq 218777360, win 65535, options [mss 1394,nop,wscale 6,nop,nop,TS val 3364579648 ecr 0,sackOK,eol], length 0
IP 192.0.2.1.8000 > 203.0.113.150.64640: Flags [S.], seq 1645943187, ack 218777361, win 65160, options [mss 1460,sackOK,TS val 2400436806 ecr 3364579648,nop,wscale 6], length 0
IP 203.0.113.150.64639 > 192.0.2.1.8000: Flags [.], ack 1, win 2051, options [nop,nop,TS val 1426504603 ecr 2400436806], length 0

ホストのdocker0の通信をみます。
コンテナとポート80番で通信しています。

$ sudo tcpdump -tnl -i docker0 tcp port 80                                                                                                          [19/1804]
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes

IP 203.0.113.150.64640 > 172.17.0.4.80: Flags [S], seq 218777360, win 65535, options [mss 1394,nop,wscale 6,nop,nop,TS val 3364579648 ecr 0,sackOK,eol], length 0
IP 172.17.0.4.80 > 203.0.113.150.64640: Flags [S.], seq 1645943187, ack 218777361, win 65160, options [mss 1460,sackOK,TS val 2400436806 ecr 3364579648,nop,wscale 6], length 0
IP 203.0.113.150.64639 > 172.17.0.4.80: Flags [.], ack 1, win 2051, options [nop,nop,TS val 1426504603 ecr 2400436806], length 0

コンテナのeth0の通信をみます。
予想どおりポート80番で通信しています。

# tcpdump -tnl -i eth0 tcp port 80
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes

IP 203.0.113.150.64640 > 172.17.0.4.80: Flags [S], seq 218777360, win 65535, options [mss 1394,nop,wscale 6,nop,nop,TS val 3364579648 ecr 0,sackOK,eol], length 0
IP 172.17.0.4.80 > 124.18.121.200.64640: Flags [S.], seq 1645943187, ack 218777361, win 65160, options [mss 1460,sackOK,TS val 2400436806 ecr 3364579648,nop,wscale 6], length 0
IP 124.18.121.200.64639 > 172.17.0.4.80: Flags [.], ack 1, win 2051, options [nop,nop,TS val 1426504603 ecr 2400436806], length 0

簡単ですが外部からのアクセスに対するコンテナのネットワークについてみました。## Ref.


  1. Macの場合はbridge0です。 

  2. Macはbridge0になります。 

  3. コンテナ名で通信する場合はdocker0ではなく、docker network create {{network_name}}で作成したネットワークを割り当てます。 

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。