Help us understand the problem. What is going on with this article?

ecs-cli でECSのサービスディスカバリを行う

More than 1 year has passed since last update.

はじめに

案件でEC2で運用していたサービスのコンテナ化と同時に、Route53のAuto Namingを使用したECSのディスカバリを行ったのでその時の手順を書きます。

動作環境

  • ecs-cli v1.12.0
  • docker-compose

対応イメージ

プライベートサブネット内で稼働しているCLB+EC2の構成を、
ECSサービスディスカバリーを利用したアクセスに変更します。
対応の概念などは
ECSのサービスディスカバリーが東京にやってきて、コンテナ間通信の実装が簡単になりました!
を参考にさせていただきました。

  • 対応前
    スクリーンショット 2018-12-03 6.22.27.png
  • 対応後
    スクリーンショット 2018-12-03 6.23.24.png

手順

公式ドキュメントにチュートリアルがあったので、ほぼその通りに行いました。特別なことはしていません。
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です。

docker-compose.common.yml
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です

docker-compose.dev.yml
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用のパラメーターの設定ファイルを用意します。

ecs-params-dev.yml
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.

スクリーンショット 2018-12-03 5.42.41.png

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 でアクセスできるようになります。

スクリーンショット 2018-12-03 5.51.04.png

DNSにはこのように設定されています。

スクリーンショット 2018-12-03 5.52.20.png

いい感じですね。

ためしにアクセスしてみます。
アプリケーションからは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

スケールされました。

スクリーンショット 2018-12-03 5.56.59.png

DNSも確認してみます。

スクリーンショット 2018-12-03 5.57.36.png

ちゃんとレコードが増えていますね。

サービスの更新

サービスの更新はこれまでの使い方とほとんど変わりませんが、 --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あたりもどんどん触っていこうと思います。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away