LoginSignup
250
247

More than 5 years have passed since last update.

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

Posted at

単一ホスト内での 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入門: コンテナ型仮想化技術の仕組みと使い方

250
247
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
250
247