204
160

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ECS CLIを使ってDocker Composeのファイルを使ってECSにデプロイする

Posted at

ECS CLIというECS専用のCLIツールが先日、発表されました(AWS CLIのECS対応という話ではなく、ElasticBeanstalk用のebコマンドがあるようなイメージと似ていると思います)

このツールの最大の利点としてはDockerComposeで作成したdocker-compose.ymlがECSでも使えるよ!という所だと思います。

自分はDockerComposeを使った事がなかったので、初めにDockerComposeの公式チュートリアルをローカルで試しつつ、その後、ECS-CLIを使ってローカルで作成したものをAWSのECSにデプロイしてみたのでメモ。

結論

  • ECS-CLIを使う事をで簡単にDockerComposeで作った環境をAWSにデプロイできる
  • コマンドはdocker-composeに似ているので覚えやすい
  • ECS-CLIでbuildディレクティブは現在使えないので、利用するイメージは予めビルドしておくこと
  • ECS-CLIがGoで書かれており、バイナリなのでインストールが楽
  • ECSでt2.microなど少ないスペックで実施する場合、複数コンテナ起動時にメモリ不足で起動できない場合があるので、その場合、mem_limitディレクティブなどで調整が必要
  • EC2を意識しないコンテナサービスが出て欲しい。。。。

参考

環境

  • MacOSX(10.10.5)
  • Docker 1.8.2
  • Docker Compose 1.4.0
  • ECS CLI v0.1.0

ローカル環境(Mac)でDocker Composeを試す

下記に沿ってやります。

Overview of Docker Compose

dockerやdocker composeをローカルマシンにインストールしていない場合、説明に従ってインストールしてください。

instalation and set-up

# version確認
$docker-compose --version
docker-compose version: 1.4.0
$mkdir composetest
$cd composetest

2つのファイルを作成します。Pythonのアプリケーション本体とアプリケーションの依存ライブラリの一覧

app.py
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)
requirements.txt
flask
redis

Create a Docker image

Dockerfileを作ります。

Dockerfile
FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD python app.py
  • DockerHubのpythonというイメージの2.7というタグがついたイメージを利用
  • app.pyとrequirments.txtをDockerイメージの/codeというパス配下に配置
  • ディレクトリを /code に移動
  • pip install -r requirements.txtコマンドを実行し、依存ライブラリをインストール
  • python app.pyというコマンドをコンテナ起動時に実行するように設定

Define services

docker-compose.ymlというファイルを作成し、複数のコンテナの定義及び起動時のオプションを設定します。

docker-compose.yml
web:
  build: .
  ports:
   - "5000:5000"
  volumes:
   - .:/code
  links:
   - redis
redis:
  image: redis
  • webとredisというコンテナを使います
  • redisコンテナはDockerHubからredisという名前のイメージを取得して利用します
  • webコンテナはカレントディレクトリのDockerfileをビルドし、そのイメージを利用します
  • Hostの5000ポートにアクセスした場合、コンテナの5000ポートにforwardするようにします
  • カレントディレクトリのファイル群をコンテナの/codeにマウントします。これによって以降、app.pyを変えた場合にコンテナの再ビルドを行う必要がなくなります
  • redisというコンテナとリンク接続します。これによってwebコンテナからredisコンテナにアクセスできるようにします。リンク設定をするとwebコンテナからはredisというホスト名でredisコンテナにアクセスできるようになり、接続ができます(/etc/hostsにredisホストの情報を追記している)

Build and run your app with Compose

いよいよdocker-composeを使ってみましょう!
イメージのダウンロードを行ってない場合、初回時に実行されるため、多少時間がかかりますが、ゆっくり待ちましょう!

$docker-compose up
....
redis_1 | 1:M 26 Oct 12:35:07.634 * The server is now ready to accept connections on port 6379
web_1   |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1   |  * Restarting with stat

これでコンテナが起動していますが、フォワグラウンドで起動し、操作できないのでCtrl+Cで一度停止させます。

次は-dオプションを利用して、起動し、バックグラウンドでコンテナを起動します。

# webとredisコンテナをバックグラウンドで起動
$docker-compose up -d

# docker-composeによって起動しているコンテナ群を確認
$docker-compose ps
      Name             Command             State              Ports
-------------------------------------------------------------------------
composetest_redi   /entrypoint.sh     Up                 6379/tcp
s_1                redis-server
composetest_web_   /bin/sh -c         Up                 0.0.0.0:5000->50
1                  python app.py

無事バックグラウンドで指定した2つのコンテナが起動しているのを確認できました。

起動したwebコンテナのアクセスはboot2dockerを使っていない場合、curl http://localhost:5000/とすることでできますが、自分の場合、Macでboot2docker(DockerMachine)を使っているのでそのIPを使ってアクセスします。

# docker-machineのIPアドレスを確認
$docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM
default   *        virtualbox   Running   tcp://192.168.99.100:2376

# アクセス。アクセスごとにカウントが増える
$curl http://192.168.99.100:5000/
Hello World! I have been seen 2 times.%

バックグラウンドで起動したコンテナは以下で停止させます。

$docker-compose stop

Amazon ECS CLI Tutorial

次にECS CLIを使ってみます。まずは先ほど作成したDockerComposeのファイルを使わず、公式でドキュメントのチュートリアルをそのまま実行してできる事を確認します。

以下、公式ドキュメントに沿ってやっています。

Using the Amazon ECS Command Line Interface

Installing the Amazon ECS CLI

MacとLinux用のGoで書かれたバイナリをあるようなのでそれを利用します。

# /usr/local/bin/ecs-cliにバイナリを配置
$sudo curl -o /usr/local/bin/ecs-cli https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-darwin-amd64-latest

# 実行権限を付与
$sudo chmod +x /usr/local/bin/ecs-cli

# 確認
$ecs-cli help

Configuring the Amazon ECS CLI

AWSの認証や利用するリージョン、クラスタ名をCLIに教えてあげる必要があります。
設定した内容は~.ecs/configとして保存されるようです

まず、AWS認証情報ですが以下のいずれかで設定が可能です。

  • 環境変数のAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEを指定
  • AWS CLIのaws configureコマンドなどによって ~/.aws/credentialsが存在し、認証情報が記載さている
  • ecs-cli configureコマンドで指定。 例:ecs-cli configure --region us-west-2 --access-key $AWS_ACCESS_KEY_ID --secret-key $AWS_SECRET_ACCESS_KEY --cluster ecs-cli-demo

自分の場合、既にAWS CLIを利用しており、~.aws/credentialsがあったのでリージョンとクラスタ名のみ指定します

# configureコマンドで設定
$ecs-cli configure --region ap-northeast-1 --cluster my-cluster

# 確認
$cat ~/.ecs/config
[ecs]
cluster = my-cluster
aws_profile =
region = ap-northeast-1
aws_access_key_id = xxxxx
aws_secret_access_key = xxxxxx

む、キー情報はこちらにも書かれるんですね。。。

Amazon ECS CLI Tutorial

ではチュートリアルをやってみます。

Step 1: Create your Cluster

AWS上でコンテナを起動させるためのAmazon EC2のクラスタを起動する必要が有ります。(正確にはECS AgentやDockerがインストールされたECS readyなEC2の起動)
上記クラスタを起動するためにecs-cli upコマンドを利用します。

$ecs-cli up --capability-iam --keypair HogeFugaKey

オプションでVPCやinstance type、解放するポートなど色々設定できますので詳細はhelpオプションで確認ください。

なお、起動したEC2を確認するとAMIはECS用の設定がされたAmazonLinuxのようでした。

Step 2: Create a Compose File

Docker-composeのファイルを作成します。
t2.mirocのEC2なので利用するメモリを各コンテナとも256MBとしています。

hello-world.yml
wordpress:
  image: wordpress
  mem_limit: 268435456
  ports:
    - "80:80"
  links:
    - mysql
mysql:
  image: mysql
  mem_limit: 268435456
  environment:
    MYSQL_ROOT_PASSWORD: password

なお現在、すべてのdocker-composeで指定できるディレクテイブが使えるわけではない点が注意点です。
利用できるのは以下のディレクティブでbuildディレクティブが使えないのでimageは必ず一旦DockerHubなどに置く必要がある点が注意点です。

  • command
  • cpu_shares
  • entry point
  • environment
  • image
  • links
  • mem_limit (in bytes)
  • ports
  • volumes
  • volumes_from

Step 3: Deploy the Compose File to a Cluster

さあ、 ecs-cli compose upコマンドを利用して、作成したcomposeファイルのコンテナをクラスタにデプロイしてみます。

デフォルトでカレントディレクトリのdocker-compose.ymlファイルを探しますが、--fileオプションでファイル名を指定することが可能です。

# composeに記載されたコンテナの起動
$ecs-cli compose --file hello-world.yml up

Step 4: View the Running Containers on a Cluster

psコマンドで起動しているコンテナを確認してみます。

# 起動しているコンテナの確認
$ecs-cli ps
Name                                            State                                                                               Ports                     TaskDefinition
d2d44fd7-5d14-4510-92ee-3a385d28ac61/wordpress  RUNNING                                                                             54.64.183.253:80->80/tcp  ecscompose-tmp:4
d2d44fd7-5d14-4510-92ee-3a385d28ac61/mysql      RUNNING                                                                                                       ecscompose-tmp:4

ブラウザでコンテナのIPアドレス(上記では54.64.183.253)にアクセスするとWordPressの画面が表示されました。

Step 5: Scale the Tasks on a Cluster

スケールさせるぞ!と思ったらメモリを足りず失敗。。。

$ecs-cli compose --file hello-world.yml scale 2
INFO[0000] Couldn't run containers                       reason=RESOURCE:MEMORY

なのでecs-cli scaleコマンドでクラスタとなっているEC2の数を1つから2に増やします。

$ecs-cli scale --capability-iam --size 2
INFO[0001] Waiting for your cluster resources to be updated
INFO[0001] Cloudformation stack status                   stackStatus=UPDATE_IN_PROGRESS

なるほど。CloudFormationのupdate stackをしているのか。

完了後、再度やってみます。

# 起動
$ecs-cli compose --file hello-world.yml scale 2

# 確認.コンテナが2つから4つになっている
$ecs-cli ps

同じようにIPアドレスにアクセスするとWordPressの画面が確認できました。

Step 6: Create an ECS Service from a Compose File

今まで実行したコンテナはECSでいうタスクというバッチなどに適した実行だったので、次にserviceというWeb/APIに適したものとして実行します。

# 現在利用しているrun taskを停止
$ecs-cli compose --file hello-world.yml down

# 停止を確認
$ecs-cli ps

# serviceとしてコンテナを起動
$ecs-cli compose --file hello-world.yml service up

# serviceとしての起動を確認
$ecs-cli compose --file hello-world.yml service ps

Step 7: Clean Up

最後に環境を削除します。
先ほど作成したserviceを削除し、クラスタインスタンスを削除します。

# serviceの削除
$ecs-cli compose --file hello-world.yml service rm

# クラスタの削除
$ecs-cli down --force

DockerComposeチュートリアルで試したものを適用してみる

最初の項でローカル環境で試したdocker-composeのファイルをECSに適用してみましょう。ただし、ECS CLIで利用できるcomposeファイルではbuildディレクティブが現在使えないのでローカルでイメージのビルドとDockerhubへのpushを行っておくことが必要な点を注意しておきます。

DockerfileのビルドとDockerHubへのpush

最初に作成したwebコンテナをDockerHubへpushします。
DockerHubへのアカウントがない場合、事前に取得しておいてください。

cd ~/composetest

# Dockerfileのビルド。-tオプションで{username}/compose-testというリポジトリを設定。usernameはDockerHubのユーザー名
$docker build -t toshihirock/compose-test .

# DockerHubへのログイン
$docker login

# DockerHubへイメージのpush
$docker push toshihirock/compose-test

DockerComposeのファイル変更

少し変更します。

  • webコンテナのイメージをDockerHubにpushしたものに変更
  • フォワードするポートを変更
  • メモリを設定(t2.microインスタンスのため)
docker-compose.yml
web:
  image: toshihirock/compose-test
  ports:
   - "80:5000"
  mem_limit: 268435456
  links:
   - redis
redis:
  image: redis
  mem_limit: 268435456

また、上記設定でも今まで同様にローカル環境でdocker-composeコマンドで起動できる事を確認します。

ECS-CLIによる起動

では、先ほどチュートリアルでやった際と同じ要領でやってみます。

# クラスタの起動
$ecs-cli up --capability-iam --keypair HogeFugaKey

# docker-compose.ymlを利用してserviceの起動
$ecs-cli compose service up

# 確認
$ ecs-cli compose service ps
Name                                        State    Ports                      TaskDefinition
e63f0788-2adb-49cb-a9f8-601758f8890a/redis  RUNNING                             ecscompose-composetest:3
e63f0788-2adb-49cb-a9f8-601758f8890a/web    RUNNING  52.68.36.117:80->5000/tcp  ecscompose-composetest:3 

$curl http://52.68.36.117/
Hello World! I have been seen 2 times.

出来ました!
ローカルで作成した環境を簡単にAWSに移行できるのは良いですね!

掃除

綺麗にします

# serviceの削除
$ecs-cli compose service rm

# クラスタの削除
$ecs-cli down --force

お疲れ様でした!

204
160
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
204
160

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?