Amazon ECSコンテナ #SaaS化 :クラスター生成、タスク定義

AWS

2023.11.8

Topics

はじめに

こんにちは、エンジニアのFeelです。
以前の投稿に続き、SaaS化のための技術的方法の一つであるコンテナサービスをAWS代表サービスのECSを用いて調べたいと思います。前回の投稿で、1つのWebアプリをイメージ化してリポジトリにプッシュするプロセスまで確認したので、今回はコンテナインスタンスのグループであるクラスターの作成と管理方法、コンテナの設定テンプレートと言われるタスク定義について確認したいと思います。

クラスターの生成

まず、クラスターを作成する前にNAT Gatewayを作成する必要があります。ECSクラスターを作成して、そこから生成されるEC2インスタンスをPrivate Subnetに配置する予定なので、 NAT Gatewayを介してPrivate Subnetのインスタンスがインターネットに接続できるようにします。

※Private Subnetに配置する理由:展開するサービスに対してセキュリティを確保するため外部から隔離する
※NAT Gatewayを作成する理由:EC2は正常に作成して動いていてもAWS ECSのAgentと通信ができず、ECSクラスターとして利用ができない

まず、NAT Gateway生成のためにVPCに入り、左のカテゴリで「NAT gateways」をクリックし、右側の「NAT ゲートウェイを作成」ボタンをクリックします。

NAT GatewayはPrivate Subnet インスタンスをインターネットに接続する必要があるため、パブリックサブネットに配置する必要があります。
そして、すでに作成した Elastic IP があればそのまま使用し、ない場合は「Elastic IP 割り当て」ボタンをクリックしElastic IP を受け取ります。これでNAT Gateway の作成は完了です。


続いて、ルーティングテーブルにてNAT Gatewayを追加します。

  • 送信先に「0.0.0.0/0」を追加
    • ※元々はデスティネーションのIPを指定して一つ一つを送信先に登録するのがセキュリティー上良いです。
  • ターゲットはNAT Gateway を選択
  • 「変更を保存」ボタンをクリックすると、NAT Gatewayの設定が完了します。

それでは、クラスターを作成してみます。 まず、ECSサービスで「クラスター」カテゴリをクリックしてから、「クラスターの作成」ボタンをクリックします。

新しい「ECSエクスペリエンス」の設定をオフにして作成します。タスクロールなど既存の機能が設定できない等少し違和感を感じましたので旧ECSエクスペリエンスとして進みます。

EC2 Linuxを選択し、次のステップに進みます。

クラスター名は「ecs-nginx」と入力し、オンデマンドを選択します。
EC2インスタンスタイプはDockerfileのサイズに応じて適切に選択してください。 今はnginxをインストールする作業だけなので大容量である必要がなくt2タイプを選択しました。 t2 型は、低コストで汎用インスタンス型です。

VPCは以前の投稿にて作成しておいた「ECSvpc」を選択します。 サブネットはプライベートサブネットを選択し、IP割り当ては無効を選択します。 最後に、セキュリティグループも以前の投稿にて作成した「ecs-container」を選択します。

IAM Roleの場合、「新しいロールを作成」をクリックすると、「ecsinstanceRole」という名前でIAM Roleが自動的に作成されます。

最後に、作成ボタンをクリックしてクラスターの作成を完了します。

EC2ダッシュボードから生成された2つのインスタンスが確認できます。

クラスターの作成が完了したのでダッシュボードからNAT Gatewayを介して生成されたPrivate SubnetのEC2インスタンスも確認できるはずなのですが……できません…。何が問題なのかを確認するためにインスタンスに接続してECS statusを確認したところ、やはりECS agentの起動失敗を繰り返していました。そもそもサービスを開始していない状態でのECSエージェントの起動失敗なので、ECSエージェントとの通信ができていない可能性が高いと思い下記のコマンドで簡単に外部との通信を確認してみました。

[ec2-user@ip-10-0-0-221 ~]$curl http://checkip.amazonaws.com/
curl: (28) Failed to connect to checkip.amazonaws.com port 80 after 300342 ms: Timeout was reached

やはりタイムアウトが発生して通信できていないということが判明したため、NAT gateway、セキュリティグループ、ACL設定を先に確認してみたところ、結果的にセキュリティグループのアウトバウンドルールのポート設定が間違っていました。修正して再度 チェックした結果、

上記のイメージのように、 ECSのクラスターを見ると、NAT Gateway を介して Private Subnet の EC2 インスタンスを問題なく認識していることが確認できました。

タスク定義(Task definition)

続けて、新しいタスク定義を進行する必要があります。簡単に説明するとタスク定義はコンテナの実行方法や起動タイプなどを設定する部分です。今回のタスクは2台のインスタンスをHA構成をすることでロードバランサーを利用する予定です。まず最初に、ロードバランサーを作成することから始めたいと思います。

ALBの作成

まず、EC2→ロードバランサーカテゴリーをクリックし、「ロードバランサーの作成」ボタンをクリックします。

ALBを選択します。

ロードバランサー名を「ecs-alb」として入力します。
VPC は ECSvpc を選択し、Subnet はパブリックサブネットを選択します。

セキュリティグループは「ecs-alb」を選択します。そして、ターゲットグループを生成するために「ターゲットグループの作成」をクリックします。

ターゲットグループ名だけを入力し、ターゲットグループの作成は完了し、クラスタ作成によって生成された2つのEC2インスタンスをターゲットとして追加し、ターゲットグループの作成を終了します。

ALB生成に戻り、先ほど作成したターゲットグループである「ecs-tg」を追加してALB生成を完了します。

タスク定義(Task definition) の作成

再びECSに戻り、「新規ジョブ定義の作成」ボタンをクリックします。

今回は、FargateではなくEC2のみを扱う予定なの起動タイプもEC2を選択します。

タスク名は「ecs-nginx-task」と入力し、ネットワークモードでは「ブリッジ」を選択します。
ネットワークモードには、ブリッジ、ホスト、awsvpc、なしがありますが、今回はLoadBalancerを使用するのでホストとコンテナを別のポートで接続することできる「ブリッジ」を選択します。そして「コンテナの追加」ボタンをクリックします。

コンテナ名を入力して、イメージには以前作成した(Amazon ECSコンテナ #SaaS :イメージをpush!)ECRからImage URLをコピーして貼り付けます。
メモリ制限は256を入力し、ホストポート0、コンテナポート80を入力します。 ホストポートを指定した場合、各ホストでタスクのインスタンス化を1つ以上実行することはできません。 これは、静的ポートマッピングの場合、単一のコンテナポート(80)にマッピングできてしまうからです。例えば、ホストポートを8080にした場合、8080→コンテナポートしかinboundできなくなります。

サービスの作成

次にクラスターに入り、サービスカテゴリで「作成」ボタンをクリックします。

起動タイプはEC2として選択し、サービス名を書き留めます。 サブタイプ Replica は、設定したタスク数の通りタスクを複製して実行して、Deamonタイプは、クラスターに接続されているインスタンスごとに1つのタスクのみを実行します。

ロードバランサーはALBを選択し、「AWSServiceRoleForECS」ロールと先ほど作成したロードバランサーをロードバランサー名から選択します。そしてロードバランス用のコンテナ →「ロードバランサーの追加」ボタンをクリックしてロードバランサーを追加します。 ターゲットグループ名に上記で作成し ターゲットグループ名を選択すると、残りは自動的に入力されます。その後、オートスケーリングは選択せずにそのままサービスの作成を完了します。

作成ボタンを押した後、クラスターの「デプロイメント」タブに入ってみると、上のイメージのようにECS用に作成した2つのprivateインスタンスにECRに保存したインスタンスイメージ(以前の投稿で作成) がデプロイされているのが確認できます。そして最後にロードバランスに入ってdnsをブラウザのアドレスバーに入力すると、以下のように以前の投稿で作成したnginxのテンプレートページが正常に表示されることが確認できました。

まとめ

前回の投稿に続き、SaaS運営開発の一つの方法でコンテナを提示するとともに、コンテナサービスへのアクセシビリティを高めたAmazon EC2 Container Service(Amazon ECS)を一度確認してみました。
ECSコンテナ
作業設定のプロセスを上記のようなアーキテクチャで表現できると思います。 また、コンテナサービスがインスタンスのコストを節約できるというメリットに加え、AWS ECSを使用することで運用上のリソースも節約できるというメリットがあるということも確認できました。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら