ECSを運用で使っていて難しいと思った点
ECSを触っていて今まで難しいと思ったことを雑にまとめておく。
ECSを仕事で運用するときに必要な知識が多すぎる。こんなの社内に1人AWSマスターいないと無理だ...
— 神速 (@sinsoku_listy) 2021年8月10日
タスクロールとタスク実行ロールの違い
ECSを長く触っているのに、いつも混乱する。
- タスクロール
- コンテナ内の権限
- S3やSESなどの権限をつける
- タスク実行ロール
- コンテナ外の権限
- ECRやParameter Storeの権限をつける
ECSのデプロイ時に静的ファイルが404になる
ECSを触った初期に遭遇した。 詳細は以下のQiitaの記事が分かりやすい。
参照: ECSのデプロイ時に一定確率で静的ファイルが404になる問題を回避する
回避する方法はいくつかある。
- 静的ファイルをS3に置く
- CodeDeployの
OneAtATime
を使う - CodeDeployのBlue/GreenとALBのスティッキーセッションを使う
知らないと気づくのは難しい。
ECSサービスを無停止で更新する手順
ECSサービスをTerraformで変更するとき、一部の設定は replace
になる。
無停止で更新するために、新しいECSサービスを作成してターゲットグループをうまく切り替える必要がある。
- 新しいECSサービスを作成
Host: dummy.exmaple.com
のリスナールールに新ECSサービスを紐づける- デフォルトリスナーは旧ECSサービス
- 新旧のECSサービスを両方ともデプロイするようにデプロイを設定する
- リスナールールの
Host
を正しい値に変更- この時点で新ECSサービスにリクエストが流れる
- 旧ECSサービスを削除
手順が多くて面倒なので、リソースを作成する前にecs_serviceの全オプションをしっかり読んだ方が良い。
- EC2 -> Fargate の移行
- ECSデプロイ -> CodeDeploy の移行
- Propagate tagsの設定
少なくとも、これらの作業をするときに必要になった。
CannotPullContainerError でECSタスクが無限に再起動する
ECRにDockerイメージをプッシュしないでタスク定義を更新・デプロイすると起きる。
deployment circuit breaker の設定しておくと良い。
参考: Amazon ECS deployment circuit breaker のご紹介
execute-command は最大2セッション
ecs execute-command でECSタスクに接続できるのは 2セッション まで。
複数人がECSタスクに接続する運用がある場合には注意が必要。
Terraformでタスク定義の最新を参照する
デプロイするとタスク定義のリビジョンが変わるので、ecs_task_definitionのコードを参考にコードを書く必要がある。
data "aws_ecs_task_definition" "mongo" { task_definition = aws_ecs_task_definition.mongo.family } resource "aws_ecs_cluster" "foo" { name = "foo" } resource "aws_ecs_task_definition" "mongo" { family = "mongodb" container_definitions = "<略>" } resource "aws_ecs_service" "mongo" { name = "mongo" cluster = aws_ecs_cluster.foo.id desired_count = 2 # Track the latest ACTIVE revision task_definition = "${aws_ecs_task_definition.mongo.family}:${ max(aws_ecs_task_definition.mongo.revision, data.aws_ecs_task_definition.mongo.revision) }" }
CodeDeployを使っているとECSサービスのタグが更新できない
AWSコンソールからは普通にタグをつけられるが、Terraformからは更新できずに下記のエラーが起きる。
Unable to update network parameters on services with a CODE_DEPLOY deployment controller. Use AWS CodeDeploy to trigger a new deployment
詳細は調べられていないけど、AWS Providerのバグかも?
CodeDeploy Blue/Greenを使うとTarget Groupは交互に変わる
リソースを用意するときはTerraformだけど、デプロイは別で行う場合にターゲットグループがズレるケースがある。
- Terraformでターゲットグループ(TG-1, TG-2)を用意する
- Terraformで TG-1 をリスナールールに紐付ける
- CodeDeployでTG-1, TG2のデプロイ設定を行う
- CodeDeployでデプロイを行う
- リスナールールに紐づくリソースが TG-1 => TG-2 に変わる
- Terraformで設定を変える
- コード上は TG-1 がリスナールールに紐づいている
- apply するとECSサービスの紐づいていない TG-1 に変わり障害になる
terraform plan
の出力をちゃんと読めば気づける。
タスク定義みたいにTerraformのコードを工夫すれば回避できるのかな...私は知らないが...
GitHub Actions vs CodePipeline
どちらも触った経験があるけど、どちらも難しくて慣れが必要。
比較して考察している記事もあるので、読んでみると良い。