Dockerで複数のコンテナーを動かそう

Tuyoshi Akiyama
8 min readSep 4, 2017

--

前回の記事の続きです。今回は、swarm(群れという意味)について見ていき、複数のコンテナーとマシン上で、一つのアプリを動作させます。

swarmとはswarm managerによって実行される、複数のマシン(物理的、仮想的な)をDockerを使って、一つのクラスターに合わさります。この群れ(swarm)に参加すると、ノードと呼ばれます。

swarm managerは、前回のcomposeファイルでサービスを定義したように、コンテナーの動きを定義していきます。swarm modeで動いているマシンのみがDockerに指示を行うことができます。

swarm managerを現在のマシンで起動するには、 docker swarm init でswarm modeを有効にします。また、他のマシンがnode(ノード)としてそのswarmに参加するには、 docker swarm join を行います。

今回はVM(Virtual Machine)を2つ立ち上げて、上のswarm処理の動きを見ていきます。まずは、それぞれのOSに合わせた、VMをインストールします。

以下、swarmの一連の処理になります。

// 2つのVMをdocker-machineを使って立ち上げます。
$ docker-machine create --driver virtualbox myvm1
// [...]
$ docker-machine create --driver virtualbox myvm2
// [...]
//2つのVMが作られ、また、走っていることを確認
$ docker-machine ls
//上の一目のVM、myvm1をswarm managerとする。ssh接続でmyvm1に、docker swarm initをつかうように指示する
$ docker-machine ssh myvm1 "docker swarm init"
//ここでエラーが出たら、swarm initに続けて、docker-machine lsで表示されるmyvm1のipアドレスを指定して、もう一度接続
$ docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100:2376"
Swarm initialized: current node (ol1v6vwz7bmf50a3waxli1csk) is now a manager.// [...]
// ここで他のマシンがnodeとして、上のmyvm1のswarmに参加するコマンドが出力されますdocker swarm join --token SWMTKN-1-4tm9p39m2h1a0o48jy8evthtulodhsonpc9qstbt73pxrkc7h1-8vc4v762b3tmzhr3b9t22pah8 192.168.99.100:2376
// 上の表示されたコマンドを""内で置き換えて、二つ目のVM、myvm2に接続します/*$ docker-machine ssh myvm2 "docker swarm join \
--token SWMTKN-1-4tm9p39m2h1a0o48jy8evthtulodhsonpc9qstbt73pxrkc7h1-8vc4v762b3tmzhr3b9t22pah8 \
<ip>:<port>"*/
$ docker-machine ssh myvm2 "docker swarm join --token SWMTKN-1-4tm9p39m2h1a0o48jy8evthtulodhsonpc9qstbt73pxrkc7h1-8vc4v762b3tmzhr3b9t22pah8 192.168.99.100:2376"

ここで、myvm2でswarmに参加しようと、最後のコマンドがエラーが出力される。

swarm に参加するには、portを2376ではなく、2377で接続する必要があるのに注意します。

ここまで、swarmが作られる過程になります。次のコマンドで、このswam内のnodeを確認します。

docker-machine ssh myvm1 "docker node ls"ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUSol1v6vwz7bmf50a3waxli1csk *   myvm1               Ready               Active              Leadermlzinuu7x7ux0ypk12k8dmk7p     myvm2               Ready               Active

2つのnodeが確認できたら、OKです。

後は、composeファイルをswarm managerにコピーして、swarm managerはそのファイルを使ってアプリをデプロイします。

$ ls
Dockerfile docker-compose.yml
app.py requirements.txt
// swam managerであるmyvm1にcomponseファイルをコピーします。
$ docker-machine scp docker-compose.yml myvm1:~
docker-compose.yml
// myvm1にssh接続して、アプリを上のcomposeファイルを基にデプロイすると指示します。
$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
Creating network getstartedlab_webnet
Creating service getstartedlab_web
// 3つのコンテナーが、2つのnode(myvm1, myvm2)に配分されていることが、確認できます。
$ docker-machine ssh myvm1 "docker stack ps getstartedlab"
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
hwrjlivijorp getstartedlab_web.1 akitsuyoshi/get-started:part1 myvm2 Running Preparing 10 seconds agoldb6yp2w09zb getstartedlab_web.2 akitsuyoshi/get-started:part1 myvm1 Running Preparing 10 seconds ago0dglesb0vxs2 getstartedlab_web.3 akitsuyoshi/get-started:part1 myvm1 Running Preparing 10 seconds ago

また前回同様、アプリの拡張には、composeファイルを書き換えます。例えば、コンテナーのインスタンス数の増減等はcomposeファイルで管理します。

変化したら、再度、デプロイのコマンドです。(今動いているコンテナーを止める必要はない、でしたね)。

$ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"

また docker-machine ls から、2つのVM、myvm1, 2のIPアドレスを調べることができます。

$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - virtualbox Running tcp://192.168.99.100:2376 v17.07.0-cemyvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.07.0-ce

このIPアドレス(両方のVMともに)をブラウザから見た時に、コンテナーIDがランダムに(負荷分散によって)表示されるのが確認できます。

これは、3つのnodeがポート8080で公開しているmy-webのサービスの表示になります。どのnodeがコンテナーを実行しても、特定のポートでデプロイされたサービスが、その特定のポートとサービス自体を結びつけます。

以上がswam機能になります。前回のserviceの内容に加えて、複数のマシンが関わってくる時に必要な機能みたいですね。

次は、stackについて見ていきたいと思います。

--

--