エブリデイ試した系ですいません。かっぱです。
tl;dr
inokara.hateblo.jp
の続き。
AWS CLI で ALB を作成して ECS の Service を作成して ALB と組み合わせてみる。尚、ALB を操作するには elbv2 というサブコマンドを利用する。
メモ
ちょっとウンチク
ここまで試してきて Amazon ECS と AWS Application Load Balancer は以下のような構成になっていると理解。
- Listner で ALB がインターネットからの接続を何番ポートで Listen するか定義する
- Path Pattern 毎に Target Group を定義する
- Target Group には EC2 インスタンスやコンテナをぶら下げることが出来る(バックエンドへのルーティングやヘルスチェックについて定義する)
ALB の詳細については以下の Blog 記事はドキュメントと並んでとても参考になる。
dev.classmethod.jp
また、ALB についての制限事項については以下のドキュメントには目を通しておきたい。
docs.aws.amazon.com
試した環境
Amazon ECS や AWS Application Load Balancer を操作する環境としては…
% sw_vers ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G24b % aws --version aws-cli/1.10.56 Python/2.7.6 Darwin/15.6.0 botocore/1.4.46
ECS については…
- クラスタ作成済み(コンテナインスタンスは 2 台)
- Task Definition は ecscompose-ecs-app:22 を利用
- Container Name は app とする
- コンテナアプリケーションはコンテナ内で Port 4567 で Listen する
- Task は
/hostname
という URL にアクセスするとコンテナのホスト名を返す
ざっくり流れ
- ALB ロードバランサの作成
- ALB ターゲットグループの作成
- ALB リスナーの作成
- ALB ターゲットグループを指定して ECS Service を作成
ALB の作成
- alb.json
% cat alb.json { "Name": "alb-demo", "Subnets": [ "subnet-12345678", "subnet-abcdefgh" ], "SecurityGroups": [ "sg-12345678" ] }
- run
% ELB_ARN=$(aws --debug \ elbv2 create-load-balancer \ --cli-input-json file://alb.json | jq -r '.LoadBalancers[].LoadBalancerArn')
- 確認
% aws \ elbv2 describe-load-balancers
- 念のため削除(消す必要が無ければ叩かない)
% aws \ elbv2 delete-load-balancer \ --load-balancer-arn ${ELB_ARN}
ターゲットグループ作成
- target-group.json
% cat target-group.json { "Name": "default", "Protocol": "HTTP", "Port": 80, "VpcId": "vpc-xxxxxxxx", "HealthCheckPath": "/hostname", "HealthCheckIntervalSeconds": 30, "HealthCheckTimeoutSeconds": 15, "HealthyThresholdCount": 3, "UnhealthyThresholdCount": 3, "Matcher": { "HttpCode": "200" } }
以下のように HealthCheckPort
を指定しない場合には traffic-port
という値が入る。Amazon ECS のコンテナをぶら下げる場合には Docker から払いだされたポートに対するヘルスチェックとなるので HealthCheckPort
は指定しない。
% aws elbv2 describe-target-groups { "TargetGroups": [ { "HealthCheckPath": "/hostname", "HealthCheckIntervalSeconds": 30, "VpcId": "vpc-xxxxxxxxx", "Protocol": "HTTP", "HealthCheckTimeoutSeconds": 15, "HealthCheckProtocol": "HTTP", "LoadBalancerArns": [ "arn:aws:elasticloadbalancing:ap-northeast-1:1234567890123:loadbalancer/app/alb-demo/1234567890123456" ], "UnhealthyThresholdCount": 3, "HealthyThresholdCount": 3, "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:1234567890123:targetgroup/default/1234567890123456", "Matcher": { "HttpCode": "200" }, "HealthCheckPort": "traffic-port", "Port": 80, "TargetGroupName": "default" } ] }
- run
% TARGET_GROUP=$(aws --debug \ elbv2 create-target-group \ --cli-input-json file://target-group.json | jq -r '.TargetGroups[].TargetGroupArn'
- 確認
% echo ${TARGET_GROUP}
リスナーの作成
- run
% aws \ elbv2 create-listener \ --load-balancer-arn ${ELB_ARN} \ --protocol HTTP \ --port 80 \ --default-actions Type=forward,TargetGroupArn=${TARGET_GROUP}
ECS Service の作成
- ecs-simple-service-elb.json
% cat ecs-simple-service-elb.json { "serviceName": "ecs-simple-service-elb", "taskDefinition": "ecscompose-ecs-app:22", "loadBalancers": [ { "targetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:targetgroup/default/zzzzzzzzzzzzzzzz", "containerName": "app", "containerPort": 4567 } ], "desiredCount": 2, "role": "ecsServiceRole" }
- run
aws \ ecs create-service \ --cluster ecs-demo \ --service-name ecs-simple-service-elb \ --cli-input-json file://ecs-simple-service-elb.json
ここまでで…
- ALB とリスナー
- ターゲットグループ(ヘルスチェックが適切では無かったので `unhealthy` → `draining` を繰り返している… )
- ECS Service
確認
- run
% URL=$(aws \ elbv2 describe-load-balancers \ --query 'LoadBalancers[].DNSName' \ --output text) % echo ${URL} % curl ${URL} % curl ${URL}/hostname
- output
% curl ${URL}/hostname e80f74a9026f% % curl ${URL}/hostname af8647af702e% % curl ${URL}/hostname 5963b959e447%
その他メモ
ecs-cli で ECS クラスタ作成
--subnets
や --azs
等の複数指定出来るパラメータの値はカンマで区切ること。スペースでは無いので注意。(aws cli はスペースで区切るという違いがある。)
% ecs-cli up \ --keypair ${KEY_NAME} \ --capability-iam \ --size 1 \ --vpc vpc-xxxxxxxx \ --instance-type t2.micro \ --subnets subnet-xxxxxxxx,subnet-zzzzzzzz \ --azs ap-northeast-1a,ap-northeast-1c \ --security-group sg-xxxxxxxx
ecs-agent が止まるとどうなるのか
ALB と ECS を連携させた状態で ecs-agent を止めてみると…
- 起動している Task(コンテナ)は維持される
- ALB にぶら下がっている Task(コンテナ)にも正常にアクセス出来る
更にこの状態で一つの Task を Stop Container してみると…
- ALB のヘルスチェックが失敗して停止したコンテナは
unhealthy
→draining
に状態が変化する(ALB から切り離される) draining
に遷移したタイミングで Running tasks count が 1 つ減る
ここで疑問、ecs-agent
が動いていない状態でもクラスタの状態は何らかの方法で管理されている?
元記事はこちら
「Amazon ECS と AWS Application Load Balancer の組み合わせを試しているメモ(2)〜 AWS CLI で試す 〜」