0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECSクラスターにコンテナアプリをデプロイする

Posted at

はじめに

この記事では、ECSクラスターにコンテナアプリをデプロイする手順を紹介します。

全体構成図

image.png

検証に使用したAWS環境では、VPC内のパブリックサブネットに踏み台サーバーが用意されていました。
同じVPC内に新たにプライベートサブネットを作成し、さらにその中にECSクラスターとALBを作成することで踏み台サーバーからコンテナアプリにアクセス出来るようにします。

踏み台サーバーからALBのリスナーにリクエストがいき、パスによってターゲットグループが振り分けられ、適切なサービスに接続されコンテナアプリにアクセスします。

ECRリポジトリの作成・イメージのpush

まずはコンテナイメージを格納するためのECRリポジトリを作成します。

リポジトリ構成

ECRにはOpenShiftでいうところの名前空間のような概念はないようです。
ただし、リポジトリを作成する際に/で区切ることで擬似的に名前空間のような使い方をすることは可能です。

また、ECRの管理画面では「リポジトリを作成」となっていますが、実際は「リポジトリ+イメージ名」の組み合わせで管理されるため、リポジトリ名の設計がそのままイメージの分類にも影響します。

例えばリポジトリ作成時、リポジトリ名に「nodejs」とだけ指定するとイメージ名として扱われます。
「myrepo/nodejs」と指定すると、myrepoをリポジトリ名、nodejsをイメージ名としてリポジトリを作成出来ます。

OpenShiftの感覚だとnamespaceごとにリポジトリがあって、そこにいろいろな名前のイメージを追加していく形なので、ECRを使い始めたときは設計思想の違いにちょっと混乱しました。

最終的には下記の名称でリポジトリを作成しました。

環境 リポジトリ+イメージ名
開発 app-dev/myjava
検証 app-test/myjava
ステージング・本番 app-release/myjava

イメージのpush

リポジトリが出来たらイメージをpushします。
「プッシュコマンドを表示」で必要なコマンドを表示できます。
コマンドはdockerベースなのでpodmanを使っている場合は修正する必要があります。
また、MFA認証をしているため、--profileでAWSプロファイルを指定しています。

# ECRリポジトリへのログイン
$ aws ecr get-login-password --region us-east-1 --profile mfa-user| podman login --username AWS --password-stdin <AWSアカウント名>.dkr.ecr.us-east-1.amazonaws.com 

# イメージのビルド
$ podman build -t app-dev/myjava .

# タグ付け
$ podman tag app-dev/myjava:latest <AWSアカウント名>.dkr.ecr.us-east-1.amazonaws.com/app-dev/myjava:latest

# プッシュ
$ podman push <AWSアカウント名>.dkr.ecr.us-east-1.amazonaws.com/app-dev/myjava:latest

ECSクラスターの作成

アプリをデプロイするECSクラスターを作成します。

設定項目
クラスター名 任意の名前を入力
インフラストラクチャ AWS Fargate(サーバーレス)

ALBの作成

アプリアクセスのためのエンドポイントを作成するため、ALBを作成します。

ALBの作成時には他のAWSリソースを指定する必要があります。
これらのリソースはALBの作成時に同時に作成出来るのですが、個別に作成した場合と比べて設定できる項目が限られているものもあります。

ですのでALBを作成する前にあらかじめ必要なリソースを作成しておき、ALB時に作成したリソースを指定する、という形で作った方が安心です。

1. サブネットの作成

検証環境VPC内に、ALB用のサブネットを作成します。
ALB用には最低2つのサブネットが必要でした。

設定項目
VPC ID ALBを作成するVPCを指定
サブネット名 任意の名前を入力
アベイラビリティーゾーン 任意のAZを選択
IPv4 VPC CIDRブロック 任意のCIDRブロックを入力

2. セキュリティグループの作成

ALBにアタッチするセキュリティグループを作成します。
踏み台サーバーからALBのHTTPリスナー(80番ポート)への通信を許可します。
インバウンドルールに下記を追加します。

設定項目
タイプ カスタムTCP
プロトコル TCP
ポート範囲 HTTPリスナーの80番ポート
ソース 踏み台サーバーのあるVPCのセキュリティグループ

3. ターゲットグループの作成

ターゲットグループとはALBがリクエストを受けたあと、トラフィックを振り分ける先(ターゲット)の集合です。
ターゲットの種類にはIP、EC2インスタンス、Lambdaなどがあります。

今回はIPを使用します。
ECSクラスターとALBが連携している場合、サービス定義にターゲットグループを指定することで、ECSクラスターがサービスに任意のIPを自動で割り当ててくれます。
そのためユーザーが手動でIPアドレスを指定する必要はありません。

設定項目
ターゲットタイプの選択 IP
ターゲットグループ名 任意の名前を入力
プロトコル HTTP or HTTPS
ポート アプリケーションの公開ポート
VPC ECSクラスターを作成するVPCを指定

4. ALBの作成

アプリを外部公開するため、ALBを作成します。

EC2 > ロードバランサー > ロードバランサーの作成 > Application Load Balancerを作成 の順にクリックします。

下記の項目を設定しました。他はすべてデフォルト値 or 設定なしのままです。

基本的な設定

設定項目
ロードバランサー名 任意の名前を入力
スキーム 内部

ネットワークマッピング

設定項目
VPC ECSクラスターを構築するVPCを指定
アベイラビリティーゾーンとサブネット 作成したサブネットを指定
セキュリティグループ 作成したALB用のセキュリティグループを指定

リスナーとルーティング

ALB作成時に指定できるリスナーはルートパス(/)へのリクエストのみです。
/java/nodejsの振り分けルールは、ALB作成後に行います。

設定項目
プロトコル HTTP
ポート 80
デフォルトアクション 作成したターゲットグループのうち片方を指定

ここまで設定できたらALBを作成します。

5. リスナールール

ALBが作成できたら、リスナールールを追加します。
構成図のこの部分ですね。
image.png

ALB > リスナーとルール > リスナーの追加 をクリックします。

設定項目
プロトコル HTTP
ポート アプリのリッスンポート

続いて個別のルールを追加します。
リスナー > リスナールール > ルールを追加する をクリックします。
ここではJavaアプリ用、Nodejsアプリ用のルールをそれぞれ追加します。

条件

設定項目
パス Javaアプリ用:/java
Nodejsアプリ用:/nodejs

アクション

設定項目
アクションのルーティング ターゲットグループへ転送
ターゲットグループ Javaアプリ用、Nodejsアプリ用のターゲットグループからそれぞれ選択

コンテナアプリの作成

ECSクラスターにコンテナアプリをデプロイします。

1. セキュリティグループの作成

ECSクラスター用のセキュリティグループを作成します。
ALBからECSクラスター上のコンテナアプリへの通信を許可します。

設定項目
タイプ カスタムTCP
プロトコル TCP
ポート範囲 8080
ソース ALBのセキュリティグループ

1. タスク定義の作成

タスク定義とは、ECSクラスターで動かすタスクの設定内容を記述したテンプレートです。
OpenShiftで言うとタスクがPod、タスク定義がDeployment内のPodSpecに相当します。

設定項目
タスク定義ファミリー 任意の名前を入力
機動タイプ ECS Fargate
コンテナの詳細 > 名前 任意の名前を入力
イメージURI イメージURIを指定
コンテナポート アプリケーションの公開ポート
プロトコル TCP
ポート名 任意の名前を入力
アプリケーションプロトコル HTTP or HTTPS

2. サービスの作成

サービスは指定した数のタスクを稼働させ続ける仕組みです。ALBと連携してトラフィックを分散することもできます。
OpenShiftで言うとReplicaSetとServiceの機能を合わせたものに近いです。

設定項目
タスク定義ファミリー 作成したタスク定義を作成
サービス名 任意のサービス名を入力
VPC ECSクラスターを構築したVPCを指定
サブネット 作成したサブネットをすべて指定
セキュリティグループ 既存のセキュリティグループを使用
セキュリティグループ名 作成したECSクラスター用セキュリティグループを指定
ロードバランシングを使用 ✅️
ロードバランサーの種類 Application Load Balancer
コンテナ 作成したタスク定義を指定
Application Load Balancer 既存のロードバランサーを使用
ロードバランサー 作成したロードバランサーを指定
リスナー 既存のリスナーを使用
タスク定義で作成したリスナーを指定
ターゲットグループ 既存のターゲットグループを使用
ターゲットグループ名 作成したターゲットグループを指定

アプリの起動確認

これでようやくアプリの作成が完了しました。
アプリの状況はサービスからタスク一覧に表示されたタスクをクリックすることで確認できます。
ステータスが「実行中」となるまで待機します。

image.png

ログタブからログの確認もできます。
より詳しく見たい場合はCloudWatchのダッシュボードのほうが見やすいです。
image.png

アプリへのアクセス

今回はアプリを外部公開していないため、同じVPC内にある踏み台サーバー経由でアプリにアクセスしてみます。
アプリへのアクセスにはALBのDNS名を使用します。ALBのページから確認できます。

# Javaアプリ
$ curl <ALB DNS名>/java

# Node.jsアプリ
$ curl <ALB DNS名>/nodejs

ローカルからアクセスしたい場合はトンネルを張ります。

# ローカルにて
$ ssh -i <鍵ファイル> -L 80:<ALB DNS名> <踏み台ユーザー名>:<踏み台IPアドレス>

ローカルのブラウザよりlocalhost/nodejsにアクセスします。
image.png

無事にアプリが表示できました!

おわりに

ネットワーク周りの知識がないため、特にALB関連のリソース作成や設定に苦労しました。
今回はECSクラスターへコンテナアプリのデプロイを行いましたが、別途CodePipelineによるCI/CD化も行いました。
こちらも別途記事にする予定です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?