26
25

More than 5 years have passed since last update.

CLIでECS(EC2 Container Serviceを)を試す

Last updated at Posted at 2015-06-23

Amazon EC2 Container Service(ECS)をGUIから試してAWS側で用意したサンプルWebアプリを動かしたときのメモ

GUIからECSを実行することが出来たので、次にCLIを使ってやってみます。nginxが動作するコンテナを作成し、アクセスしてみます。

前提

  • AWS CLIが使えること
  • Docker実行環境が存在すること
  • DockerHubのアカウントが存在すること

参考

というかほとんど上記をCLIをメインで再度やってみた形になります。

Dockerコンテナの作成

Amazon EC2 Container Service(ECS)で静的Webサイトをデプロイする

上記リンクの通り、Dockerfileを作成します。

$ mkdir nginx
$ cd nginx
$ vi Dockerfile
FROM nginx
COPY html /usr/share/nginx/html

また、コピーするHTMLも作成します。

$ mkdir html
$ vi html/index.html
<html>
<head><title>Amazon ECS deployed!</title></head>
<body><h1>Amazon ECS deployed!</h1></body>
</html>

docker buildコマンドを利用してビルドし、コンテナ化します。toshihirockの部分はDockerhubのアカウント名に置き換えてください。

$docker build -t toshihirock/mynginx .

試しにローカルで起動してみます

$docker run -d -p 80:80 toshihirock/mynginx
1eff877751a7
$curl http://localhost
<html>
<head><title>Amazon ECS deployed!</title></head>
<body><h1>Amazon ECS deployed!</h1></body>
</html>

docker inspectを使う設定内容が確認できます。Cmdに以下が設定されるのが確認でき、 deamon off(つまりフォアグラウンド)で実行される事が分かります。(コマンドをフォアグランドで動作させないとコンテナが終了するので)

        "Cmd": [
            "nginx",
            "-g",
            "daemon off;"
        ],

Dockerhubへの登録

確認ができたらDockerhubにコンテナを登録します。

まず、Dockerhubにログインします。

$docker login

次にdocker pushでDockerhubにコンテナを登録します。

$docker push toshihirock/mynginx

ECS用のIAMロールの作成

コンテナを実行するEC2からECSにアクセスを行うために必要なIAMロールの作成を行います。

作成時に以下のサイトが参考になりました。

AWS CLIでサービスの各種コマンドを動かしてみる(IAM編3: ロール)

最初にロールを作成するためのファイルを作成します。

role.json
{
  "Version": "2012-10-17",
  "Statement": [
     {
       "Action": "sts:AssumeRole",
       "Principal": {
         "Service": "ec2.amazonaws.com"
        },
        "Effect": "Allow",
        "Sid": ""
     }
  ]
}

作成後、以下の操作でロールを作成します。

# 作成
$aws iam create-role --role-name ecs-full-access --assume-role-policy-document file://role.json

#確認
$aws iam get-role --role-name ecs-full-access

次にECSへアクセスするポリシーの作成をします。

role-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "ecs:*",
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

先ほど作成したロールに適用します。

$aws iam put-role-policy --role-name ecs-full-access --policy-name  ECSFullAccess --policy-document file://role-policy.json

確認します。

$ aws iam list-role-policies --role-name ecs-full-access
{
    "PolicyNames": [
        "ECSFullAccess"
    ]
}

先ほどのポリシーが作成したロールに適用されているのが確認できました。

EC2のIAMロールとして利用するためにインスタンスプロファイルを作成します。

$aws iam create-instance-profile --instance-profile-name ecs-full-access

作成したプロファイルをロールに適用させます。

$aws iam add-role-to-instance-profile --instance-profile-name ecs-full-access --role-name ecs-full-access

クラスタの作成

コンテナを動作させるEC2群まとめるクラスタを作成します

$aws ecs create-cluster --cluster-name MyCluster

クラスタの作成を確認します

$aws ecs describe-clusters --clusters MyCluster

ECS-Optimized Amazon Linuxの起動とクラスタへの参加

Launching an Amazon ECS Container Instance

CoreOSも使えるようですが、最新のAmazonLinuxのECS readyなAMIを使います。20150623現在、ap-northeast1で使える最新のものはami-fa12b7faだったのでこれを使って起動します。

また、先ほど作ったクラスタに参加するために起動するEC2のUserDataで以下を設定するようにします。

#!/bin/bash
echo ECS_CLUSTER=MyCluster >> /etc/ecs/ecs.config

CLIから操作する場合、UserDataはBase64エンコードしたものを設定するようにします。
--subnet-id--security-group-ids--key-nameについては適宜自分の環境にあったものを設定して下さい。また、セキュリティグループについては80ポートを開放したものを設定してください。

$aws ec2 run-instances \
--image-id  ami-fa12b7fa \
--instance-type t2.micro \
--subnet-id subnet-d949e1ae \
--iam-instance-profile Name=ecs-full-access \
--user-data IyEvYmluL2Jhc2gNCmVjaG8gRUNTX0NMVVNURVI9TXlDbHVzdGVyID4+IC9ldGMvZWNzL2Vjcy5jb25maWc= \
--security-group-ids sg-baca56df \
--key-name hogeFugaKey \
|jq -r '.Instances[].InstanceId'

上記実行により、インスタンスIDのみ出力するようにjqでフィルタしています。
あとで利用するのでメモしておいて下さい。

少し時間を置いてからクラスタに先ほどのインスタンスが参加しているか確認します。

$aws ecs list-container-instances --cluster MyCluster
{
    "containerInstanceArns": [
        "arn:aws:ecs:ap-northeast-1:694273932022:container-instance/b16efbb0-c12f-4f74-bd2f-aa7756a5cc2d"
    ]
}

上記のようにcontainerInstanceArnsに一つ値が入っていればOKです。

タスクの追加

タスク(実行するコンテナの詳細をまとめたもの)を追加します。指定するファイルでの詳細なパラメーターはこちらを参照のこと。

今回の例では最初に作成したnginxのコンテナを利用するタスクを設定し、コンテナとホストでは80ポートのマッピングをしています。cpu、memoryはコンテナのスペックを表し、essentialをtrueにするとこのコンテナの実行が失敗するとタスクとして失敗したものとしてみなしてくれます。

nginx-task.json
[
  {
    "image": "toshihirock/mynginx",
    "name": "mynginx",
    "cpu": 10,
    "memory": 500,
    "essential": true,
    "environment": [],
    "portMappings": [
      {
        "containerPort": 80,
        "hostPort": 80
      }
    ]
  }
]

タスクを登録します。

$ aws ecs register-task-definition --family mynginx  --container-definitions file://nginx-task.json

タスクが登録されたことを確認します。

$aws ecs describe-task-definition --task-definition mynginx

上記ではタスクを登録しただけで、クラスタとの関連づけはされていません。先ほど登録したクラスタで上記タスクを実行させたいので登録を行います。
下記コマンドの--task-definitionパラメーターではfamily:revisionという形式で指定します。今回のタスクのリビジョンは1なのでmynginx:1という指定を行います。

$aws ecs run-task --cluster MyCluster --task-definition mynginx:1
{
    "failures": [],
    "tasks": [
        {
            "taskArn": "arn:aws:ecs:ap-northeast-1:694273932022:task/bf71c7b8-6fd0-40e5-b106-a14e588a3b04",
            "overrides": {
                "containerOverrides": [
                    {
                        "name": "mynginx"
                    }
                ]
            },
            "lastStatus": "PENDING",
            "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:694273932022:container-instance/f053e789-7aaf-4be7-a90c-2f868b2802f0",
            "clusterArn": "arn:aws:ecs:ap-northeast-1:694273932022:cluster/MyCluster",
            "desiredStatus": "RUNNING",
            "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:694273932022:task-definition/mynginx3:1",
            "containers": [
                {
                    "containerArn": "arn:aws:ecs:ap-northeast-1:694273932022:container/18de6ec3-66b6-4b72-91a1-044c03ad60ba",
                    "taskArn": "arn:aws:ecs:ap-northeast-1:694273932022:task/bf71c7b8-6fd0-40e5-b106-a14e588a3b04",
                    "lastStatus": "PENDING",
                    "name": "mynginx"
                }
            ]
        }
    ]
}

登録直後はlastStatusがPENDDINGとなっており、コンテナが起動しておりません。少し時間をおいてから登録されたタスクの状態を確認します。--tasksパラメーターには先ほどタスクを登録した時に表示されたタスクのARN(taskArn)を指定します。

$aws ecs describe-tasks --cluster MyCluster --tasks arn:aws:ecs:ap-northeast-1:694273932022:task/bf71c7b8-6fd0-40e5-b106-a14e588a3b04

lastStatusを確認し、PENDDINGがRUNNINGになっていればコンテナが起動し、準備が完了していることになります。

Webサイトにアクセスする

インスタンス登録時に表示したインスタンスIDを利用してEC2のPublicDNS名を取得します。

$aws ec2 describe-instances --instance-ids i-6004f292 |jq -r '.Reservations[].Instances[].PublicDnsName'

上記URLにアクセスするとnginxが起動しているコンテナにアクセスし、以下の内容が確認できるかと思います。

Screen Shot 2015-06-24 at 8.38.06 AM.png

お掃除

まず、クラスタに登録したタスクを停止します。

$aws ecs stop-task --cluster MyCluster --task arn:aws:ecs:ap-northeast-1:694273932022:task/bf71c7b8-6fd0-40e5-b106-a14e588a3b04

次にECSを動作させているEC2をterminateします。

$aws ec2 terminate-instances --instance-ids i-6004f292

最後にクラスタを削除します。

# 削除
$aws ecs delete-cluster --cluster MyCluster

# 確認
$ aws ecs describe-clusters --clusters MyCluster
{
    "clusters": [
        {
            "status": "INACTIVE",
            "clusterName": "MyCluster",
            "registeredContainerInstancesCount": 0,
            "pendingTasksCount": 0,
            "runningTasksCount": 0,
            "clusterArn": "arn:aws:ecs:ap-northeast-1:694273932022:cluster/MyCluster"
        }
    ],
    "failures": []
}

statusがINACTIVEとなっていればOKです。

ECSのタスク、ECS用のロールを削除したい人は各自お願いします。

26
25
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
26
25