Instantly share code, notes, and snippets.

@koudaiii /article.md Secret
Last active Aug 29, 2015

Embed
What would you like to do?
docker-compose.yml からwerckerで Amazon ECS でコンテナを起動する

docker-compose.yml からwerckerで Amazon ECS でコンテナを起動する

先日、AWS New Service Meet upに参加してきた。

※ まとめ資料

AWS ECSのサービスを聴きながら、
手元で利用しているdocker-composeをそのまま本番に反映されたら、
手元の開発環境とQAまたはstaging用環境と本番環境との差異がほとんどなくなってすごいいいんじゃないかなぁと思って以下のツイートをしました。

docker-compose.ymlで書いた構成がECSでインスタンスを超えてスケーリングしていく未来にならないかなぁー。

— 坂部広大 (@koudaiii) April 22, 2015
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

こっそりdocker-compose.ymlを AWS ECS 用のjson形式に変換してくれるcontainer-transformを教えてくれました! 早速試してみた。

※ container-transformはAWSサポート対象外

pip install で以下のモジュールをインストール

事前準備

docker-compose.ymlを用意。

$ cat docker-compose.yml

base:
  image: ubuntu 
  cpu_shares: 512
  mem_limit: 536870912b
  command: echo "hellow world!"
  • 試しにjson形式に変換してみる
$ cat docker-compose.yml | container-transform 
[
    {
        "memory": 512,
        "cpu": 512,
        "image": "ubuntu",
        "command": [
            "echo",
            "\"hellow",
            "world!\""
        ],
        "essential": true,
        "name": "base"
    }
]

このように、json形式に変換してくれる。

  • 上のjson形式をtask-definitionに登録。
  • AWS ECS は、実行するDockerコンテナをタスクというグループ単位で管理している。
  • register-task-definitionはそのタスクを登録する。
$ aws ecs register-task-definition --family your_task_definition --container-definitions "$(cat docker-compose.yml | container-transform)"
  • register-task-definition で登録したタスクを実行するにはrun-taskを使う。--countを使うとdocker-composeのscaleみたいなことが出来る。
  • インスタンスのリソースが足りない場合は、起動できないって文言がjsonで返ってくる。
$ aws ecs run-task --cluster your_cluster_name --task-definition your_task_definition_name
  • AWS ECSのCLIはこちら
  • または$ aws ecs helpで確認できる

werckerからECSのコンテナを起動

【画面キャプチャ:werckerのロゴ】

上のコマンドを覚えて叩くのが大変なので、wercker のboxとstepを作った。 作ったものはサポート対象外のもの利用しているためproductionには利用できないけど(そもそもdocker-composeが非推奨)、 git push やGithub上でリポジトリを更新した際にAWS ECSにコンテナが展開させることが出来る。

  • 処理のフロー図

【画面キャプチャ:処理のフロー】

ユースケースとして、 このstepとboxを使って、コンテナdeployやコンテナによる並列でのCIみたいなことが出来そうだけど実際そこまでは試していない。

以下は簡単な設定例。

Deploy設定例(wercker step)

上記の事前準備とdocker-compose.ymlに合わせて、

  • 以下のwercker.ymlを用意

  • werckerのdeploy piplineで値($AWS~~~と書かれている部分)を設定

  • sampleで作成したもの

  • 例:wercker.yml

box: wercker/python
build:
  steps:
    - script:
        name: Hello World
        code: echo "Hello World"
deploy:
  steps:
    - koudaiii/install-container-transform:
        key: $AWS_KEY
        secret: $AWS_SECRET
        region: $AWS_REGION
        cluster: $AWS_ECS_CLUSTER
        definition: $AWS_ECS_DEFINITION
        count: $AWS_ECS_COUNT
  • werckerのDeploy piplineの設定箇所

【画面キャプチャ:deploy piplineの設定】

CI用の設定例(wercker box)

上記の事前準備とdocker-compose.ymlに合わせて、

  • 以下のwercker.ymlを用意

  • werckerのpipline(上のDeployの設定とは違う場所)で値($WERCKER~~~と書かれている部分)を設定

  • sampleで作成したもの

  • 例:wercker.yml

box: koudaiii/install-container-transform
build:
  steps:
    - script:
        name: Configuring based on parameters..
        code: |
          aws configure set aws_access_key_id $WERCKER_INSTALL_CONTAINER_TRANSFORM_KEY
          aws configure set aws_secret_access_key $WERCKER_INSTALL_CONTAINER_TRANSFORM_SECRET
          aws configure set default.region $WERCKER_INSTALL_CONTAINER_TRANSFORM_REGION
    - script:
        name: register task definition
        code: |
          aws ecs register-task-definition --family wercker --container-definitions "$(cat docker-compose.yml | container-transform)"
    - script:
        name: create run task
        code: |
          aws ecs run-task --cluster $WERCKER_INSTALL_CONTAINER_TRANSFORM_CLUSTER --task-definition wercker
    - script:
        name: Done.
  • werckerのpiplineの設定箇所

【画面キャプチャ:piplineの設定】

ここまで、書いて一旦終了。

まとめ

CI側について

これをそのままcommandをrspecコマンドに書き変えると、jsonが返っくるだけで、必ずテストがgreenになる世の中になりそうな。。。 また、CIを一気に回しまくるとrun-taskを実行の際にインスタンスのリソースが一杯一杯でコンテナの起動できないなどの事象が発生するため、もう一工夫が必要。

Deploy側について

コンテナ起動だけじゃなくて最終的に以下の内容も含めてwercker-stepで実装したらblue-green deploymentに近いことが出来るし、Dockerのホスト側を面倒を減らすことが出来るのでは?と妄想しています。

  • 新規にインスタンスの起動(リソース確保のため)
  • taskのUpdateで切替

出来上がりのイメージ図です。

※ 実際にawscliからイメージ図の作業が出来るかは不明><!

現時点の課題

docker-compose.ymlで書いた構成がECSでインスタンスを超えてスケーリングしていく未来にならないかなぁー。

最初に書いたこのツイートについて、 いろいろ触ってみて現時点では、以下の点からまだまだ解決すべきものがいっぱいありそう。

  • AWS ECSがdocker-composeをサポートしていない点
  • container-transformがAWSでサポートしていない点
  • docker-compose自体がそもそもproductionの利用を推奨(以下サイト抜粋)していない点

Docker Compose Overview Compose is a tool for defining and running complex applications with Docker. With Compose, you define a multi-container application in a single file, then spin your application up in a single command which does everything that needs to be done to get it running.

Compose is great for development environments, staging servers, and CI. We don't recommend that you use it in production yet.

上の課題が今後何らかの方法で解決されていけば、 docker-composeでアプリの構成を管理しつつ、 local - development - QA/Staging - production 間の環境差異がさらになくなり、 それ以外に、コンテナならではの以下のようなことも出来る。

  • CI系のサービスでテストが増えて重たくなってしまっている場合に、コンテナで並列処理
  • エンジニアじゃない方(local上に環境を作って確認するのが難しい方)でちょっと文言とかCSSを変更したい場合に、直接Github上で編集してCommitしたらコンテナが起動してWeb上で確認

今後、どのようなUpdateが入るか楽しみです!!

$ cat docker-compose.yml | container-transform
[
{
"memory": 512,
"cpu": 512,
"image": "ubuntu",
"command": [
"echo",
"\"hellow",
"world!\""
],
"essential": true,
"name": "base"
}
]
box: koudaiii/install-container-transform
build:
steps:
- script:
name: Configuring based on parameters..
code: |
aws configure set aws_access_key_id $WERCKER_INSTALL_CONTAINER_TRANSFORM_KEY
aws configure set aws_secret_access_key $WERCKER_INSTALL_CONTAINER_TRANSFORM_SECRET
aws configure set default.region $WERCKER_INSTALL_CONTAINER_TRANSFORM_REGION
- script:
name: register task definition
code: |
aws ecs register-task-definition --family wercker --container-definitions "$(cat docker-compose.yml | container-transform)"
- script:
name: create run task
code: |
aws ecs run-task --cluster $WERCKER_INSTALL_CONTAINER_TRANSFORM_CLUSTER --task-definition wercker
- script:
name: Done.
base:
image: ubuntu
cpu_shares: 512
mem_limit: 536870912b
command: echo "hellow world!"
$ aws ecs register-task-definition --family your_task_definition --container-definitions "$(cat docker-compose.yml | container-transform)"
$ aws ecs run-task --cluster your_cluster_name --task-definition your_task_definition_name
box: wercker/python
build:
steps:
- script:
name: Hello World
code: echo "Hello World"
deploy:
steps:
- koudaiii/install-container-transform:
key: $AWS_KEY
secret: $AWS_SECRET
region: $AWS_REGION
cluster: $AWS_ECS_CLUSTER
definition: $AWS_ECS_DEFINITION
count: $AWS_ECS_COUNT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment