
EC2 + Docker Machine + Swarm + Composeでコンテナオーケストレーションする
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
今回はDocker Machine、Docker Swarm、Docker Composeの3つを使って、Amazon EC2でDockerコンテナをオーケストレーションしてみます!
やってみた
Swarmクラスタを作成する
まずは前回と同様に、Docker MachineでSwarmクラスタを作成します。
なおswarm createではdiscovery-stage.hub.docker.comにリクエストしてクラスタIDを取得しているのですが、タイミングによってはエラーが出る事がありました。現在はベータリリースという扱いなので仕方がないかと思いますが、ちょっと注意が必要です。
$ sudo docker run --rm swarm create 4e8ebb66a08f838fe05a36c20341f044 $ sudo ./docker-machine create --driver amazonec2 --amazonec2-access-key YOUR_ACCESS_KEY --amazonec2-secret-key YOUR_SECRET_KEY --amazonec2-region ap-northeast-1 --amazonec2-ami ami-a1bf56a1 --amazonec2-vpc-id YOUR_VPC_ID--swarm --swarm-master --swarm-discovery token://4e8ebb66a08f838fe05a36c20341f044 master $ sudo ./docker-machine create --driver amazonec2 --amazonec2-access-key YOUR_ACCESS_KEY --amazonec2-secret-key YOUR_SECRET_KEY--amazonec2-region ap-northeast-1 --amazonec2-ami ami-a1bf56a1 --amazonec2-vpc-id YOUR_VPC_ID--swarm --swarm-discovery token://4e8ebb66a08f838fe05a36c20341f044 node1 $ sudo ./docker-machine create --driver amazonec2 --amazonec2-access-key YOUR_ACCESS_KEY --amazonec2-secret-key YOUR_SECRET_KEY --amazonec2-region ap-northeast-1 --amazonec2-ami ami-a1bf56a1 --amazonec2-vpc-id YOUR_VPC_ID--swarm --swarm-discovery token://4e8ebb66a08f838fe05a36c20341f044 node2
作成されたSwarmクラスタはこんな感じ。EC2インスタンスが3台追加されているはずです。
$ sudo ./docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM master amazonec2 Running tcp://54.178.132.195:2376 master (master) node1 amazonec2 Running tcp://54.92.24.244:2376 master node2 * amazonec2 Running tcp://54.178.180.56:2376 master
Docker Composeをインストールする
Docker Composeはバイナリをダウンロードしてくるだけです。
$ curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > docker-compose $ sudo mv ./docker-compose /usr/local/bin $ sudo chmod +x /usr/local/bin/docker-compose $ docker-compose --version docker-compose 1.1.0
オーケストレーションするDockerコンテナイメージを作成する
今回はWebサーバとMemcachedサーバを構築し、Memcachedにカウンター値を格納して、Webサーバにアクセスするたびにカウントアップする、という仕組みを作ります。このためWebアプリケーションを搭載したWebサーバ用のDockerイメージを作成します。
compose/web/scriptsというディレクトリを作り、その中にWebアプリケーションとなるRubyスクリプトを作成します。
$ mkdir ~/compose/web/scripts $ vi ~/compose/web/scripts/app.rb
スクリプトの内容はこんな感じ。SinatraでWebサーバとして動作し、DalliによってMemcachedを操作します。Memcachedサーバは固定値を使っています(後述にて説明します)
require 'sinatra'
require 'dalli'
set :environment, :production
dc = Dalli::Client.new('54.178.132.195:11211')
value = Array.new
get '/' do
if dc.get("count") == nil then
dc.set("count", 1)
end
value = dc.get("count")
dc.set("count", value + 1)
"count is " + value.to_s
end
Webサーバ用DockerイメージのDockerfileでは、Docker Language Stackのrubyを使い、gemでSinatraとDalliを追加し、上述のrubyスクリプトを組み込んで起動しています。またSinatraのデフォルトポートである4567をEXPOSEしています。
$ vi ~/compose/web/Dockerfile FROM ruby:latest RUN gem install sinatra RUN gem install dalli ADD scripts/app.rb /usr/local/bin/app.rb CMD ["ruby","/usr/local/bin/app.rb"] EXPOSE 4567
このDockerfileをbuildし、Docker Hubに登録しておきます。
$ sudo docker build -t smokeymonkey/app . $ sudo docker login $ sudo docker push smokeymonkey/app:latest
Docker Composeの定義ファイルを作成する
Docker Domposeはdocker-compose.ymlファイルに定義を記述します。今回はwebコンテナとmemcachedコンテナを定義しており、Webコンテナでは前述で作成したWebサーバ用Dockerイメージを指定しています。
$ cd ~/compose/
$ vi docker-compose.yml
web:
image: smokeymonkey/app:latest
ports:
- 4567
memcached:
image: memcached
ports:
- 11211:11211
environment:
- constraint:node==master
memcachedコンテナはconstraint:node行によって必ずmasterノードで起動するように定義しています。これが上述のRubyスクリプトでMemcachedサーバのIPアドレスを固定値として埋め込んでいた理由です。
また、この仕組みでは11211/tcpとコンテナの4567/tcpポートがバインドされるランダムなホスト側ポートを使いますので、セキュリティグループで許可してください。
コンテナオーケストレーションする
さて本題。まず、Swarmクラスタを操作するために、環境変数を定義します。
$ $(sudo ./docker-machine env --swarm master)
次にComposeを操作するための環境変数の定義です。環境変数DOCKER_CLIENT_TIMEOUTはデフォルトでは60秒なのですが、大きなサイズのコンテナイメージを使う場合すぐにタイムアウトしてしまうので、大きく取っておきます。
$ export DOCKER_CLIENT_TIMEOUT=600
では起動!
$ sudo -E /usr/local/bin/docker-compose up -d
Creating compose_web_1...
Creating compose_memcached_1...
$ sudo -E /usr/local/bin/docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------
compose_memcached_1 memcached Up 54.178.132.195:11211->11211/tcp
compose_web_1 ruby /usr/local/bin/app.rb Up 54.92.24.244:49153->4567/tcp
memcachedコンテナとweb_1コンテナが起動しました。試しにweb_1コンテナにアクセスしてみます。
$ curl 54.92.24.244:49153 count is 1
ちゃんとカウントが取れてますね。
コンテナをスケールアップさせる
それではオーケストレーションのキモ、コンテナをスケールさせてみます。
$ sudo -E /usr/local/bin/docker-compose scale web=5 Creating compose_web_2... Creating compose_web_3... Creating compose_web_4... Creating compose_web_5... Starting compose_web_2... Starting compose_web_3... Starting compose_web_4... Starting compose_web_5...
一気に4つのコンテナが増えました。確認してみます。
$ sudo -E /usr/local/bin/docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------
compose_memcached_1 memcached Up 54.178.132.195:11211->11211/tcp
compose_web_1 ruby /usr/local/bin/app.rb Up 54.92.24.244:49153->4567/tcp
compose_web_2 ruby /usr/local/bin/app.rb Up 54.178.132.195:49155->4567/tcp
compose_web_3 ruby /usr/local/bin/app.rb Up 54.178.180.56:49154->4567/tcp
compose_web_4 ruby /usr/local/bin/app.rb Up 54.92.24.244:49156->4567/tcp
compose_web_5 ruby /usr/local/bin/app.rb Up 54.92.24.244:49157->4567/tcp
Swarmノードに分散されて、Webコンテナが5つに増えています!
カウンタの動作を確認してみます。
$ curl 54.178.132.195:49155 count is 2 $ curl 54.178.180.56:49154 count is 3 $ curl 54.92.24.244:49156 count is 4 $ curl 54.92.24.244:49157 count is 5
問題なく、どのWebサーバにアクセスしても、カウントがアップされていますね!
コンテナをスケールダウンさせる
スケールダウンもコマンド一発でできます。
$ sudo -E /usr/local/bin/docker-compose scale web=1
Stopping compose_web_5...
Stopping compose_web_4...
Stopping compose_web_3...
Stopping compose_web_2...
Removing compose_web_5...
Removing compose_web_4...
Removing compose_web_3...
Removing compose_web_2...
$ sudo -E /usr/local/bin/docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------
compose_memcached_1 memcached Up 54.178.132.195:11211->11211/tcp
compose_web_1 ruby /usr/local/bin/app.rb Up 54.92.24.244:49153->4567/tcp
簡単!
さいごに
まだまだベータリリースなので少々動作に気になる点はありますが(特にAPIサーバ側)、かなり楽に展開できました。こうなると今後のECSの展開が気になるところですねー。正式リリースが楽しみです。






