warning
この記事は2年以上前に更新されたものです。情報が古くなっている可能性があります。

Cloud Native BuildpacksでビルドしたOCIイメージ(making/hello-cnb)をAWS Fargateにデプロイします。

目次

CLIのインストール

brew install awscli
brew install amazon-ecs-cli

IAM ロールの作成

export AWS_ACCESS_KEY_ID=****
export AWS_SECRET_ACCESS_KEY=****
cat <<'EOF' > task-execution-assume-role.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

aws iam --region ap-northeast-1 create-role --role-name ecsTaskExecutionRole --assume-role-policy-document file://task-execution-assume-role.json
aws iam --region ap-northeast-1 attach-role-policy --role-name ecsTaskExecutionRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

ECSクラスタの作成

ecs-cli configure \
  --cluster hello-cnb \
  --config-name hello-cnb \
  --default-launch-type FARGATE \
  --region ap-northeast-1

ecs-cli up
INFO[0001] Created cluster                               cluster=hello-cnb region=ap-northeast-1
INFO[0001] Waiting for your cluster resources to be created... 
INFO[0002] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
INFO[0062] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
VPC created: vpc-0c917aa72745f9cb6
Subnet created: subnet-0530ccfcfe68c28ef
Subnet created: subnet-0f153ee20359f90ef
Cluster creation succeeded.

出力結果に含まれるVPC IDと二つのSubnet IDを次のように変数に設定します。

export VPC_ID=vpc-0c917aa72745f9cb6
export SUBNET_ID_1=subnet-0530ccfcfe68c28ef
export SUBNET_ID_2=subnet-0f153ee20359f90ef

デフォルトのセキュリティグループルールを追加し、8080ポートでインバウンドアクセスを許可します。

export SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \
  --filters Name=vpc-id,Values=${VPC_ID} \
  --region ap-northeast-1 | \
  jq -r ".SecurityGroups[0].GroupId")

aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} \
  --protocol tcp \
  --port 8080 \
  --cidr 0.0.0.0/0 \
  --region ap-northeast-1

アプリケーションのデプロイ

次のコマンドでdocker-compose.ymlを作成します。

mkdir deploy-to-fargate
cd deploy-to-fargate
cat <<'EOF' > docker-compose.yml
version: '2'
services:
  hello-cnb:
    ports:
    - 8080:8080
    mem_limit: 768m
    image: making/hello-cnb:latest
    environment:
      INFO_MESSAGE: Hello World!
    logging:
      driver: awslogs
      options: 
        awslogs-group: hello-cnb
        awslogs-region: ap-northeast-1
        awslogs-stream-prefix: web
EOF

次のコマンドでecs-params.ymlを作成します。

cat <<EOF > ecs-params.yml
version: 1
task_definition:
  task_execution_role: ecsTaskExecutionRole
  ecs_network_mode: awsvpc
  task_size:
    mem_limit: 1024
    cpu_limit: 256
run_params:
  network_configuration:
    awsvpc_configuration:
      subnets:
      - ${SUBNET_ID_1}
      - ${SUBNET_ID_2}
      security_groups:
      - ${SECURITY_GROUP_ID}
      assign_public_ip: ENABLED
EOF

次のコマンドでアプリケーションをデプロイします。

ecs-cli compose \
  --project-name hello-cnb \
  --file docker-compose.yml \
  --ecs-params ecs-params.yml \
  service up \
  --create-log-groups

次のようなログが出力されます。

INFO[0000] Using ECS task definition                     TaskDefinition="hello-cnb:1"
INFO[0000] Created Log Group hello-cnb in ap-northeast-1 
INFO[0016] (service hello-cnb) has started 1 tasks: (task 90947d26-027a-4ea2-bd30-44231bf90c06).  timestamp="2020-04-29 06:24:01 +0000 UTC"
INFO[0046] Service status                                desiredCount=1 runningCount=1 serviceName=hello-cnb
INFO[0046] (service hello-cnb) has reached a steady state.  timestamp="2020-04-29 06:24:41 +0000 UTC"
INFO[0046] ECS Service has reached a stable state        desiredCount=1 runningCount=1 serviceName=hello-cnb
INFO[0046] Created an ECS service                        service=hello-cnb taskDefinition="hello-cnb:1"

次のコマンドでTaskのログを確認します。

TASK_ID=$(ecs-cli compose --project-name hello-cnb --cluster hello-cnb service ps | grep hello-cnb | awk -F '/' '{print $1}') 
ecs-cli logs --task-id ${TASK_ID}

次のようなログが出力されます。

Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=88833K -XX:ReservedCodeCacheSize=240M -Xss1M -Xmx185598K (Head Room: 0%, Loaded Class Count: 13270, Thread Count: 250, Total Memory: 805306368)
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.6.RELEASE)
2020-04-29 06:24:49.000  INFO 1 --- [           main] hello.HelloCnbApplication                : Starting HelloCnbApplication on ip-10-0-0-105.ap-northeast-1.compute.internal with PID 1 (/workspace/BOOT-INF/classes started by cnb in /workspace)
2020-04-29 06:24:49.096  INFO 1 --- [           main] hello.HelloCnbApplication                : No active profile set, falling back to default profiles: default
2020-04-29 06:25:02.797  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 3 endpoint(s) beneath base path '/actuator'
2020-04-29 06:25:08.108  INFO 1 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2020-04-29 06:25:08.197  INFO 1 --- [           main] hello.HelloCnbApplication                : Started HelloCnbApplication in 24.7 seconds (JVM running for 28.791)

指定したコンテナのメモリに合わせて、JVMのメモリが自動で設定されていることに注目してください。

Public IPを変数に設定します。

PUBLIC_IP=$(ecs-cli compose --project-name hello-cnb --cluster hello-cnb service ps | grep hello-cnb | awk '{print $3}' | awk -F ':' '{print $1}')

アプリケーションにアクセスします。

$ curl http://${PUBLIC_IP}:8080/actuator/health -w '\n'
{"status":"UP"}

$ curl http://${PUBLIC_IP}:8080/actuator/info -w '\n'
{"message":"Hello World!"}

メモリの調整

Buildpackに含まれるJava Buildpack Memory Calculatorの機能を使って、
自動設定されるJVMのメモリを調整し、少ないメモリ量(256MiB)で起動できるようにします。

次のコマンドでmanifestをアップデートします。

cat <<'EOF' > docker-compose.yml
version: '2'
services:
  hello-cnb:
    ports:
    - 8080:8080
    mem_limit: 256m # <--
    image: making/hello-cnb:latest
    environment:
      INFO_MESSAGE: Hello World!
      JAVA_OPTS: "-XX:ReservedCodeCacheSize=32M -Xss512k" # <--
      BPL_JVM_THREAD_COUNT: "20" # <--
      BPL_JVM_HEAD_ROOM: "5" # <--
    logging:
      driver: awslogs
      options: 
        awslogs-group: hello-cnb
        awslogs-region: ap-northeast-1
        awslogs-stream-prefix: web
EOF

cat <<EOF > ecs-params.yml
version: 1
task_definition:
  task_execution_role: ecsTaskExecutionRole
  ecs_network_mode: awsvpc
  task_size:
    mem_limit: 512 # <--
    cpu_limit: 256
run_params:
  network_configuration:
    awsvpc_configuration:
      subnets:
      - ${SUBNET_ID_1}
      - ${SUBNET_ID_2}
      security_groups:
      - ${SECURITY_GROUP_ID}
      assign_public_ip: ENABLED
EOF

次のコマンドでアプリケーションを更新します。

ecs-cli compose \
  --project-name hello-cnb \
  --file docker-compose.yml \
  --ecs-params ecs-params.yml \
  service up

次のコマンドでTaskのログを確認します。

TASK_ID=$(ecs-cli compose --project-name hello-cnb --cluster hello-cnb service ps | grep hello-cnb | awk -F '/' '{print $1}') 
ecs-cli logs --task-id ${TASK_ID}

メモリの設定が次のように出力されていることを確認してください。

Calculated JVM Memory Configuration:  (Head Room: 5%, Loaded Class Count: 13270, Thread Count: 25, Total Memory: 268435456)

アプリケーションの削除

次のコマンドでアプリを削除します。

ecs-cli compose --project-name hello-cnb service down
aws logs delete-log-group --log-group-name hello-cnb --region ap-northeast-1 
ecs-cli down --force
Found a mistake? Update the entry.
Share this article: