Kattsu Sandbox

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

投稿日:

はじめに

ステージング・本番環境をデータセンターから ECS に移行した際のメモです。 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 であれば<default>と 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 にデプロイまで行うようにする。

書いている人

大阪でソフトウェアエンジニアとして働いています。

© 2020 Kattsu Sandbox