Amazon EC2 Container Serviceでサービスを構築する⑥ 〜 Container Instancesについて 〜

ECSのcontainerインスタンスはEC2インスタンスです。そのEC2インスタンスはECS container agentを実行し、クラスタ内に登録されています。ECSでtaskを実行するとactiveなcontainerインスタンスに配備されます。

Topics

Container Instance Concepts

  • containerインスタンスはclusterに登録するためにECS container agentを実行しなければならない。Amazon ECS-optimized AMIにはagentはすでにインストール済み。他のOSを使用したいならインストールする必要がある。詳しくはAmazon ECS Container Agentを参照。
  • ECS container agentがECSへの呼び出しを行うために、containerインスタンスは必要な権限を持ったアカウント用IAMロールで立ち上げる必要がある。詳しくはAmazon ECS Container Instance IAM Roleを参照。
  • taskに関連付けられたcontainerはネットワークポートを、ホストしているcontainerインスタンスのポートにマップされる。その為インターネット上から到達可能。containerの外部接続が必要ならcontainer instanceのsecurity groupで該当ポートのinboundアクセスを許可しなければならない。詳しくはCreate a Security Groupを参照。
  • ECSはcontainerインスタンスVPC内に構築することを強く推奨する。なぜならVPCは、ネットワークをより厳密にコントロールできより広範囲の設定を提供します。詳しくはAmazon EC2 and Amazon Virtual Private Cloudを参照。
  • containerインスタンスはECSサービスエンドポイントとの通信のために外部ネットワークアクセスを必要とします。その為、containerインスタンスをプライベートVPC内で実行する場合、外部接続を提供するNATインスタンスが必要となります。詳しくはNAT Instancesを参照。
  • containerインスタンスとして選択するEC2インスタンスのタイプはクラスタ内で利用可能なリソースを決定します。EC2はtaskが利用可能なCPU、メモリ、ストーレジ、ネットワークそれぞれのキャパシティが異なるインスタンスのタイプを提供します。詳しくはAmazon EC2 Instancesを参照。

Container Instance Life Cycle

ECS containerエージェントはクラスタインスタンスを登録するとき、containerインスタンスはステータスACTIVE、エージェントはコネクションステータスTRUEとなる。このcontainerインスタンスはtask実行リクエストを受けることが出来るようになる。

ECS containerインスタンスをterminateではなく、stop状態にするとステータスはACTIVEのままになるが、エージェントコネクションステータスは数分でFALSEとなる。containerインスタンス上で実行されていたtaskは止まる。container instanceを再びスタートすると、containerエージェントはECSサービスに再接続し、インスタンス上でtaskを実行できるようになります。

重要
もしcontainerインスタンスをストップしてスタート、または再起動するとECS container agentの古いバージョンではoriginal containerインスタンスIDを登録解除せずに再度インスタンスを登録するものもある。その為、本当に所持しているよりも多くのcontainerインスタンスクラスタ内に表示されるかもしれない。(もし同じEC2インスタンスIDでcontainerインスタンスIDが被ってたらACTIVEでエージェントコネクションステータスFALSEの方は安全に登録解除可能)。現在のECS container agentバージョンではこの事象はfixしています。現在バージョンへのアップデート方法はUpdating the Amazon ECS Container Agentを参照


containerインスタンスを登録解除またはterminateすると、containerインスタンスステータスはすぐにINACTIVEに変わる。containerインスタンス一覧を開いても表示されなくなる。しかし、終了させてから1時間は表示はされる。1時間経過後なくなっちゃう。

Check the Instance Role for your Account

ECS container agentはECS APIを叩く、その為、agentを実行するcontainerインスタンスはagentがあなたのものだと分かるIAMポリシーとロールが必要。

多くの場合ECSインスタンスロールはconsole first run experience(例のやつ)で自動生成される。以下の手順でアカウントにすでにECSサービスロールがあるかチェックすることが可能

To check for the ecsInstanceRole in the IAM console

  1. AWS Management ConsoleにサインインしてIAMコンソールを開く
  2. ナビゲーションからRolesを選択
  3. ロールリストからecsInstanceRoleを差が明日。もしあれば作る必要なし。なければAmazon ECS Container Instance IAM Roleを参照してロールを作成

Launching an Amazon ECS Container Instance

このトピックではECSコンテナインスタンスAWS Management Consoleを使っての実行について説明する。始める前にSetting UP with Amazon ECSは終わらしておけよ。インスタンスを実行したらそれを使ってtaskを実行できる!

To launch a container instance

  1. EC2コンソールを開く
  2. ナビゲーションバーからリージョンを選択する
  3. ダッシュボードからLaunch Instanceを選択する
  4. Choose an Amazon Machine Image(AMI)ページでCommunity AMIsを選択する
  5. containerインスタンス用のAMIを選択する。Amazon ECS-optimized AMIを選択することもできるし、他のOSを選択することも可能。Amazon ECS-optimized AMIを選択し無かったらInstalling the Amazon ECS Container Agentに従う必要あり。
    • ECS-optimized AMIを使うには、Search community AMIsフィールドにamazon-ecs-optimizedと入力してEnterを押すべし。amzn-ami-2015.09.c-amazon-ecs-optimizedAMIの横のSelectを選択し次へ。
  6. Choose an Instance Typeページで、インスタンスのハードウェアの設定が選択可能。t2.microインスタンスタイプがデフォルトでは選択されている。選択するインスタンスタイプはtask実行に利用可能なリソースを決定する
  7. Next: Configure Instance Detailsを選択
  8. Configure Instance Detailsページにて、インターネットからアクセス出来るようにAuto-assign Public IPフィールドがEnableになっていることを確認する
  9. Configure Instance DetailsページにてSetting Up with Amazon ECSでContainerインスタンス用に作成したecsInstanceRole IAM roleを選択する。
  10. (必須ではない) Amazon ECS Container Agent Configurationを参考に、agent環境変数等のユーザーデータをECS containerインスタンスに設定する。
    • デフォルトではcontainerインスタンスはデフォルトclusterに起動される。デフォルトではないclusterに起動したい場合はAdvanced Detailsリストを選択しUser dataフィールドに下記のスクリプトyour_cluster_nameを自分のクラスタ名に変更して貼り付けろ。
      • #!/bin/bash
        echo ECS_CLUSTER=your_cluster_name >> /etc/ecs/ecs.config
    • または、ecs.configファイルをS3上に持っていて、containerインスタンスロールへread onlyアクセスを許可しているならAdvanced Detailsリストを選択し以下のスクリプトyour_bucket_nameを自分のバケット名に置き換えてUser dataフィールドに貼り付けろ。起動時のAWS CLIのインストールと設定ファイルの書き込みのためだ。
    • #!/bin/bash
      yum install -y aws-cli
      aws s3 cp s3://your_bucket_name/ecs.config /etc/ecs/ecs.config
  11. Review and Launchを選択
  12. Review Instance Launchページにて、Security Groupの下にwizardが作られてsecurity groupが選択されるだろう。security gourpを選択する代わりに作成することもできるけど割愛します。
  13. Review Instance Launchページ似てLaunchを選択する
  14. Select an existing key pair or create a new key pairダイアログボックスでキーを選ぶ。準備ができたらacknowledgmentフィールドを選択しLaunch Instanceを選択だ!
  15. 確認ページはインスタンスが起動していくのを教えてくれる。View Instancesを選択し、確認ページを閉じてコンソールへ戻れ!
  16. Instancesスクリーンでインスタンスのステータスが見れる。インスタンスの起動には少しかかる。インスタンスを起動したら始めのステータスはpendingだぜ!インスタンスがスタート後runningに変わりpublic DNS nameがもらえるぜ!(Public DNSカラムが隠れていたらShow/Hideiconを選択してPublic DNSを選択しよう!

Starting a Task at Container Instance Launch Time

アプリケーションアーキテクチャデザインによるが、セキュリティやらモニタリングやらロギングのために同じ特定のcontainerを全てのconteinerインスタンス上で走らせる必要があるかもしれない。

実現方法の1つはcontainerインスタンスをdocker runコマンドを呼ぶように設定することです。それには起動時のuser dataスクリプトか、upstartやsystemdのようなinitシステムが使える。この方法で起動した場合、ECSはcontainerの情報を持たず、CPU、メモリ、ポートなどのがモニタリング出来ないため不便です。
ECSが正確に全てのtaskリソースを計算出来るためには、containerインスタンス上で実行したいcontainerのタスク定義を作成し、taskを起動時に配備するためにECSをEC2 user dataと一緒に使うべきだ。

以下の手順の中でEC2 user dataはECS introspection APIをcontainerインスタンスを識別するのに使用し、AWS CLIstart-taskコマンドをスタートアップ中に指定のtaskを実行するのに使用している。

To start a task at container instance launch time

  1. まだやってないなら、Creating a Task Definitionを参考に、起動時にcontainerインスタンス上で実行したいcontainerと一緒にtask定義を作成する
  2. ecsInstanceRole IAMロールにStartTask API実行権限を加える。詳細はAmazon ECS Container Instance IAM Roleを参照。
  3. 1つ以上のcontainerインスタンスLaunching an Amazon ECS Container Instanceを参考に起動する。でも、Step 10で下記のMIME multipart user dataスクリプトUser dataフィールドにコピペすべし。your_cluster_nameをcontainerインスタンスに登録したいclusterに、my_task_defを起動時にインスタンう上で実行したいtask定義に置き換えること。
    • 注意
      • 以下のMIME multipartコンテントはshell scriptを使い、設定とパッケージのインストールを行っている。更に、Upstream jobも、ecsサービスの実行されintrospection APIが使用可能になった後にtaskをスタートするために使用されている。
Content-Type: multipart/mixed; boundary="==BOUNDARY=="
MIME-Version: 1.0

--==BOUNDARY==
MIME-Version: 1.0
Content-Type: text/text/x-shellscript; charset="us-ascii"

#!/bin/bash
# Specify the cluster that the container instance should register into
cluster=your_cluster_name

# Write the cluster configuration variable to the ecs.config file
# (add any other configuration variables here also)
echo ECS_CLUSTER=$cluster >> /etc/ecs/ecs.config

# Install the AWS CLI and the jq JSON parser
yum install -y aws-cli jq
--==BOUNDARY==
MIME-Version: 1.0
Content-Type: text/text/upstart-job; charset="us-ascii"

#upstart-job
description "Amazon EC2 Container Service (start task on instance boot)"
author "Amazon Web Services"
start on started ecs

script
	exec 2>>/var/log/ecs/ecs-start-task.log
	set -x
	until curl -s http://localhost:51678/v1/metadata
	do
		sleep 1
	done

	# Grab the container instance ARN and AWS region from instance metadata
	instance_arn=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F/ '{print $NF}' )
	cluster=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .Cluster' | awk -F/ '{print $NF}' )
	region=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F: '{print $4}')

	# Specify the task definition to run at launch
	task_definition=my_task_def

	# Run the AWS CLI start-task command to start your task on this container instance
	aws ecs start-task --cluster $cluster --task-definition $task_definition --container-instances $instance_arn --started-by $instance_arn --region $region
end script
--==BOUNDARY==--

Deregister a Container Instance

containerインスタンスを終了したらclusterから登録解除出来ます。登録解除するとcontainerインスタンスは新しいtaskを受け入れることは出来ません。登録解除時にcontainerインスタンスで実行されていたtaskがあれば、taskは走り続けELBロードバランサーのhealthチェックをパスし続けます。instanceをterminateするか、 他の手段でtaskをstopするまでは。しかし、ECSでモニタリングも勘定もされませんず孤立します。containerインスタンス上の孤立taskがECSの一部であれば、サービススケジューラーは可能であれば異なるcontainerインスタンス上にtaskのコピーを開始するでしょう。

登録解除後に他の目的でcontainerインスタンスを使うつもりなら、孤立taskがリソース消費をしないように、登録解除前にcontainerインスタンス上で走っているtaskを全てstopするべきです。

containerインスタンスの登録解除はclusterからインスタンスを取り除くことです。しかし、EC2インスタンスはterminateしません。もしインスタンスの仕様を終えたいなら、確実にEC2コンソールでterminateしてください。

To deregister a container instance

  1. ECSコンソールを開く
  2. ナビゲージョンバーからcontainerインスタンスを登録しているリージョンを選択する。
  3. Clusterを選択
  4. Cluster: nameページでECS Instancesタブを選択
  5. 登録解除したいcontainerインスタンスIDを選択
  6. Container Instance: idページでDeregisterを選択
  7. 登録解除メッセージを見てYes, Deregisterを選択しcontainerインスタンスの登録解除
  8. containerインスタンスが終了したら、EC2インスタンスをterminate!
    • 注意
      • Auto Scaling gouprかCloudFormation stackでインスタンスを保守しているなら、Auto Scaling gourpかCloudFormation stackのアップデートでインスタンスをterminateする。さもなくば落としても落としても立ち上がるぞ!

今回はここまで。次回へ続く。。。のか?