■Amazon Elastic Container Service(Amazon ECS)
AWS ECSでDockerコンテナ管理入門(基本的な使い方、Blue/Green Deployment、AutoScalingなどいろいろ試してみた) - Qiita
https://qiita.com/uzresk/items/6acc90e80b0a79b961ce
【Docker × ECS入門】docker compose upでECSデプロイ - Qiita
https://qiita.com/Rubyist_SOTA/items/1ead200bf602569804ea
ECSやEKSのメトリクスを一括取得するContainer Insightsが一般公開!既存ECSクラスタも追加設定可能に! | DevelopersIO
https://dev.classmethod.jp/articles/container-insights-ga/
ECSの概念を理解しよう - まーぽんって誰がつけたの?
http://www.mpon.me/entry/2017/11/19/200000
ECSでごっつ簡単に機密情報を環境変数に展開できるようになりました! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/ecs-secrets/
Amazon ECSを安定運用するためにやっていること コンテナインスタンス、ログ、モニタリングにおける工夫 - ログミーTech
https://logmi.jp/tech/articles/320723
基礎から応用までじっくり学ぶECS Fargateを利用したコンテナ環境構築 #Fargate | Developers.IO
https://dev.classmethod.jp/articles/developers-io-2020-connect-kaji-ecs-fargate/
ECS×Fargateで実現する運用コストほぼ0なコンテナ運用の仕組み/ ecs fargate low cost operation - Speaker Deck
https://speakerdeck.com/shoichiron/ecs-fargate-low-cost-operation
Docker ComposeによるAmazon ECS対応がGAに!コンテナをローカル環境と同じノリでECS環境で起動できるぞ!! | Developers.IO
https://dev.classmethod.jp/articles/docker-compose-for-amazon-ecs-now-available/
ラズパイでもAmazon ECSを動かせる、「Amazon ECS Anywhere」が正式リリース。ラズパイやオンプレミスのコンテナ環境をAWSから集中管理可能 − Publickey
https://www.publickey1.jp/blog/21/amazon_ecsamazon_ecs_anywhereaws.html
Amazon ECS Anywhereを使ってAWS外でもコンテナが運用できるようになったので使ってみた | DevelopersIO
https://dev.classmethod.jp/articles/try-amazon-ecs-anywhere/
アプリケーション開発者は Amazon ECS あるいは Kubernetes をどこまで知るべきか #AWSDevDay / You build it, you run it - Speaker Deck
https://speakerdeck.com/toricls/you-build-it-you-run-it
AWS Black Belt コンテナシリーズのあるきかた 2021年10月版 | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/aws-black-belt-guide202110/
「コンテナ・サーバレスがもたらす世界と開発者がAWS上で取り組むべきこと」というタイトルで登壇しました - How elegant the tech world is...!
https://iselegant.hatenablog.com/entry/2022/03/08/071906
■FargateとEC2
EC2のセキュリティ対策は利用者自身が行う必要がある
一方Fargateはマネージドサービスのため、セキュリティ対策はAWSの責任になる
Fargateだと、ベストエフォートでAZ間のバランスを調整しながらタスクが配置される
つまり利用者は、AZ配置に関して考える必要が無い
Fargateの料金はEC2の1.4倍ほど
月額1万円が1万4000円になるような案件はFargateでいいと思うが、月額100万円が140万円になるような案件だと考慮が必要そう
AWS Fargate - サーバーやクラスターの管理が不要なコンテナの実行
https://aws.amazon.com/jp/fargate/
AWS Fargateとは? - Qiita
https://qiita.com/riywo/items/1a5b50028542d9bb06cc
AWS FargateとECSの違いは? - Qiita
https://qiita.com/ABCompany1/items/5f3fcea04052415dc875
【全世界のFargateファンに朗報】Fargate利用料が35%〜50%値下げされました! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/fargate-lower-price/
平成最後なのでEC2からECS+Fargateに 置き換えた話 - Speaker Deck
https://speakerdeck.com/marnie/ping-cheng-zui-hou-nafalseteec2karaecs-plus-fargateni-zhi-kihuan-etah...
AWS Fargateを本番運用した所感 - コネヒト開発者ブログ
http://tech.connehito.com/entry/2018/11/21/163534
AWS FargateではなくECS on EC2を選ぶメリット〜コスト編〜 - Uzabase for Engineers
https://tech.uzabase.com/entry/2022/12/01/175423
Fargateには「プラットフォームバージョン」というものがある
できるだけ最新を保つのが良さそう
AWS Fargate プラットフォームのバージョン - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/platform_versions.html
[アップデート] AWS Fargate (ECS)のプラットフォームバージョン “LATEST” が 1.4.0 になりました | DevelopersIO
https://dev.classmethod.jp/articles/fargate-updates-platform-version-1-4-0-to-be-the-latest-version/
Fargateプラットフォーム1.4.0の変更点 - Qiita
https://qiita.com/ryo0301/items/8929761f5df7e1e2e7a0
AWS Fargateのプラットフォームバージョンを1.3.0に固定したつもりが失敗したお話 - Qiita
https://qiita.com/imai_amazia/items/df139425df350be439a8
AWS FargateではなくECS on EC2を選ぶメリット〜コスト編〜 - Uzabase for Engineers
https://tech.uzabase.com/entry/2022/12/01/175423
■Fargateのプラットフォームのバージョン
「プラットフォームのバージョン: LATEST」は特定のバージョン(その時点での最新版)を指定すべきか
2023年5月時点で、選択できるバージョンは「LATEST」「1.4.0」「1.3.0」となっている
プラットフォームに問題が発覚した場合、恐らく「1.4.1」と「1.3.1」がリリースされるのだと思われる
それなら、マイナーバージョンを最新に保っておけばいいのだと思われる
プラットフォームバージョンが古いものは、徐々に廃止されていく
強制更新日になると、強制デプロイにより自動的に更新される
また、普段の更新でもLATESTがデプロイされることになるので、それによっても更新されることになる
AWS Fargate プラットフォームバージョンの廃止 - Amazon ECS
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/platform-versions-retired.html
1.4.0のときは、以下のような変更がされている
Fargateプラットフォーム1.4.0の変更点 - Qiita
https://qiita.com/ryo0301/items/8929761f5df7e1e2e7a0
そのままでも動作するかもしれないが、RDSのアップデートなどと同様に考えるなら、意図しない変更での問題は防ぎたい
よってバージョンは固定したうえで、検収環境などで問題無いことが確認できてから、プラットフォームのバージョンを手動で調整する方が安全そう
バージョンを固定する場合、CodePipelineやSDKの考慮が必要かどうかは確認しておく
AWS Fargateのプラットフォームバージョンを1.3.0に固定したつもりが失敗したお話 - Qiita
https://qiita.com/imai_amazia/items/df139425df350be439a8
■Fargateのスペック
ECSにおけるタスクとコンテナについて、前提として
・タスクはECSで管理する最小単位
タスクには1つ以上のコンテナが含まれる
単一のタスクは同一のホストOS上で稼働する。1つのタスクを2台以上のホストOSにまたいで稼働させることはできない
・コンテナはDockerのコンテナのこと
ECSのタスクに内包される
単一のコンテナを起動するには、1つのタスク内に1つのコンテナのみを内包する
となっているが、それを踏まえてFargateのスペックについて
インスタンスタイプは「タスクサイズ」により決定される
これは
・「サービスの設定 → デプロイ設定 → 必要なタスク」はデフォルト「1」だが、この場合はマルチAZでは無い
「2」以上にしてはじめてマルチAZになるので、本番環境では原則「2」以上にしておく
・「タスク定義 → 環境 → タスクサイズ」の「CPU」「メモリ」は、1つのタスクが使用するCPUとメモリを決定するもの
つまりデフォルトのCPU「1 VCPU」メモリ「3 GB」は、EC2の1台の性能に相当するものと考える
またnginxコンテナとphpコンテナを立ち上げるタスクの場合、その2つのコンテナにより1つのEC2(に相当するもの)が使われる
・例えば「必要なタスク」を「2」にした場合、全体でCPU「2 VCPU」メモリ「6 GB」の環境が用意されることになる
という理解でいいと思われる
例えば
「検収環境ではt3.micro(2vCPU / 1GB)で1台構成、本番環境ではt3.small(2vCPU / 2GB)で2台構成」
に相当する性能で稼働させたい場合、メモリベースで考えるなら
・検収環境での必要なタスクは「1」とする。タスクサイズは、CPU「0.5vCPU」、メモリ「1GB」とする
・本番環境での必要なタスクは「2」とする。タスクサイズは、CPU「1vCPU」、メモリ「2GB」とする
程度とするのがいいか
ただしそもそも、EC2とFargateの性能を単純に比較するのは難しそうなので、稼働させるプログラムに応じて考える
また上記の場合、検収環境はCPUが普段(EC2)よりも弱いので、動作が遅いなどの可能性はありそう
本稼働前に、負荷をかけてベンチマークを取るなどをしておくといい
Fargate タスクサイズの選択 - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/bestpracticesguide/fargate-task-size.html
ECS on Fargateの良いところ ~性能・拡張性~ | BTC Cloud
https://cloud.bigtreetc.com/column/merit-of-ecs-on-fargate-spec-scalability/
Amazon ECS タスク定義の"タスクサイズのCPU"と”コンテナのCPUユニット”の違いを調べてみた - のぴぴのメモ
https://nopipi.hatenablog.com/entry/2020/12/13/223713
FargateのvCPU性能と価格感等雑感
https://gist.github.com/nabeken/97a54cc98ae6892910df4b4b265b4fdd
■作業の流れ
おおまかに、以下のような作業の流れとなる
削除する場合、逆順に作業する
1. VPCの作成 ... ネットワークを作成する(クラスターと一緒に作成できるが、あらかじめ作成しておく方が良さそう)
2. ロードバランサーの作成 ... クラスターの上位に配置するロードバランサーを作成する
3. タスクの定義 ... クラスター上で動かすコンテナの情報を定義する(イメージ、CPUやメモリの制限、アプリケーションの環境変数など)
4. クラスターの作成 ... クラスターを動かすためのFargateやEC2の設定を行う(ネットワークなど。EC2の場合はインスタンスタイプ、インスタンス数も)
5. サービスの作成 ... VPC、ロードバランサー、タスク、クラスターを結びつける(一つのクラスターに複数のサービスを登録することもできる)
※イメージは「Amazon Elastic Container Registry(Amazon ECR)」で作成した「ecr_test」を使用するものとする
■VPCの作成
クラスター作成時、VPCを作成する指定を行なえばCloudFormationで一緒に作成される
が、ここではCloudFormationであらかじめ作成しておく(管理しやすいそうなので)
VPCの名前は、ここでは「Container」とする
※VPCやセキュリティグループは、CloudFormationであらかじめ作成しておく方が良さそう
手順中に新規に作った場合、名前が無しで作られるようなので、名前の設定はしておくと良さそう
手順中に作ると、ECSクラスターと一緒に削除してくれるメリットはあるが、VPCを削除することはそう無いか
■ロードバランサーの作成
EC2 → ターゲットグループ → ターゲットグループの作成
Choose a target type: IP addresses
Target group name: Container-Test-TargetGroup
VPC: Container(あらかじめ作成しておいたもの)
Protocol version: HTTP1
Healthy threshold: 2(デプロイ高速化のため変更するといい)
Interval: 30(ヘルスチェックの間隔はデフォルトで30秒だが、短くすればデプロイも早くなる。ただし間隔が短すぎるのも考えものか。要検討)
「Next」をクリック
「Register targets」の画面になる
特に何も変更せず「Create target group」をクリック
これでターゲットの無いターゲットグループができる
EC2 → ロードバランサー → ロードバランサーの作成
Select load balancer type: Application Load Balancer
Load balancer name: Container-Test-LoadBalancer
VPC: Container(あらかじめ作成しておいたもの)
Mappings: Container-Public-A, Container-Public-C(あらかじめ作成しておいたもの)
Security groups: default, Container-WebSecurityGroup(あらかじめ作成しておいたもの / 80番ポートを通すためのセキュリティグループを選択)
Listeners and routing
Protocol: HTTP
Port: 80
Default action: Container-Test-TargetGroup
「Create load balancer」をクリック
ロードバランサーが作成されるので、「View load balancer」で確認する
ターゲットタイプについては以下を参照
Blue/Greenデプロイを使うなら、「Instance」ではなく「IP addresses」にしておく必要があるらしい
(古いプログラムと新しいプログラムを混在することが短時間でも許容できない場合、Blue/Greenデプロイを採用するといい)
[新機能] ALBのターゲットにIPアドレスを指定可能になりました | DevelopersIO
https://dev.classmethod.jp/articles/ip-target-for-alb/
ALBのターゲットにIPアドレスを指定できる機能は、2017年からの機能らしい
外部のサーバを指定したりではなく、ローカルのIPを指定する前提みたい
到達可能なIPアドレスであれば、VPCをまたいで指定できるメリットはあるみたい
ターゲットグループ作成時の「Healthy threshold」と「Interval」の設定によるデプロイ高速化については、以下の記事が参考になる
Amazon ECS でのコンテナデプロイの高速化 | トリの部屋
https://toris.io/2021/04/speeding-up-amazon-ecs-container-deployments/
CodePipelineの環境を作って、Gitへのプッシュからデプロイ完了までの時間を確認すると、以下のような変化があった
3分ほど早くなったので、確かに効果はありそう(設定次第では、さらに早くできそう)
20:22 にプッシュ
Sourceはすぐに完了した
Buildは20:26に完了した(4分かかった)
Deployは20:33に完了した(7分かかった)
合計11分ほどかかった
ターゲットグループの「Healthy threshold」の設定を「5」から「2」に変更
20:36 にプッシュ
Sourceはすぐに完了した
Buildは20:40に完了した(4分かかった)
Deployは20:44に完了した(4分かかった)
合計8分ほどかかった
■タスクの定義
※イメージは「Amazon Elastic Container Registry(Amazon ECR)」で作成した「ecr_test」を使用するものとする
※本番運用するなら、「コンテナの追加」の際に「ストレージとログ」の「ログ設定」にチェックを入れておくか
再作成する場合、CloudWatchのロググループが作成済みなら、あらかじめ削除しておく必要があるか
Elastic Container Service → Amazon ECS → タスク定義 → 新しいタスク定義の作成 → 新しいタスク定義の作成
タスク定義とコンテナの設定
タスク定義ファミリー: Container-Test-Task
コンテナの詳細
名前: ecr_test
イメージURI: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
プライベートレジストリ認証: (チェックしない / ECR以外でプライベートリポジトリを利用する場合に必要みたい)
ポートマッピング:
コンテナポート: 80
プロトコル: tcp
ポート名: ecr_test-80-tcp(初めから入力されていた)
アプリケーションプロトコル: HTTP
「次へ」をクリック
環境、ストレージ、モニタリング、タグの設定
アプリケーション環境: AWS Fargate (変更せず) ★「Amazon EC2 インスタンス」も検証したい
オペレーティングシステム/アーキテクチャ: Linux/X86_64 (変更せず)
タスクサイズ
CPU: 1 vCPU (変更せず / 詳細は「Fargateのスペック」を参照)
メモリ: 3 GB (変更せず / 詳細は「Fargateのスペック」を参照)
タスクロール: (未選択のまま)
タスク実行ロール: ecsTaskExecutionRole (変更せず)
ネットワークモード: awsvpc(Fargateの場合、awsvpc以外に変更できない)
モニタリングとログ記録: (デフォルトで「ログ収集の使用」にチェックされている。本番運用でなければチェックを外しておくか)
「次へ」をクリック
確認して作成
「作成」をクリック
「正常に作成されたタスク定義」のようなメッセージが表示されれば完了
「作成」ボタン押して以下のエラーが作成された場合、作業しているユーザの権限を確認する
User: arn:aws:sts::949004901725:assumed-role/AWSReservedSSO_PowerUserAccess_1db0a2445f639f21/refirio is not authorized to perform: iam:PassRole on resource: arn:aws:iam::949004901725:role/ecsTaskExecutionRole because no identity-based policy allows the iam:PassRole action
Fargate タスクサイズの選択 - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/bestpracticesguide/fargate-task-size.html
Fargateの場合、インスタンスタイプは上記設定の「タスクサイズ」により決定される
ECSのタスクロールとタスク実行ロールの違い - karakaram-blog
https://www.karakaram.com/difference-between-ecs-task-role-and-task-execution-role/
ネットワークモードについては以下を参考
Blue/Greenデプロイを使うなら、「<default>」ではなく「awsvpc」にする必要があるみたい
ECSでEC2インスタンスを利用する際のネットワークモードについて調べてみた | DevelopersIO
https://dev.classmethod.jp/articles/ecs-networking-mode/
ECSのバックエンドをEC2からFargateに変更するにあたり知っておくとよさそうな事 - コネヒト開発者ブログ
https://tech.connehito.com/entry/2018/09/05/164805
AWS ECSのネットワークモードの違いを調べてみた - 私の戦闘力は53万です
https://cloud-aws-gcp.hateblo.jp/entry/2019/10/30/023835
「EC2」の場合は「bridge」を選択すれば良さそうだが、以前は「<default>」を選択していた
とは言え、ネットワークモードは「<default> = bridge」みたい?
【Amazon ECS】Amazon Elastic Container Service (EC2 Linux + ネットワーキング)を構築してみた - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/ecs-ec2-linux-networking
■クラスターの作成
Elastic Container Service → Amazon ECS → クラスター → クラスターの作成
クラスターの作成
クラスター名: Container-Test-Cluster
ネットワーキング
VPC: Container(あらかじめ作成しておいたもの)
サブネット: Container-Public-A, Container-Public-C(あらかじめ作成しておいたもの)
デフォルトの名前空間: Container-Test-Cluster(初めから入力されていた)
インフラストラクチャ: AWS Fargate(はじめからチェックされていて、チェックを外せないようになっている)
モニタリング: (チェックしない / 後から変更できないかも?本番環境用ならチェックを入れておくと良さそう)
「作成」をクリック
※はじめてクラスターを作成する際、「Unable to assume the service linked role. Please verify that the ECS service linked role exists.」と表示されて中断された
もう一度同じ操作をすると、「ECSクラスターContainer-Test-Clusterが正常に作成されました」と表示されて完了した
クラスター作成時に必要なロールが作成されるが、そのロールが使えるようになるには若干のタイムラグがあるため…らしい
ただしエラーが発生したのはEC2のとき。Fargateの場合も発生するかは不明だし、そもそも改善されているかもしれない
ECS初回構築時に自動作成されるIAMロール「AWSServiceRoleForECS」とTerraformでの予期せぬ挙動 - 憂鬱な世界にネコパンチ!
https://nekopunch.hatenablog.com/entry/2018/09/01/122525
AWS Fargate - Qiita
https://qiita.com/propella/items/d261879e89774a06e2bb
■サービスの作成
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → 作成
サービスの設定
環境
コンピューティングオプション: キャパシティープロバイダー戦略 ★「起動タイプ」についても検証したい
キャパシティープロバイダー戦略: カスタムを使用(変更できず)
キャパシティープロバイダ: FARGATE(変更せず)
ベース: 0(変更せず)
ウェイト: 1(変更せず)
プラットフォームのバージョン: LATEST ※実案件では「1.4.0」などその時点での最新を選択する方が良さそう
デプロイ設定
アプリケーションタイプ: サービス
リビジョンの手動指定: (デフォルトのままチェックを入れず) ★意味については確認したい
ファミリー: Container-Test-Task
リビジョン: 1(最新)
サービス名: Container-Test-Service
サービスタイプ: レプリカ(変更できず)
必要なタスク: 2(デフォルトは1だが、2以上でマルチAZとなる)
ネットワーキング
VPC: Container
サブネット: Container-Public-A, Container-Public-C
セキュリティグループ: default, Container-WebSecurityGroup(あらかじめ作成しておいたもの / 80番ポートを通すためのセキュリティグループを選択)
ロードバランシング
ロードバランサーの種類: Application Load Balancer
Application Load Balancer: 既存のロードバランサーを使用
ロードバランサー: Container-Test-LoadBalancer
ロードバランス用のコンテナの選択: ecr_test 80:80 (変更せず)
リスナー: 既存のリスナーを使用
リスナー: 80:HTTP
ターゲットグループ: 既存のターゲットグループを使用
ターゲットグループ名: Container-Test-TargetGroup
ヘルスチェックパス: /(変更せず)
ヘルスチェックプロトコル: HTTP(変更せず)
ヘルスチェックの猶予期間: 120 ★適切な値は確認したい(FargateではなくEC2のときだが「0だとコンテナサイズによってはうまく起動しないことがある」と聞いた)
「作成」をクリック
2〜3分ほど待つと、サービスの「前回のデプロイ」列が「完了」になった
「サービスタイプ」については引き続き調査したい
ECSをより便利に使うためのポイント解説 - UUUM攻殻機動隊(エンジニアブログ)
https://system.blog.uuum.jp/entry/aws-ecs-tips
Amazon ECS タスク配置戦略 - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-placement-strategies.html
■動作確認
ロードバランサーのDNS名にアクセスすると、ページが表示される
http://Container-Test-LoadBalancer-1234567890.ap-northeast-1.elb.amazonaws.com/
ターゲットグループを確認すると、2つのインスタンスがぶら下がっている
それぞれ、ローカルのIPアドレスを持っている
インスタンスIDや名前は付けられていない(表示用の列自体が無い)
EC2のインスタンス一覧には表示されていない
■イメージの変更
変更したイメージを作成し、ECRにプッシュする
$ cd docker/ecr_test
$ docker image build -t ecr_test .
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
タスク定義に新しいリビジョンを作成する
Elastic Container Service → Amazon ECS → タスク定義
「Container-Test-Task」にチェックを入れて「新しいリビジョンの作成」をクリック
(以下、前回タスクを作成した時の内容をベースに入力する)
「イメージ URI」のみ以下に変更した(末尾のバージョンを変更)
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → Container-Test-Service → サービスを更新
デプロイ設定で以下2箇所を調整する
「新しいデプロイの強制」にチェックを入れる
「リビジョン」を最新のものに変更する
「更新」をクリック
2〜3分ほど待つと更新される
■コンテナへのSSH接続
※未検証
※後からAmazon ECS Execがリリースされ、SSHキーなどを使わずに直接コンテナに接続できるようになった
「Windows+WSL2+AWS CLI+Session Manager」で、ローカルPCから直接コマンドラインで操作できるようになる
詳細は、このファイル内の「Amazon ECS Exec」を参照
EC2とは違い、Fargateに直接SSHで接続したりはできない
どうしても接続したい場合、AWS Systems Managerを使えば接続できるらしい
ECS FargateにSSMを利用してSSH接続する(チュートリアル) - Qiita
https://qiita.com/kouji0705/items/005ea6d7c21ddd24ebb3
FargateのコンテナでOSコマンドやsshで入りたい!! それssm-agentで解決できます
https://zenn.dev/ryurock/articles/qiita-20191203-fa18b25b1b38c9a0f113
[AWS ECS]Fargateのcontainerにシェルで入りたい(sshd無しで!) - Qiita
https://qiita.com/pocari/items/3f3d77c80893f9f1e132
AWS Fargateで動いているコンテナにログインしたくて Systems Manager の Session Manager を使ってみた話 - SMARTCAMP Engineer Blog
https://tech.smartcamp.co.jp/entry/fargate-with-session-manager
■環境の削除
※見かけ上の削除処理がすぐに完了したとしても、裏側ではCloudFormationなどが実行中で完了はしていないことがある
よって環境を削除してすぐに同じ名前で環境を作ると、「すでに存在している」などのエラーになることがある
また、何らかの理由でCloudFormationが正常に完了できない可能性もある
削除後に再作成する場合、30分ほど時間を空けたり、CloudFormationに未完了の処理が無いか確認するなどするのが無難
上の手順で作成した場合、以下の順番で削除できる
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス
から「Container-Test-Service」を削除
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster
で「クラスターの削除」をクリック
これで関連するCloudFormationとEC2インスタンスも削除される(少し時間がかかる)
Elastic Container Service → Amazon ECS → タスク定義 → Container-Test-Task
からすべてのリビジョンを登録解除(これでタスク定義の一覧からも Container-Test-Task が削除される)
EC2 → ロードバランサー
から「Container-Test-LoadBalancer」を削除
EC2 → ターゲットグループ
から「Container-Test-TargetGroup」を削除
CloudFormation → スタック
CloudFormationを別途手動で作成した場合、必要に応じて別途削除する
また、不要になったセキュリティ認証情報(ロールやポリシー)を削除しておく
なお、タスク定義は「登録解除」しかできなかったが、これはタスクの一覧で「非アクティブなタスク定義」を選択することで表示できる状態だった
が、2023年3月ごろに「非アクティブなタスク定義」一覧から削除できるようになった
(とは言え、タスク定義が残っていても料金はかからないらしい)
Amazon ECSのタスク定義のリビジョンが削除できるようになった - Qiita
https://qiita.com/t_tsuchida/items/8f62aa8a218d5b9121fb
■ECS+EC2の構築メモ
「インフラストラクチャの作成」という手順が必要?
何か変更されたか、以前と違う操作をしてしまっているだけか
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → インフラストラクチャ → コンテナインスタンス → 外部インスタンスを登録
アクティベーションキーの有効期間 (日数): 1(変更せず)
インスタンス数: 4(デフォルトは1000。「このアクティベーションで登録する外部インスタンスの最大数です。」とあるので、これは1000台のEC2インスタンスが作られるのではなく、上限値を設定するだけ?)
インスタンスロール: 新規作成
「登録コマンドの生成」ボタンをクリック
以下のようなコマンドが表示されたが、よく解らず
curl --proto "https" -o "/tmp/ecs-anywhere-install.sh" "https://amazon-ecs-agent.s3.amazonaws.com/ecs-anywhere-install-latest.sh" && bash /tmp/ecs-anywhere-install.sh --region "ap-northeast-1" --cluster "Container-Test-Cluster" --activation-id "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" --activation-code "XXXXXXXXXXXXXXXXXXXX"
■ECS+EC2の動作確認メモ
FargateではなくEC2を採用したときの動作確認メモ
ターゲットグループを確認すると、以下2つのインスタンスがぶら下がっている
i-02e8ec2ab414b6c2d
i-0017fea28482d815b
各インスタンスの名前は、以下のようになっている(自動で付けられたもの)
ECS Instance - EC2ContainerService-Container-Test-Cluster
各インスタンスのIPアドレスで、直接アクセスすることもできる
http://203.0.113.1/
http://203.0.113.2/
また、インスタンスに紐づいているセキュリティグループで22番ポートへのアクセスを許可すると、SSHで直接アクセスできる
サーバ内の /etc/ecs/ecs.config に、ECSの設定ファイルらしきものがある
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → タスク
以下が表示されている
インスタンスは同じものが使われている?
タスク タスク定義 コンテナインスタンス EC2インスタンス
0715d017bb5f4764bed66b00836d899d Container-Test-Task:1 5b23968a45a74f6aa16bf9f0b019e19d i-02e8ec2ab414b6c2d
2bd80034be4b4eb1bb91d5a732dff8cf Container-Test-Task:1 fd472723b89845549b13024396418ae2 i-0017fea28482d815b
タスク 0715d017bb5f4764bed66b00836d899d を停止させてみる
すぐにタスクの一覧から削除された
10秒程度で、すぐに別のインスタンスが起動した
タスク タスク定義 コンテナインスタンス EC2インスタンス
2bd80034be4b4eb1bb91d5a732dff8cf Container-Test-Task:1 fd472723b89845549b13024396418ae2 i-0017fea28482d815b
7d346e49f4be45de9b53350378211f81 Container-Test-Task:1 5b23968a45a74f6aa16bf9f0b019e19d i-02e8ec2ab414b6c2d
今度はEC2のインスタンス一覧から、i-02e8ec2ab414b6c2d を直接停止させてみる
停止させる際
・このインスタンスはAuto Scalingグループにアタッチされている
・停止すると自動的に別のインスタンスが立ち上がる可能性がある
という注意が表示される
自動で別のEC2インスタンスが起動された
タスク タスク定義 コンテナインスタンス EC2インスタンス
2bd80034be4b4eb1bb91d5a732dff8cf Container-Test-Task:1 fd472723b89845549b13024396418ae2 i-0017fea28482d815b
374003de24e043dfa5b7ac309be69d4d Container-Test-Task:1 7ab06e6ff00747eb9b04a070a9cbe596 i-0b11a824305c8d37d
新しいインスタンスにも、HTTP&SSHとも直接アクセスできている
■ECS+EC2の動作確認メモ: イメージの変更準備(動的ポートマッピングの設定)
動的ポートマッピングを利用するため、
Container-WebSecurityGroup(Webサーバに設定しているセキュリティグループ)のインバウンドルールに以下を追加
タイプ: カスタムTCP
プロトコル: TCP
ポート範囲: 32768-61000
ソース: Container-WebSecurityGroup ※ロードバランサーからのアクセスを許可する(ロードバランサー専用にセキュリティグループを設定しているなら、それを指定する)
説明: Dynamic port mapping
【図解】ELB + ECSの動的ポートマッピング | DevelopersIO
https://dev.classmethod.jp/articles/dynamic-portmapping-elb-ecs/
ECSでタスク定義更新してデプロイしても古いタスク定義のままになる問題について - インターネットのスケッチ
https://khanamoto.hatenablog.com/entry/2021/05/18/222001
■ECS+EC2の動作確認メモ: イメージの変更準備(イメージの準備)
変更したイメージを作成し、ECRにプッシュする
$ cd docker/ecr_test
$ docker image build -t ecr_test .
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
■ECS+EC2の動作確認メモ: イメージの変更
タスク定義に新しいリビジョンを作成する
Elastic Container Service → Amazon ECS → タスク定義
「Container-Test-Task」にチェックを入れて「新しいリビジョンの作成」をクリック
(以下、前回タスクを作成した時の内容をベースに入力する)
タスク定義名: Container-Test-Task (変更せず)
タスクロール: なし
ネットワークモード: <default> (変更せず)
もともと追加されている「ecr_test」をクリックし、必要な箇所を調整
コンテナ名: ecr_test
イメージ: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
プライベートレジストリの認証: (チェックしない)
メモリ制限 (MiB): ハード制限 128
ポートマッピング:
ホストポート: 0 ※通常は80だが、動的ポートマッピングを利用するため0に設定する
コンテナポート: 80
プロトコル: tcp
環境
基本: (チェックを入れたままにする)
「更新」をクリック
「作成」をクリック
「タスク定義 Container-Test-Task: 3 の新しいリビジョンを正常に作成しました」と表示された
次にサービスを更新して新しいリビジョンを選択する
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → Container-Test-Service → サービスを更新
サービスの設定
タスク定義
リビジョン: 2 (latest)
新しいデプロイの強制: チェックを付ける
タスクの配置
配置テンプレート: AZバランススプレッド
「次のステップ」をクリック
「次のステップ」をクリック
「次のステップ」をクリック
「サービスの更新」をクリック
「デプロイメント」タブ内の画面に移動し、デプロイ状況が表示される
「ロールアウトの状態」列の最下部が「完了」になれば完了(通常すぐに完了される)
ただしこの時点では、まだ前のバージョンのタスクが起動されたまま
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス
「Container-Test-Service」のタスク定義のバージョンが変わっていることを確認する
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → タスク
タスクが4つになっていることを確認する(タスクの起動までは2〜3分程度かかる)
タスク更新時に以下のように設定したので、最大で4タスク、最低で2タスク起動されることになる
タスクの数: 2
最小ヘルス率: 100
最大率: 200
2〜3分程度待つと、更新の反映が完了する
(不要になったタスクの終了も含めてだと、10分程度かかる)
■ECS+EC2の動作確認メモ: 補足1
EC2の台数には変化がない
ロードバランサーには変化がない
ターゲットグループでは、以下のようにターゲットの切り替えを確認できる
(ターゲットが切り替わらない場合、動的ポートマッピングのためのセキュリティグループ設定がされているかを確認する)
Instance ID Name
Port Zone Health status Health status details
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1c healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1a healthy
↓
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1c draining Target deregistration is in progress
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1c healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1a healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1a draining Target deregistration is in progress
↓
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1c healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1a healthy
■ECS+EC2の動作確認メモ: 補足2
「新しいデプロイの強制」にチェックを入れなかった場合、以下のようにしてタスクを入れ替えることができる
1. タスクを1つ選択し、「停止」ボタンで停止させる
2. サービスの設定に従って、「Container-Test-Task:1」ではなく「Container-Test-Task:2」が起動される
この場合、動的ポートマッピングの設定は不要だが、起動させるべきタスクの数が多いと単純に手間がかかる
また、どうしてもダウンタイムが発生してしまうと思われる
※タスクを停止した直後は、タスクが終了された方のインスタンスにアクセスされてエラーが表示されることがある
数秒で解消するようだが、本番運用するとなると気になる
CodePipelineでの自動デプロイなら、「新しいタスクが起動されてから、古いタスクへのアクセスが遮断される」となっているようなので問題無いか
■ECS+EC2の動作確認メモ: 補足3
「新しいデプロイの強制」にチェックを入れると、自動でタスクが差し変わる…はずだが、最初はいつまで経っても変わらなかった(チェックをいれていないときでも、エラーになることがあった)
サービスの「イベント」タブを確認すると、以下のように表示されていた
service Container-Test-Service was unable to place a task because no container instance met all of its requirements.
The closest matching container-instance 2f7dd44c692b4a028183e6d9bb053659 is already using a port required by your task.
For more information, see the Troubleshooting section.
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/troubleshooting.html
以下によると、スペック不足の可能性はありそうだが、クラスターのインスタンスタイプをmicroからsmallにしても変わりなかった
ECS運用のノウハウ - Qiita
https://qiita.com/naomichi-y/items/d933867127f27524686a
[AWS] Amazon ECS(EC2タイプ)のちょっと長めのチュートリアル(第6回) - Qiita
https://qiita.com/VA_nakatsu/items/8e588c693a2f650c2af3
Amazon ECS コンテナインスタンスの要件エラーを解決する
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ecs-container-instance-requirement-error/
今回の場合、動的ポートマッピングを使う必要があった
【図解】ELB + ECSの動的ポートマッピング | DevelopersIO
https://dev.classmethod.jp/articles/dynamic-portmapping-elb-ecs/
ALB + ECSの動的ポートマッピングでローリングアップデートをする - Qiita
https://qiita.com/mochizuki-pg/items/138de08e7a9ea03f241d
イメージ更新時は恐らく
1. Webサーバ用のコンテナを追加で起動する
2. 追加で起動した方のコンテナにトラフィックを移す
3. もともと起動していた方のコンテナを終了させる
という流れのはずだが、1でコンテナを起動しようにも、すでに80番ポートが使われていて起動できない…という現象
この対策に、新しいWebサーバ用のコンテナは 32768-61000 で起動し、ロードバランサーからのアクセスもこのポートに合わせる
これを動的ポートマッピングと呼ぶ
■ECS+EC2の動作確認メモ: クラスターのインスタンスタイプを変更する
クラスターを作成する際にEC2のインスタンスタイプを指定するが、ECSの画面内にこの指定を変更する箇所が無い
これはクラスター作成時に実行されるCloudFormationスタックで指定する必要がある
今回は「t2.micro」を「t2.small」に変更するものとする
CloudFormation → スタック → EC2ContainerService-Container-Test-Cluster → 更新
テンプレートの指定
テンプレートの準備: 「現在のテンプレートの使用」が選択されていることを確認する
「次へ」をクリック
スタックの詳細を指定
EcsInstanceType: 「t2.micro」を「t2.small」に変更する
「次へ」をクリック
スタックオプションの設定
「次へ」をクリック
レビュー
「スタックの更新」をクリック
スタックが更新され、数秒で処理が完了した
ただしこの時点では、まだEC2のインスタンスタイプは変更されていない
EC2 → インスタンス
クラスター用のEC2を停止させると、オートスケーリングによって自動的にEC2が起動される(停止させたEC2は自動的に終了される)
起動されたEC2はインスタンスタイプがt2.smallになっていることを確認する
(ただし、停止させてから自動起動が完了するまでは、5〜10分程度タイムラグがあるかもしれないので注意)
Amazon ECSでインスタンスタイプを変更する | DevelopersIO
https://dev.classmethod.jp/articles/ecs-change-instance-type/
ECS(EC2)のインスタンスタイプ変更は要注意 - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/2020/08/05/193842