概要
ECS と ALB を連携してコンテナアプリケーションのスケールアウトを行ってみました
ECS にはホスト側のポートを動的に決定する仕組みがあり、その動的に割り振れたポートを ALB に接続することでスケールアウトを実現します
環境
- CentOS 7.3
- docker 17.03
- ruby 2.3.3
- gem 2.6.11
- aws cli 1.11.71
- ECS, ALB (2017/04/05 時点)
ECS の作成
前回 チュートリアルから基本的なコンポーネントを作成しました
今回もその方法で作成していきます
基本的な流れは同じなのでポイントだけ紹介します
「Amazon ECS クラスターにサンプルアプリケーションをデプロイする」「Amazon ECR によりコンテナイメージをセキュアに保存する 」には両方チェックして次に進みます
レジストリですが今回はアプリケーションをスケールさせたときにどのコンテナにリクエストが行っているかちゃんと確認するために独自のコンテナアプリを作成します
ついでに作成したレジストリにイメージを push します
独自アプリは sinatra を使っています
- aws ecr get-login –region ap-southeast-2
- docker login コマンドが表示されたらそのままそれを使ってログインする
- bundle init
- vim Gemfile
gem "sinatra"
- vim app.rb
require 'sinatra'
set :bind, '0.0.0.0'
get '/host' do
`hostname`
end
- vim Dockerfile
FROM ruby:latest
ADD . /work
WORKDIR /work
RUN bundle install
CMD ["bundle", "exec", "ruby", "app.rb"]
- docker build -t simple-sinatra-app .
- docker tag simple-sinatra-app:latest 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com/simple-sinatra-app:latest
- docker push 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com/simple-sinatra-app:latest
で OK です
ECS の作成画面はイメージを push したあとで次に進んでください
次にタスクの設定ですが、ここの「ポートマッピング」の設定でホストポートを 0, コンテナポートを 4567 にします
ホストポートを 0 にすることでホスト側のポートを動的に決定することができます
サービスはとりあえずデフォルトのままで OK です
あとで ALB を作成したあとで新しいサービスを作成します
クラスタの設定もそのままで OK です
SSH などは必要に応じて作成してください
あとは確認し問題なければ作成を開始してください
EC2 コンテナホストが所属する VPC ID を確認する
チュートリアル方式で ECS を作成すると EC2 コンテナホストの設定も自動で行われます
ALB を作成する際にどの VPC 配下にいるコンテナを組み込むかという設定が必要になります
なので、ECS が作成できたら EC2 コンテナホストが所属する VPC を確認してください
クラスタ -> デフォルト -> ECS インスタンス -> インスタンスを選択 -> 画面が飛んだら EC2 の画面で VPC ID を確認
EC2 コンテナホストが所属するセキュリティグループの設定を確認する
チュートリアルで作成した場合セキュリティグループも設定を確認したほうがいいと思います
おそらくデフォルトだとインバウンドの設定が以下になっていると思います
- プロトコル -> TCP
- ポート範囲 -> 0
- 送信元 -> 0.0.0.0/0
これだと動的に割り振れれたポートにアクセスできないのでポートの範囲を以下のように変更します
- ポート範囲 -> 0 - 65535
送信元などは必要に合わせて変更してください
ALB の作成
次に ALB を作成します
EC2 の管理画面画から作成します
ロードバランサーを選択し「ロードバランサーの作成」を選択します
次にロードバランサーのタイプを選択する画面になると思います
ここでは必ず「Application Load Balancer」を選択します
次に ALB の設定です
名前など設定します
ALB が LISTEN するポートは 80 にしています
その下で VPC の設定をします
ここで先程確認した VPC ID を必ず選択するようにしてください
ここが間違うとスケールしたコンテナがうまく ALB にぶら下がってくれません
サブネットを 2 つ以上選択したら次に進みます
セキュリティの設定はとりあえずスルーします
セキュリティグループの設定は今回は default を選択します
アクセス元など絞りたい場合は独自のセキュリティグループを適宜設定してください
ターゲットグループの作成です
新しく ECS のコンテナを管理するターゲットグループを作成しましょう
ポートはアプリが LISTEN する 4567 にしヘルスチェックのパスを今回のアプリが動作する「/host」に変更します
ターゲットの登録は何もしません
すでに ECS コンテナインスタンスが割り当てられていることが確認できると思います
あとは作成すれば OK です
ALB が所属するセキュリティグループの設定を確認する
今回 default を選択しましたがおそらく外部からアクセスできない設定になっていると思います
ALB は 80 番ポートで LISTEN する設定にしているので 80 番ポートでアクセスできる設定を入れてあげましょう
サービスを作成し直す
チュートリアルで作成したサービスを削除し先程作成した ALB を使用するサービスを作成します
クラスタを選択しサービスタブから既存のサービスを削除します
エラーが出て削除できない場合はタスク数が 1 以上になっていると思うので 0 にしてから削除します
削除できたら新規でサービスを作成していきます
サービス名を決定しタスクの数を設定します
タスクの数はとりあえず 1 にしておきましょう (あとからここの数を変更してスケールアウトさせてみます)
ELB の選択で「Application Load Balancer」を選択します
そしてタスクを追加したら以下のように設定します
ターゲットグループは先程作成したターゲットグループを選択しましょう
これで保存しサービスを作成します
動作確認
これでコンテナが ALB にぶら下がり ALB 経由でアプリにアクセスできるようになります
EC2 のロードバランサーのターゲットグループのターゲットタグを確認するとコンテナが「healthy」の状態でぶら下がっているのが確認できると思います
この状態で ALB にデフォルトで振られているドメインにアクセスしてみましょう
http://albforecs-1234567890.ap-southeast-2.elb.amazonaws.com/host
(URL はダミーです)
するとコンテナのホスト名が表示できると思います
何度かアクセスしてみて表示されているホスト名が変わらないことを確認してください
コンテナをスケールアウトさせてみる
では、スケールアウトさせてみます
先程作成したサービスのタスクの数を 1 -> 3 くらいまで増やしてみましょう (5 にしても 3 までしか増えなかったのでとりあえず 3 にしました)
これで再度 ALB にアクセスするとホスト名がちょくちょく変わるのが確認できると思います
ALB のターゲットグループを見ると healthy なターゲットが 3 つに増えていることも確認できると思います
最後に
ECS + ALB で web アプリコンテナをスケールアウトしてみました
やってることは単純なのですが概念を理解したり VPC やセキュリティグループまで絡んでくるので結構ハマりポイントが多かったです
ステートレスな Web アプリならこれで単純にスケールアウトできそうです
セッションなどを管理する必要がありアプリがステートフルな場合は、アプリ側でもう少し頑張る必要があるかなと思います
Tips
作成した ECS のリソースでクラスタを削除しようとするとエラーになると思います
その場合は
alb 削除 -> ターゲットグループ削除 -> VPC (インターネットゲートウェイ) -> 使っていた VPC からインターネットゲートウェイをデタッチ
としてからクラスタを削除してみてください
0 件のコメント:
コメントを投稿