Dockerのマルチホストネットワークの概要説明と環境構築


 前回は、単一のDockerホスト内のDockerネットワークについて解説しました。

 今回は、異なるDockerホスト上のコンテナのネットワークであるマルチホストネットワークについて解説させていただきます。

 マルチホスト間のネットワーク構成は、Dockerのバージョン1.9より前のDocker単体では実現できず、flannelなどの他のアプリケーションを利用することで実現していました。

 しかし、Docker Engineのバージョン1.9でマルチホストネットワーク機能が実装されまして、Docker単体で実現できるようになっております。

※但し、ネットワーク情報を共有するためのキーバリューストアサーバーは別途必要です。

 本記事では、Dockerのマルチホストネットワークの概要について解説しております。また、そのあとでシンプルな環境の構築方法についても解説しております。

前回記事はこちら:Dockerネットワークの概要とその作り方の解説

 

マルチホスト間でのDockerネットワークの構成

 異なるDockerホスト上のコンテナを、同じDockerネットワークに参加させるためには、以下のような環境を構築する必要があります。

docker-network-multi10

 図中の「overlay」部分が、マルチホストネットワークを実現するための仮想ネットワークインターフェイスです。

 キーバリューストアサーバーには、マルチホストネットワーク環境で必要な情報(ネットワーク名や対象コンテナなど)が格納されています。キーバリューストアサーバーには、マルチホストネットワークの情報を、そのネットワークに参加するコンテナ間で共有するという目的があります。

 キーバリューストアサーバーのホスト名は、Dockerデーモンに定義します。同じマルチホストネットワークに参加させたいコンテナが存在するDockerホストには、同じキーバリューストアサーバーを定義する必要があります。

 コンテナ(仮想nicを含む)や物理nicに関しては、マルチホストネットワークを意識する必要はありません。

 結局のところ、単一Dockerホスト内のネットワーク環境とマルチホストネットワーク環境の構成上の違いは、仮想ネットワークであるoverlayの部分とキーバリューストアサーバーの部分だけということがお分かりいただけたと思います。コンテナやDockerホストのネットワークインターフェイスなどには、構成上の変更は必要ありません。

 

マルチホスト間でのDockerネットワーク環境の構築

 では、実際にサンプル環境を構築したいと思います。

 構築する環境は以下のとおりです。

docker-network-multi20

 マルチホストネットワークoverlay01を作成し、Dockerホスト1上のコンテナvmtest1とDockerホスト2上のコンテナvmtest2を参加させます。

 サンプル環境は、以下を用意しました。

 Docker公式ドキュメントによりますと、マルチホストネットワークの前提条件として、DockerホストのOSのカーネルバージョンが3.16以上と記載されてました。いつもはDockerホストとしてCentOSを利用しているのですが、CentOS最新版(2017.02現在)のカーネルバージョンが3.10で要件を満たしませんでしたので、今回はUbuntuを利用することにしました。

  • Dockerホスト1
OS Ubuntu 14.04
kernel 4.4.0-31
Docker 1.13.1
IPアドレス 192.168.1.1
コンテナ vmtest1
仮想ネットワーク overlay01
  • Dockerホスト2
OS Ubuntu 16.04
kernel 4.4.0-75
Docker 1.13.1
IPアドレス 192.168.1.2
コンテナ vmtest2
仮想ネットワーク overlay01
  • キーバリューストアサーバー
OS Ubuntu 17.04
kernel 4.10.0-19
Docker 1.13.1
IPアドレス 192.168.1.3

 

キーバリューストアサーバーの構築

 では、まずキーバリューストアサーバーから作っていきたいと思います。

※キーバリューストアサーバーとは、キーと値の組を登録して、 キーを指定し値を読みだすことができるデータベース管理サーバーのことを指します

 Docker公式ドキュメントによりますと、キーバリューストアはConsul、Etcd、Zookeeperのいずれか、と記載されてました。よって今回は、公式ドキュメント内の構築例でも使用してますConsulを利用することにしました。

 Consulを自力で構築しても良いのですが、これについても公式ドキュメントと同様に、DockerHubからConsulイメージを入手して、コンテナとして構築することにしました。本筋でないところであまりハマりたくない、というのが正直なところです。

 キーバリューストアサーバーにDockerをインストールしまして、以下のコマンドでコンテナを起動します。(Dockerのインストールに関しましては省略します)

$ docker run -d -p 8500:8500 -h consul progrium/consul -server -bootstrap

 起動されているか確認します。

$ docker ps
CONTAINER ID   IMAGE            COMMAND                 CREATED        STATUS        PORTS                                                                           NAMES
fc76971448e9   progrium/consul  "/bin/start -serve..."  4 seconds ago  Up 3 seconds  53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp, 8301-8302/udp, 0.0.0.0:8500->8500/tcp  dazzling_johnson

 これでキーバリューストアサーバーの準備は完了です。

 

Dockerホスト1の構築

※本項の作業は管理者権限で行う必要があります

 Dockerの最新版をインストールします。インストール方法は割愛させてください。

 次に、Dockerデーモンにキーバリューストアサーバーを定義します。

 今回のサンプル環境では、Dockerホスト1と2のOSを異なるバージョン(Ubuntuの14.04と16.04)にしました。マルチホストネットワーク環境を構築する際、Dockerデーモンのオプション設定を行う必要があるのですが、その設定方法が、Ubuntuの14.04と16.04で異なるので2つとも試したい、というのがその理由です。

 まず最初に構築するDockerホスト1のOSは、Ubuntu14.04です。

 このバージョンは、OSのサービス管理機能にrcスクリプトを使用してます。この場合、Dockerデーモンのパラメータは、/etc/default/dockerファイルに設定します。

 viなどのテキストエディタで/etc/default/dockerファイルを開きまして、その最下行に以下を記述して下さい。

DOCKER_OPTS="--cluster-store=consul://192.168.1.3:8500 --cluster-advertise=eth0:2376"

 ここで、赤字部分(192.168.1.3)はキーバリューストアサーバーのIPアドレスを設定します。また、ピンク色部分(eth0)はDockerホスト1のネットワークインターフェイス名を設定して下さい。

 設定が終わりましたら、以下のコマンドでDockerサービスを再起動します。

※現在起動中のコンテナは停止してしまいますのでご注意ください。

# service docker restart

 以下の内容が表示されましたら正常に再起動が完了しています。(1672の部分はDockerデーモンのプロセスIDですので環境によって異なります)

docker stop/waiting
docker start/running, process 1672

 

Dockerホスト2の構築

※本項の作業は管理者権限で行う必要があります

 次に構築するDockerホスト2のOSは、Ubuntu16.04です。

 このバージョンは、OSのサービス管理機能にsystemdを使用してます。この場合、Dockerデーモンのパラメータは、/lib/systemd/system/docker.serviceファイルに設定します。

※systemdの設定はハマりポイントですので、単純な設定方法で解説させていただきます

 viなどのテキストエディタにて/lib/systemd/system/docker.serviceファイルを開きまして、以下の部分を見つけます。

(省略)
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd://
(省略)

 この部分の「ExecStart=/usr/bin/dockerd -H fd://」の後に以下の内容を記述します。

--cluster-store=consul://192.168.1.3:8500 --cluster-advertise=eth0:2376

 赤字部分(192.168.1.3)はキーバリューストアサーバーのIPアドレスを設定します。また、ピンク色部分(eth0)はDockerホスト1のネットワークインターフェイス名を設定して下さい。

 記述後は、以下のとおりになります。

ExecStart=/usr/bin/dockerd -H fd:// --cluster-store=consul://192.168.1.3:8500 --cluster-advertise=eth0:2376

 定義が終わりましたら、以下のコマンドを実行して、Dockerサービスの再起動を行います。

# systemctl daemon-reload
# systemctl restart docker

 最後に、以下のコマンドでDockerサービスの状態を確認します。

# systemctl status docker

 以下のように、出力内容の3行目に「active (running)」が表示されていれば大丈夫です。

 docker.service - Docker Application Container Engine
 Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: e
 Active: active (running) since 月 2017-03-06 16:09:15 JST; 29s ago
(以下省略)

 

まとめ

 今まで単一のDockerホストで動いていたコンテナを、マルチホスト環境に移行する場合には、移行先のDockerホスト上でマルチホストネットワークを作成して、今まで動いていたコンテナを移行先でマルチネットワークに参加させて再実行すれば完了です。

 但し、IPアドレスなどは変わってしまいますので、コンテナ内にハードコードしている場合は大変な作業になってしまいますが、そうでなければシンプルに移行作業が行えると思います。

 スケーラビリティに優れたDockerだけのことはあるのではないでしょうか。

 今回作成したマルチホストネットワークを利用して実際にコンテナを動かしてみた記事「Dockerのマルチホストネットワーク機能を試してみた」も宜しかったらご参照ください。

 

 最後までお読みいただきありがとうございました。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください