Dockerのネットワークの基礎
今までいろいろ触ってきて,Dockerネットワーク周りに関しては何となくは理解していたが,人に説明できるほど理解してなかったのでまとめておく.基本は,Advanced networking - Docker Documentationがベースになっている.
仮想ブリッジの仕組み
Dockerのネットワークは,仮想ブリッジdocker0
を通じて管理され,他のネットワークとは隔離された環境で動作する.
Dockerデーモンを起動すると,
- 仮想ブリッジ
docker0
の作成 - ホストの既存ルートからの空きのIPアドレス空間を検索
- 空きから特定の範囲のIPアドレス空間を取得
- 取得したIPアドレス空間を
docker0
に割り当て
が行われる.
コンテナを起動すると,コンテナには以下が割り当てられる.
docker0
に紐づいたveth
(Virtual Ethernet)インターフェースdocker0
に割り当てられたIPアドレス空間から専用のIPアドレス
そしてdocker0
はコンテナのデフォルトのgatewayとして利用されるようになる.コンテナに付与されるveth
は仮想NICで,コンテナ側からはeth0
として見える.2つはチューブのように接続され,あらゆるやりとりはここを経由して行われるようになる.
実際にコンテナを起動して確認する.まず,インターフェースから.
1 2 3 |
|
1 2 |
|
1 2 |
|
1 2 3 |
|
b9ffb0800ca5
コンテナにはveth29c1
が,4c0d9b786e8f
コンテナにはveth9eb7
がそれぞれ割り当てられているのがわかる.
次にIPを見てみる.
1 2 3 |
|
1 2 |
|
1 2 |
|
docker0
に割り当てられた172.17.42.1/16
のうち,b9ffb0800ca5
コンテナには172.17.02
が,4c0d9b786e8f
コンテナには172.17.0.3
がそれぞれ割り当てられているのがわかる.
コンテナ同士のやりとり
コンテナ間のやりとりの制御は,Dockerデーモンの-icc
パラメータにより行う.Dockerはこれにiptables
を使っている.
-icc=true
とすると,コンテナ間のやりとりが可能になる(default)-icc=false
とすると,コンテナ同士は隔離される
さらに,コンテナ同士でやりとりするにはportをdocker0
に晒す必要がある.これには,以下の2つの方法がある.
- Dockerfileに
EXPOSE <port>
を記述する - コンテナ起動時に
--expose <port>
を指定する
具体的に,docker0
を通じてコンテナ同士を接続する場合は,link機能を使う.コンテナを起動する際に,--link コンテナ名:エイリアス名
とすると,環境変数を通じて接続したいコンテナのIPやPortを取得できるようになる(詳しくは,“Dockerコンテナ間のlink,database.ymlの書き方”に書いた).
外部ネットワークからコンテナへのアクセス
外部ネットワークからコンテナにアクセスするには,コンテナを起動するときに外部ポートをdocker0
に晒した内部portにマップする必要がある.
例えば,ホストの8080ポートをコンテナの80ポートにマップしてApacheコンテナを起動してみる.
1 2 |
|
マッピングは以下で確認できる.
1 2 3 |
|
IDと晒したportを基に確認することもできる.
1 2 |
|
実際に接続してみる.
1 2 |
|
ホスト側のIPの指定を省略することもできる.この場合,自動でポートが選ばれる.
1 2 3 4 5 |
|