前回はDockerホスト単体でのコンテナ管理方法を紹介した。サービス提供環境では、以下の理由から複数のサーバで運用することが多い。

 ・ひとつのホストに負荷が集中するのを避けるため
 ・ホストがダウンした場合のリスクを軽減するため

そこで今回は、複数サーバでのDockerの活用方法を紹介する。

Dockerホスト間での通信

Docker1.8までは、異なるDockerホストに存在するコンテナにアクセスするためには、ポートフォワードの設定を行い、DockerホストのIPアドレスでアクセスする必要があった。これがDocker 1.9へのバージョンアップ時に、Docker multi-host networkingが正式にリリースされ、異なるDockerホストのコンテナ同士が直接アクセスできるようになった。

Docker multi-host networkingを実現するためには、「Overlay Network」と呼ばれるDockerホスト間の仮想ネットワークを設定する必要がある。Overlay Networkを利用するためには、以下の2種類の方法がある。

①Swarm mode

Swarm modeは、Dockerホスト群をひとつのクラスタ(※)として構成するDockerの機能である。この機能は、クラスタ情報を管理するManagerとクラスタに参加しているWorkerの2種類で構成されている。

※クラスタとは、複数台のシステムをネットワークで連結することでひとつのシステムとして処理や運用をする方法である。

②Swarm classic

Swarm classicは、Swarm modeのManagerの役割を、Docker以外のアプリケーションを使用しクラスタを構成する機能である。対応しているアプリケーションは以下の3種類である。

・Consul
・Etcd
・ZooKeeper

なおSwarm Classicは、Docker1.12の時点で、Swarm modeに更新することを推奨している。したがって、Overlay Networkによる複数サーバでの環境を構築したい場合は、Swarm modeでクラスタ環境を構成するとよい。

複数サーバでのWordPress構築

複数のサーバでWordPressを構築する場合に、想定される構成の一例を下に図示する。

WebサーバにはWordPressが、DatabaseサーバにはMySQLがインストールされている構成だ。このような構成をコンテナのみで実現するには、コンテナ同士をOverlay Networkにより通信できるようにする必要がある。

これを実現するためには、Swarm modeでDockerホスト群をクラスタ構成にすることは前述したとおりだ。まずは、Swarm modeによるクラスタの作成方法を説明する。手順は以下の流れとなる。

1.Swarm ModeでManagerとなるDockerホストを選択する。
Swarm Mode でのクラスタは、前述したようにManagerとWorkerで構成されており、Managerは必ずひとつ必要となる。今回はDatabaseサーバをManagerとする。

2.2. Databaseサーバにdocker swarm initコマンドを実行し、クラスタを初期化する。
実行コマンドと実行結果内容は以下のとおりだ。

$ docker swarm init
Swarm initialized: current node (vp45edklghtipuhhlrgtpi1jl) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token (クラスタ参加用トークン) (WebサーバのIPアドレス):2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
$

docker swarm initコマンド実行時に、他のDockerホストがこのクラスタにWorkerとして参加するためのコマンドが表示されるので、コピーしておく。

3.Webサーバでdocker swarm joinコマンドを実行し、クラスタに参加する。 実行コマンドと実行結果内容は以下のとおりだ。 。
実行コマンドと実行結果内容は以下のとおりだ。

$ docker swarm join --token (クラスタ参加トークン) (DatabaseサーバのIPアドレス):2377
This node joined a swarm as a worker.$

docker swarm joinコマンドを実行すると、クラスタにWorkerとして参加したとのメッセージが表示される。

4.Databaseサーバでdocker node lsコマンドを実行し、Webサーバがクラスタに参加しているか確認する。

docker node ls

このコマンドを実行後、Webサーバ、DatabaseサーバともにSTATUSがReadyとなればクラスタは完成だ。

次にOverlayNetworkをクラスタ上に作成する。OverlayNetworkの作成には、docker network createコマンドで--driverオプションにoverlayを指定すればよい。

ネットワーク名はwordpress-networkとする。

$ docker network create --driver overlay wordpress-network

上記コマンドをDatabaseサーバで実行すれば、Dockerホストのコンテナ間で使用できるネットワークの作成は完了だ。

最後にWordPressコンテナをクラスタ上で起動する。クラスタ上でコンテナを起動するには、docker container runコマンドではなくdocker service createコマンドを利用する。

MySQLコンテナをMangerであるDatabaseサーバで起動するには、以下のコマンドを実行すればよい。

$ docker service create\
   --name mysql \
   -e MYSQL_ROOT_PASSWORD=mysql \
   -d \
   --constraint 'node.role == manager' \
   --network wordpress-network \
   mysql

docker service createコマンドは、docker container runコマンドのオプションがそのまま利用可能であり、さらに独自のオプションも実装している。

コンテナの稼働状況は、docker service psコマンドを実行すれば確認できる。

$ docker service ps mysql

このコマンドを実行後、mysql.1のDESIRED STATEがRunningとなれば、起動しており利用は可能だ。

続いて、WordPressコンテナをWorkerであるWebサーバで起動する。

$ docker service create \
   --name wordpress \
   -e WORDPRESS_DB_PASSWORD=mysql \
   -p 8080:80 \
   -d \
   --constraint 'node.role == worker' \
   --network wordpress-network \
   wordpress

WordPressのコンテナが正常に起動しているか確認するには、第3回と同様にブラウザよりアクセスし、WordPressが正常に表示されるか確認すればよい。

http://(WebサーバのIPアドレス):8080

上記ではdocker service createコマンドで作成したが、ではdocker-compose.ymlファイルを使用して一斉にコンテナを起動することは可能か。もちろん可能だ。

docker-compose.ymlファイルを利用して起動する場合は、docker stack deployコマンドを使用すればよい。まずは、docker service createコマンドの内容を元にdocker-compose.ymlファイルを作成する。

version: '3'
services:
  wordpress:
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_PASSWORD: mysql
    deploy:
      placement:
        constraints:
          - node.role == worker

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: mysql
    deploy:
      placement:
        constraints:
          - node.role == manager

作成が完了したら、後は以下のコマンドを実行すればよい。

$ docker stack deploy wordpress --compose-file docker-compose.yml

これで複数のサーバでもDockerによる構成が可能となり、ひとつのDockerホストに対してのリスクを軽減することはできた。

では負荷を軽減するために、複数台のDockerホストで同じコンテナを起動する手軽な方法はあるのか。これについては次回の「Dockerコンテナをスケールアウトしてみよう」で説明する。

CloudGarage開発担当
IaaS型パブリッククラウドサービス「CloudGarage」の開発エンジニア。バックエンドのサーバ構築からフロントのアプリケーション開発まで幅広く行う。「Docker」は実務でも頻繁に利用するため、実際に使っている立場から「Docker」について解説をする。