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: ロール)
最初にロールを作成するためのファイルを作成します。
{
"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へアクセスするポリシーの作成をします。
{
"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にするとこのコンテナの実行が失敗するとタスクとして失敗したものとしてみなしてくれます。
[
{
"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が起動しているコンテナにアクセスし、以下の内容が確認できるかと思います。
お掃除
まず、クラスタに登録したタスクを停止します。
$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用のロールを削除したい人は各自お願いします。