既存のECS(Fargate)にALBを追加してみる
ECS(Fargate)でとりあえずタスクを立ち上げて使えるようにしてみたけど、本当はALBを前段に置いてバランシングしたいんだよねぇ。なんてことはありませんか?
ようするに今タスクIP直アクセスして使ってるやつを、こう変えたいみたいなことです。
マネジメントコンソールから変更しようと思うと、一見できなさそうに見えますが、ドキュメントにAWS CLIまたはSDKを使用してロードバランサーの設定変更できる旨が記載されています。
AWS CLI または SDK を使用して、ロードバランサーの設定を変更します。設定の変更方法の詳細については、「Amazon Elastic Containers サービス API リファレンス」の UpdateService を参照してください。
このロードバランサーの設定変更をやってみたので、その手順を紹介します。
とりあえずCLIコマンド
AWS CLIのコマンドさえ教えてもらえばなんとなくわかるよ。ってかたはこちらをどうぞ。
$ CLUSTER=<<ECS(Fargate)のクラスター名>> $ SERVICE=<<ECS(Fargate)のサービス名>> $ TARGET_GROUP_ARN=<<ターゲットグループのARN>> $ CONTAINER_NAME=<<接続したいタスク定義のコンテナ名>> $ aws ecs update-service \ --cluster ${CLUSTER} \ --service ${SERVICE} \ --load-balancers targetGroupArn=${TARGET_GROUP_ARN},containerName=${CONTAINER_NAME},containerPort=80
ここから、もうちょっと詳しく説明します。
現状の説明
Fargateの場合、すべてのECSタスクにENI(Elastic Network Interface)が提供されます。パブリックサブネットを使用する場合には、パブリックIPを割り当てることもでき、とりあえず動かしてみたいなんて時にはこんな風にパブリックIPで直接アクセスすることができます。
ただ、このアクセスの方法ではタスクが増えた時にスケールしていかないので前段にALBを置いて各タスクへバランシングしたい、みたいな状況です。
ALBを作成する
まずは、マネジメントコンソールから、ALBを作成します。
ターゲットグループの作成
ALBの接続先設定となるターゲットグループを作成します。
ターゲットタイプは IPアドレス を選択します。ターゲットグループ名は適当につけます。プロトコルは HTTP の 80 とします。
VPCはFargateを動かしているVPCと同じVPCを選択します。ヘルスチェックは環境に合わせて設定してください。
IPアドレスの設定は不要です。ターゲットグループの作成をしてください。 ECSにALBを設定した時に、自動でタスクのIPアドレスを登録してくれます。
作成したターゲットグループのARNはメモしておいてください。ECSにALBを設定する時に使います。
ALBの作成
ターゲットグループが作成できたらALBを作成します。
ロードバランサー名は適当につけます。スキームを インターネット向け にして、IPアドレスタイプを IPv4 にします。
VPCはFargateを動かしているVPCと同じVPCを選択します。サブネットはパブリックサブネットを指定します。
HTTP接続可能なセキュリティグループをあらかじめ作っておきます。なければ新しいセキュリティグループを作成してください。 リスナーのデフォルトアクションに先程作成したターゲットグループを設定します。
設定できたら概要を確認して、ロードバランサーの作成をしてください。
これでALBの作成は完了です。
ECSサービスのセキュリティグループを更新する
ECSタスクのENIに付与されるセキュリティグループは、ECSサービスで定義されています。 ECSサービスのセキュリティグループを更新して、ALBからアクセスできるようにします。
ECSサービスのセキュリティグループのインバウンドルールを編集して、 ALBに設定したセキュリティグループからHTTPでの接続許可を追加します。
タスク定義のポートマッピングを設定する
タスクのパブリックIPへ直接アクセスしている場合、タスク定義でポートマッピングを設定しなくてもセキュリティグループで許可されていれば接続できます。 ECSにALBを設定する場合は、タスク定義でポートマッピングの設定が必要です。
ちなみに、タスク定義のポートマッピングを設定せずにALBを設定しようとすると、次のようなポートが定義されていませんといったエラーが発生します。
An error occurred (InvalidParameterException) when calling the UpdateService operation: The container web did not have a container port 80 defined.
タスク定義から新しいリビジョンを作成して、ポートマッピングの設定をします。
コンテナのポートに80(HTTP)を追加して保存します。
ECSサービスの更新
タスク定義を新しくしたので、ECSサービスを更新して最新のタスク定義のタスクが実行されるよう、ECSサービスを更新します。
タスク定義のリビジョンを最新にして更新します。
そうすると、最新のタスクが起動してきます。
AWS CLIでECSのALB設定を更新する
ここまで準備ができれば、次のコマンドを実行するとALB設定を更新できます。
$ CLUSTER=<<ECS(Fargate)のクラスター名>> $ SERVICE=<<ECS(Fargate)のサービス名>> $ TARGET_GROUP_ARN=<<作成したターゲットグループのARN>> $ CONTAINER_NAME=<<タスク定義のコンテナ名>> $ aws ecs update-service \ --cluster ${CLUSTER} \ --service ${SERVICE} \ --load-balancers targetGroupArn=${TARGET_GROUP_ARN},containerName=${CONTAINER_NAME},containerPort=80
実行後、マネジメントコンソールを確認するとECSにALBが登録されていることが確認できます。
ALBのDNS名でもアクセスして、問題なく表示できることも確認できました。
おわりに
マネジメントコンソールからECSのALB追加ができないので、後から変更できないように見えるのですが、AWS CLIを利用することで後から変更することもできます。 ECSクラスター作り直すより早くできると思うので、ぜひご活用ください。