ニュース
» 2016年12月21日 08時00分 UPDATE

古賀政純の「攻めのITのためのDocker塾」:第33回 Dockerコンテナ同士の通信方法、フラットなネットワークを作る(後編) (1/4)

引き続き、「Swarmクラスタ」を使わずに複数の物理サーバで稼働するDockerコンテナ同士を通信させる方法について紹介します。前編ではコンテナ用のネットワーク「mynet1」を用いる方法を取り上げましたが、後編ではこれを使わない方法も取り上げてみたいと思います。

[古賀政純(日本ヒューレット・パッカード),ITmedia]

コンテナ用ネットワークを作成しないマルチホストでのコンテナ間通信

 前回の例では、ホストOSのブリッジインタフェース「docker1」に対して、docker network createにより、コンテナ用のネットワーク「mynet1」を作成し、マルチホストのコンテナ間通信を実現しましたが、一方、Dockerデーモンに対して使用するブリッジインタフェースを明示的にオプションから指定することで、コンテナ用のネットワーク「mynet1」を作成せずに、マルチホストのコンテナ間通信を実現することも可能です。

 Dockerデーモンは、デフォルトで172.17.0.0/16というIPアドレスが付与された「docker0」というブリッジインタフェースが自動的に生成されます。しかし、172.17.0.0/16は、ホストOSのネットワークセグメントと異なるため、外部との通信には、ホストOS側で提供されるNATとポート変換の仕組みが必要となります。そこで、ホストOSのブリッジインタフェースを明示的にDockerデーモンに指定することで、ホストOSと同じLANセグメントのIPアドレスをコンテナに対して自動的に付与することができです。

図.docker1をDockerデーモンに明示的に指定

 以下では、dockerデーモンに対して独自に作成したブリッジインタフェースdocker1を明示的に指定することで、コンテナ用のネットワークを作成せずにマルチホストのコンテナ間通信を行う設定の手順を示します。OSは、CentOS 7.2を想定します。今回のネットワーク構成は、以下のとおりです。

ホストA docker1
IPアドレス 172.16.44.1/16
コンテナ用ネットワーク名 なし
コンテナ用のセグメント 172.16.0.0/16

ホストB docker1
IPアドレス 172.16.44.2/16
コンテナ用ネットワーク名 なし
コンテナ用のセグメント 172.16.0.0/16

 まず、ホストOS上でブリッジインタフェース「docker1」の設定ファイル「ifcfg-docker1」と、それに対応するNICのeth0の設定ファイル「ifcfg-eth0」を作成します。今回は、docker1の固定IPアドレスとして172.16.44.1/16を割り当てるとします。


# vi /etc/sysconfig/network-scripts/ifcfg-docker1
DEVICE="docker1" ←ホストOSのブリッジインタフェース「docker1」を作成
BOOTPROTO="none"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Bridge"
IPADDR="172.16.44.1"
NETMASK="255.255.0.0"
GATEWAY=172.16.1.1
DNS1=172.16.1.1
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
HWADDR="52:54:00:df:b3:a3"
ONBOOT=yes
TYPE=Ethernet
BRIDGE="docker1" ←対応するブリッジインタフェースを指定

 次に、/etc/sysconfig/dockerファイルを読み込むように設定ファイル「docker.service」が記述されているかを念のために確認します。もし、以下の設定ファイル「docker.service」が/etc/systemd/systemディレクトリに存在しない場合は、事前に、/usr/lib/systemd/systemディレクトリからコピーしておく必要があります。


# cat /etc/systemd/system/docker.service  |grep -v ^# |grep -v ^$
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/docker ←設定ファイルが指定されていることを確認
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
ExecStart=/usr/bin/dockerd \
$OPTIONS \
$DOCKER_STORAGE_OPTIONS \
$DOCKER_NETWORK_OPTIONS \
$ADD_REGISTRY \
$BLOCK_REGISTRY \
$INSECURE_REGISTRY
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target

 上記の設定ファイルを編集した場合は、ホストOSのsystemdに変更を通知します。


# systemctl daemon-reload

 これで、Dockerデーモン(/usr/bin/dockerd)が設定ファイル「/etc/sysconfig/docker」に記載された文字列をオプションとして認識できるようになりましたので、Dockerの設定ファイル「/etc/sysconfig/docker」内で、独自に作成したブリッジインタフェースdocker1を「OPTIONS行」に指定します。


# vi /etc/sysconfig/docker
OPTIONS='-b=docker1 --selinux-enabled' ←ブリッジインタフェースを明示的に指定
DOCKER_CERT_PATH=/etc/docker

 上記のように、「-b=」の後にブリッジインタフェースdocker1を指定します。設定ファイルを正しく記述したら、ホストOSを再起動します。


# reboot

 ホストOS再起動後、ホストOSのネットワーク構成を確認します。


# ip -4 a
...
4: docker1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    inet 172.16.44.1/16 brd 172.16.255.255 scope global docker1
       valid_lft forever preferred_lft forever

 上記のとおり、ホストOSのブリッジインタフェース「docker1」は、外部のネットワークと通信できますが、それに加え、先述の「-b=docker1」の記述により、Dockerデーモンが利用するブリッジインタフェースとしても機能します。これにより、このホストOS上のコンテナは、ホストOSのブリッジインタフェース「docker1」のセグメントに所属することができます。試しに、コンテナを起動してみます。コンテナ起動時に「--net」オプションを指定していないことに注意してください。


# docker run -itd --name test02 centos:7.2.1511 /bin/bash

 起動したコンテナ「test02」のIPアドレスを調べます。


# docker inspect \
> --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
> test02
172.16.0.1

 コンテナ「test02」のIPアドレスが172.16.0.1であることが分かります。このコンテナ「test02」は、ホストOSと同一LANセグメントに所属しています。

注意

ただし、このネットワーク構成の場合は、docker networkによるネットワークを作成していませんので、docker run時の「--ipオプション」によりコンテナに固定IPアドレスを付与することはできませんので注意してください。


       1|2|3|4 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

ピックアップコンテンツ

- PR -

注目のテーマ