Docker の基本学習 ~ Docker のネットワーク

  • 143
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

単一ホスト内での Docker のネットワークの仕組みをまとめてみる。

全体像

まず、Docker のネットワークは以下の図ような構成になっている。
DockerNetwork.png

ざっとポイントをまとめるとこんな感じ。
* ホストには docker0 という仮想ブリッジが作成される
* コンテナは veth を介して仮想ブリッジに接続される
* コンテナ内からは eth0 というNIC があるように見える(実体は veth)
* コンテナ内の eth0 には、空いているIPアドレスが自動で割り当てられる(なので、IPアドレスは不定)。
* コンテナからホストの外部に通信するには、NAT(IPマスカレード)が使われる
* 単一ホスト上のコンテナ間の通信は、仮想ブリッジを経由して行われる(なので、コンテナ内で見える 172.17.0.0/16 のアドレスを使って通信できる)

もう少し詳しく

分からないところを調べてみた。

仮想ブリッジ

Linux 上に仮想的なL2スイッチを構成する機能(VMware ESXi でいえば、仮想スイッチのことかな)。Docker をインストールしたLinuxホストでは docker0 という仮想ブリッジが作られる。

# インターフェイスの表示
$ ifconfig -a
docker0   Link encap:Ethernet  HWaddr 56:84:7A:FE:97:99
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          (略...)

eth0      Link encap:Ethernet  HWaddr 06:D8:0E:5D:B8:C9
          inet addr:10.0.0.73  Bcast:10.0.0.255  Mask:255.255.255.0
          (略...)

# 仮想ブリッジの情報を表示してみる。
$ sudo yum install bridge-utils
$ brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.56847afe9799       no

veth

veth とは、仮想的なネットワークインターフェース(仮想NIC)。ただ、単純な仮想NICではなく、veth を作成すると2つの仮想NICのペアができ、この2つの間で通信ができるようになる(2つのNICをクロスケーブルで直結して通信する感じ)。

2つの veth のうち、1つはコンテナのネットワーク名前空間に入れられて、コンテナ内からのみ見えるようになる。また、名前も、コンテナ内では veth から eth0 に変更されている。
もう1つの veth は、ホスト側の仮想ブリッジ(docker0)に接続される。

コンテナを起動した後、ホストからは以下のように veth が作られていることが見れる。

$ ifconfig -a
docker0   Link encap:Ethernet  HWaddr 56:84:7A:FE:97:99
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          (略...)

eth0      Link encap:Ethernet  HWaddr 06:D8:0E:5D:B8:C9
          inet addr:10.0.0.73  Bcast:10.0.0.255  Mask:255.255.255.0
          (略...)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          (略...)

# コンテナを起動したら作成された(ホスト側の veth)
vethbe8a6db Link encap:Ethernet  HWaddr E6:B0:26:46:48:C6
          inet6 addr: fe80::e4b0:26ff:fe46:48c6/64 Scope:Link
          UP BROADCAST RUNNING  MTU:9001  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:508 (508.0 b)  TX bytes:438 (438.0 b)

# たぶん、ホスト側の veth が仮想ブリッジ(docker0)に接続されていることを表している
$ brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.56847afe9799       no              vethbe8a6db

また、コンテナ内からは eth0 が見える。そして、Default Gateway(DGW) は、ホスト側の docker0 の IPアドレスになっており、この DGW を経由して NAT で外部と通信することになる。

# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          (略...)

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

コンテナへのIPアドレスの割り当て

コンテナには、Docker が管理しているアドレス空間から空いている(使われていない)IPアドレスが自動で割り当てられる。なので、コンテナ内のIPは不定となる。

そのため、同一ホスト上に2つのコンテナがあるとして、一方から他方に通信したい場合は、リンクの機能 を使って接続先のIPアドレスを取得し、接続するという方法を取ることになる。

参考サイト

KVMで始めるプライベート・クラウドへの第一歩
第6回 Linuxカーネルのコンテナ機能[5] ─ネットワーク
Docker入門: コンテナ型仮想化技術の仕組みと使い方