AWS
Docker
ECS

【AWS】ECSでのステージング・本番環境構築

ステージング・本番環境をデータセンターからElasticContainerServiceに移行した際のメモです。

ECSはFargateではなくEC2インスタンスで動かします。


なぜステージング・本番環境をECSで構築するか


  • 開発環境と同じ環境で稼働させたい(同じDockerイメージを使えば可能になる)

  • スケールできるようにしたい


ECSの全体的な構成


タスク定義

ひとつまたは複数のコンテナを動かすための設定でdocker-compose.ymlのようなもの。


タスク

タスク定義を動かした実態。Dockerコンテナの集まり。

リソースが許せばひとつのEC2インスタンス(≒コンテナインスタンス)の中に複数のタスクを実行させることが可能。

リソースやタスクの割り振りはECSがいいように行ってくれる。


サービス

下記のようなタスク管理を行う。


  • どのタスク定義から何個のタスクを走らせるか

  • デプロイ時の古いタスクと新しいタスクの入れ替えをどのようなルールで行うか(ダウンタイムを作らずやるか、ダウンタイムありで素早く入れ替えるか)

  • どのロードバランサーからクラスター内のEC2インスタンスに振り分けるか

  • オートスケーリング


クラスター

どのようなEC2インスタンスを、どこで、何個動かすかを決定する。

中に複数のサービスを持ち、サービスにEC2インスタンスを使わせるための土台のようなもの。

FargateはEC2インスタンスの管理をこちらでやらなくてよくなるので、クラスターでFargateを選べばクラスターの設定はほぼなくなる。なのでFargateの方が楽だがその分料金が高い。

ECSの全体的な構成はこちらの記事が参考になりました。

Amazon EC2 Container Service(ECS)の概念整理 - Qiita


クラスターを作成


EC2のインスタンスタイプ・個数

動かすタスクの使用メモリ・CPUとその数によって、EC2のインスタンスタイプと数を決定する。

例えば、メモリ512Mib、CPU256unit(0.25vCPU)のタスクを2個動かす場合、

最低でもメモリ1Gib、0.5vCPUのインスタンスが1つは必要になる。

オートスケーリングの有無や、デプロイ時のタスク入れ替えルールによってもこのあたりは変わってくる。


ネットワーク

サービスで選択するLBから繋げるようなVPC・サブネット・セキュリティグループにする。

ALBから動的ポートマッピングさせる場合、32768-61000のいずれかのランダムなポートでEC2に来るのでセキュリティグループでこれらのポートを空けておく必要がある。


ECRを作成

ただのDockerイメージのリポジトリ。リポジトリ名だけで特に設定なし。

ローカルでビルドしたDockerイメージをpushする。

pushするためのコマンドはECRを作成したときに出てくる。


タスク定義を作成

docker-compose.ymlをイメージして作成する。

以下ははまったとこ。


ネットワークモード

DockerコンテナがLinuxであればとBridgeは同じ設定である。

Bridge接続になることでひとつのEC2インスタンスの中で複数のタスクを動かすことができるようになるっぽい。


コンテナのポートマッピング

ホストポートを0とすることでエフェメラルポートが動的に割り当てられ、ALBから動的ポートマッピングが可能になる。

クラスター作成の項で書いたようにセキュリティグループでポートを空けておくこと。

その他、S3バケット、RDSなど必要に応じて作成して環境変数に入れるなどする。


(サービス作成の前に)ALBを作成

HTTP、HTTPSレベルでのロードバランサー。

どのようなリクエストをクラスターにあるEC2にどう分散させるかを設定する。

今回はブラウザからHTTPSでリクエストが来る想定で作成する。

作成し終わったらDNSレコードにCNAMEでDNSnameを登録する。

スキーマ:internet-facing(外向け)

リスナー:HTTP(80)、HTTPS(443)(証明書をACMで作成)

VPC、サブネット、セキュリティグループ:外向けのもの

ターゲットグループ:プロトコルHTTP、ターゲットタイプinstanceで作成

ターゲット登録:ここではなにも登録しない(サービスと紐付けると自動でクラスターにあるEC2インスタンスに分散される)


サービスを作成


デプロイ時のタスク数


  • Minimum healthy percent:通常タスク数の何%までタスク数を減らせるか。通常タスク数が2なら、動いているタスク数が1まではデプロイ時に減らしていいとなる。

  • Maximum percent:通常タスク数の何%までタスク数を増やせるか。通常タスク数が2なら、動いているタスク数が3まではデプロイ時に増やしていいとなる。


ロードバランサー

選択したALBからサービスがいるクラスター上のEC2インスタンスへリクエストが分散されるようになる。

また、ここでパスパターンによるルーティングも設定できる。

サービスを作成してタスクの起動がうまくいったらALBのDNSNameなどでアクセスして接続がうまくいっているか確認。

タスクの起動がうまくいかない場合やタスクがRunningでもアクセスがうまくいかない場合は、各タスクIDを選択して(タスクが失敗している場合はStoppedで絞り込んで出てきたタスク)出てくる画面のタブでLogsを選択してログを確認する。

よくあった失敗


  • EC2インスタンスのリソースが足りない

  • ロググループが作成されていない

  • ECRからイメージを下ろせていない


CodePipelineで自動ビルド~デプロイ

Githubと連携して特定リポジトリにpushがあったらCodeBuildでビルド、ECSにデプロイまで行うようにする。