はじめに
案件でEC2で運用していたサービスのコンテナ化と同時に、Route53のAuto Namingを使用したECSのディスカバリを行ったのでその時の手順を書きます。
動作環境
- ecs-cli v1.12.0
- docker-compose
対応イメージ
プライベートサブネット内で稼働しているCLB+EC2の構成を、
ECSサービスディスカバリーを利用したアクセスに変更します。
対応の概念などは
ECSのサービスディスカバリーが東京にやってきて、コンテナ間通信の実装が簡単になりました!
を参考にさせていただきました。
手順
公式ドキュメントにチュートリアルがあったので、ほぼその通りに行いました。特別なことはしていません。
Tutorial: Creating an Amazon ECS Service That Uses Service Discovery Using the Amazon ECS CLI
ecs-cliのgithubのREADMEにも同様のことが書かれています。
using-route53-service-discovery
ECSのタスクの準備
アプリケーションはnginx+javaアプリというよくある構成です。
ecs-cli
を使用するのでdocker-composeの形式で記述します。
まずは基本となる共通のyamlです。
version: '3'
services:
sample-api-app:
image: 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/sample-api-app:latest
user: quartette
ulimits:
nproc: 65536
nofile:
soft: 65536
hard: 65536
environment:
- JAVA_OPTS=-Xms1024m -Xmx2048m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -Duser.country=JP -Duser.language=ja -Duser.timezone=Asia/Tokyo -Djava.awt.headless=true -XX:-OmitStackTraceInFastThrow
command:
/bin/sh -c
"java -jar -Dspring.profiles.active=$$APP_ENV /var/app/quartette/app.jar"
sample-api-nginx:
image: 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/sample-api-nginx:latest
ulimits:
nproc: 65536
nofile:
soft: 65536
hard: 65536
command:
/bin/sh -c
"nginx -g 'daemon off;'"
ports:
- "80:80"
次に環境ごとの設定を記述するyamlです
version: '3'
services:
sample-api-app:
environment:
- APP_ENV=dev
labels:
- Env=dev
logging:
driver: awslogs
options:
awslogs-group: "quartette-app"
awslogs-region: "ap-northeast-1"
awslogs-stream-prefix: "dev"
sample-api-nginx:
environment:
- APP_ENV=dev
labels:
- Env=dev
logging:
driver: awslogs
options:
awslogs-group: "quartette-nginx"
awslogs-region: "ap-northeast-1"
awslogs-stream-prefix: "dev"
最後にECS用のパラメーターの設定ファイルを用意します。
version: 1
task_definition:
ecs_network_mode: awsvpc
# Amazon ECS タスク実行 IAM ロール
# https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_execution_IAM_role.html
task_execution_role: ecsTaskExecutionRole
task_size:
cpu_limit: 2048
mem_limit: 4096
services:
sample-api-app:
cpu_shares: 2048
mem_limit: 3GB
mem_reservation: 3GB
essential: true
sample-api-nginx:
mem_limit: 128M
mem_reservation: 128M
run_params:
network_configuration:
awsvpc_configuration:
subnets:
# private subnet
- subnet-xxxxxxxx
- subnet-zzzzzzzz
security_groups:
- sg-yyyyyyyy
assign_public_ip: DISABLED
ECSクラスターの作成(まだ作っていない場合)
ECSクラスターを作成していない場合はまず作成します。
% ecs-cli up --cluster quartette-cluster --vpc vpc-aaaaaaaa --subnets subnet-xxxxxxxx,subnet-zzzzzzzz --security-group sg-yyyyyyyy --launch-type FARGATE --region ap-northeast-1 --ecs-profile quartette
INFO[0005] Created cluster cluster=quartette-cluster region=ap-northeast-1
INFO[0006] Waiting for your cluster resources to be created...
INFO[0006] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
Cluster creation succeeded.
Service Discoveryを使ったECS Serviceの作成
下記のパラメーターが必要になります。
-
--private-dns-namespace
:プライベートDNSで設定されるドメインのネームスペース -
--enable-service-discovery
:ECSのサービスディスカバリを有効にするオプション
% ecs-cli compose --project-name dev -f compose/docker-compose.common.yml -f compose/docker-compose.dev.yml --ecs-params compose/ecs-params/ecs-params-dev.yml --cluster quartette-cluster service up --private-dns-namespace quartette.com --vpc vpc-aaaaaaaa --create-log-groups --launch-type FARGATE --enable-service-discovery
INFO[0000] Using ECS task definition TaskDefinition="dev:2"
WARN[0000] Failed to create log group quartette-app in ap-northeast-1: The specified log group already exists
WARN[0000] Failed to create log group quartette-app in ap-northeast-1: The specified log group already exists
INFO[0006] Waiting for the private DNS namespace to be created...
INFO[0006] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
INFO[0066] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
WARN[0102] Defaulting DNS Type to A because network mode was awsvpc
INFO[0102] Waiting for the Service Discovery Service to be created...
INFO[0102] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
INFO[0134] Created an ECS service service=dev taskDefinition="dev:2"
INFO[0134] Updated ECS service successfully desiredCount=1 serviceName=dev
INFO[0149] (service dev) has started 1 tasks: (task 66666666-cccc-ffff-b000-bbbbbbbbbbbb). timestamp="2018-12-02 20:50:00 +0000 UTC"
INFO[0211] Service status desiredCount=1 runningCount=1 serviceName=dev
INFO[0211] (service dev) has reached a steady state. timestamp="2018-12-02 20:50:57 +0000 UTC"
INFO[0211] ECS Service has reached a stable state desiredCount=1 runningCount=1 serviceName=dev
作成するとこのような感じにサービスの検出の項目が設定されます。
この設定では、VPC内からは dev.quartette.com
でアクセスできるようになります。
DNSにはこのように設定されています。
いい感じですね。
ためしにアクセスしてみます。
アプリケーションからはjsonが返ってくる想定です。
$ curl http://dev.quartette.com/api/
{"message":null,"result": …
タスクのスケール
次にタスクをスケールしてみます。
% ecs-cli compose --verbose --project-name dev -f compose/docker-compose.common.yml -f compose/docker-compose.dev.yml --ecs-params compose/ecs-params/ecs-params-dev.yml --cluster quartette-cluster service scale 4
DEBU[0000] Parsing the compose yaml...
DEBU[0000] Docker Compose version found: 3
DEBU[0000] Docker Compose version found: 3
DEBU[0000] Parsing v3 project...
DEBU[0000] Parsing the ecs-params yaml...
DEBU[0000] Parsing the ecs-registry-creds yaml...
DEBU[0000] Transforming yaml to task definition...
DEBU[0000] Updated ECS service count=4 service=dev
INFO[0000] Updated ECS service successfully desiredCount=4 serviceName=dev
INFO[0001] Service status desiredCount=4 runningCount=1 serviceName=dev
INFO[0016] (service dev) has started 3 tasks: (task 11111111-1111-1111-1111-111111111111) (task 22222222-2222-2222-2222-222222222222) (task 33333333-3333-3333-3333-333333333333). timestamp="2018-12-02 20:55:28 +0000 UTC"
INFO[0061] Service status desiredCount=4 runningCount=2 serviceName=dev
INFO[0076] Service status desiredCount=4 runningCount=4 serviceName=dev
INFO[0076] ECS Service has reached a stable state desiredCount=4 runningCount=4 serviceName=dev
スケールされました。
DNSも確認してみます。
ちゃんとレコードが増えていますね。
サービスの更新
サービスの更新はこれまでの使い方とほとんど変わりませんが、 --private-dns-namespace
パラメーターが増えています。
ecs-cli compose --project-name dev -f compose/docker-compose.common.yml -f compose/docker-compose.dev.yml --ecs-params compose/ecs-params/ecs-params-dev.yml --cluster quartette-cluster service up --private-dns-namespace quartette.com --vpc vpc-aaaaaaaa --create-log-groups --launch-type FARGATE --deployment-max-percent 200 --deployment-min-healthy-percent 50 --healthcheck-custom-config-failure-threshold 2
サービスの削除
最後にサービスを削除します。private dnsの設定も削除するには、 --delete-namespace
を追加してあげる必要があります。
このパラメーターを追加せずに手動でRoute53から削除しようとするとエラーになります。
% ecs-cli compose --project-name dev -f compose/docker-compose.common.yml -f compose/docker-compose.dev.yml --cluster quartette-cluster service rm --delete-namespace
INFO[0000] Updated ECS service successfully desiredCount=0 serviceName=dev
INFO[0000] Service status desiredCount=0 runningCount=1 serviceName=dev
INFO[0015] Service status desiredCount=0 runningCount=0 serviceName=dev
INFO[0015] (service dev) has stopped 1 running tasks: (task 11111111-1111-1111-1111-1111111111111). timestamp="2018-12-02 21:07:00 +0000 UTC"
INFO[0015] ECS Service has reached a stable state desiredCount=0 runningCount=0 serviceName=dev
INFO[0015] Deleted ECS service service=dev
INFO[0015] ECS Service has reached a stable state desiredCount=0 runningCount=0 serviceName=dev
INFO[0015] Trying to delete any Service Discovery Resources that were created by the ECS CLI...
INFO[0016] Waiting for your Service Discovery Service resource to be deleted...
INFO[0016] Cloudformation stack status stackStatus=DELETE_IN_PROGRESS
INFO[0047] Waiting for your Private DNS Namespace resource to be deleted...
INFO[0047] Cloudformation stack status stackStatus=DELETE_IN_PROGRESS
INFO[0107] Cloudformation stack status stackStatus=DELETE_IN_PROGRESS
最後に
ECSの運用を始めてから1年半ほどになりますが、Fargateの登場以降どんどん便利になっていきますね。
現状はECS Fargateばかりで運用していますが、世の中的にはkubernetesの事例のほうが圧倒的に多いのでEKSあたりもどんどん触っていこうと思います。