■ECS/Fargate周辺の説明
参考
20190731 Black Belt Online Seminar Amazon ECS Deep Dive
ECS on EC2の構成図
- EC2上で稼働するTaskでコンテナが処理されます
- EC2を複数個まとめてクラスターとして扱います
- クラスター管理をし、どのEC2へ新規タスクを設けるかはECSの役目です
ECS on Fargateの構成図
- しかし僕らが注力したいのはコンテナでどのような処理が稼働するかです
- EC2の管理はやりたくないので、そこをマネージドしてくれるのがFargate
ECSの主要要素
- クラスター:実行環境の境界線
- サービス:タスクを維持する機能
- タスク:タスク定義に記載された内容を実行するコンテナ群
- タスク定義:CPU/メモリ、稼働するコンテナイメージ等、何を稼働させるのかの定義
■クラスターの作成
- クラスターという実行環境の境界線を作成します
cmd
aws ecs create-cluster \
--cluster-name ContainerHandsOn \
--tags "key=Name,value=ContainerHandsOn"
result
{
"cluster": {
"clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ContainerHandsOn",
"clusterName": "ContainerHandsOn",
"status": "ACTIVE",
"registeredContainerInstancesCount": 0,
"runningTasksCount": 0,
"pendingTasksCount": 0,
"activeServicesCount": 0,
"statistics": [],
"tags": [
{
"key": "Name",
"value": "ContainerHandsOn"
}
],
"settings": [
{
"name": "containerInsights",
"value": "disabled"
}
],
"capacityProviders": [],
"defaultCapacityProviderStrategy": []
}
}
■タスク定義の作成
- どのようなタスクが稼働するかを定義します
cmd
cd ~/environment
cat << EOF > register-task-definition.json
{
"family": "ContainerHandsOn",
"executionRoleArn": "arn:aws:iam::${AccountID}:role/ecsTaskExecutionRole",
"networkMode": "awsvpc",
"containerDefinitions": [
{
"name": "ContainerHandsOn",
"image": "${AccountID}.dkr.ecr.ap-northeast-1.amazonaws.com/jaws-days-2022/container-hands-on:latest",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"essential": true,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "awslogs-container-hands-on",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "hands-on"
}
}
}
],
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "256",
"memory": "512",
"runtimePlatform": {
"cpuArchitecture": "X86_64",
"operatingSystemFamily": "LINUX"
}
}
EOF
aws ecs register-task-definition \
--cli-input-json file://register-task-definition.json \
--tags "key=Name,value=ContainerHandsOn"
result
{
"taskDefinition": {
"taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/ContainerHandsOn:11",
"containerDefinitions": [
{
"name": "ContainerHandsOn",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/jaws-days-2022/container-hands-on:latest",
"cpu": 0,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"essential": true,
"environment": [],
"mountPoints": [],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "awslogs-container-hands-on",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "hands-on"
}
}
}
],
"family": "ContainerHandsOn",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"networkMode": "awsvpc",
"revision": 11,
"volumes": [],
"status": "ACTIVE",
"requiresAttributes": [
{
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
},
{
"name": "ecs.capability.execution-role-awslogs"
},
{
"name": "com.amazonaws.ecs.capability.ecr-auth"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
},
{
"name": "ecs.capability.execution-role-ecr-pull"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
},
{
"name": "ecs.capability.task-eni"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
}
],
"placementConstraints": [],
"compatibilities": [
"EC2",
"FARGATE"
],
"runtimePlatform": {
"cpuArchitecture": "X86_64",
"operatingSystemFamily": "LINUX"
},
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "256",
"memory": "512",
"registeredAt": 1663243819.62,
"registeredBy": "arn:aws:sts::123456789012:assumed-role/ContainerHandsOnForCloud9/i-0ddf413a91a008a52"
},
"tags": [
{
"key": "Name",
"value": "ContainerHandsOn"
}
]
}
■タスク定義のリビジョン取得
- タスク定義は作成する度にカウントアップされるので、最新のリビジョン番号を取得します
cmd
RevisionNo=`aws ecs list-task-definitions \
--family-prefix ContainerHandsOn \
--status ACTIVE \
--sort ASC | \
grep ContainerHandsOn | tail -1 | sed -e 's/"//g' | cut -f 7 --delim=":"`
clear; cat << EOF > ~/environment/export.log
export AccountID="${AccountID}"
export VpcId="${VpcId}"
export SubnetId1aPublic="${SubnetId1aPublic}"
export SubnetId1cPublic="${SubnetId1cPublic}"
export SubnetId1aPrivate="${SubnetId1aPrivate}"
export SubnetId1cPrivate="${SubnetId1cPrivate}"
export InternetGatewayId="${InternetGatewayId}"
export RouteTableIdPublic="${RouteTableIdPublic}"
export RouteTableIdPrivate="${RouteTableIdPrivate}"
export PublicSecurityGroupsId="${PublicSecurityGroupsId}"
export PrivateSecurityGroupsId="${PrivateSecurityGroupsId}"
export InstanceId="${InstanceId}"
export LoadBalancersDnsName="${LoadBalancersDnsName}"
export LoadBalancerArn="${LoadBalancerArn}"
export TargetGroupArn="${TargetGroupArn}"
export RevisionNo="${RevisionNo}"
EOF
cat ~/environment/export.log
result
これはサンプルです。export AccountID="123456789012"
これはサンプルです。export VpcId="vpc-010a940bbd8f747c2"
これはサンプルです。export SubnetId1aPublic="subnet-0356b36ba2daa766c"
これはサンプルです。export SubnetId1cPublic="subnet-0dabe411bfdc835fb"
これはサンプルです。export SubnetId1aPrivate="subnet-0d99180ac3baeb5fa"
これはサンプルです。export SubnetId1cPrivate="subnet-0a66f1c2d5ce3b939"
これはサンプルです。export InternetGatewayId="igw-082f42082d7748713"
これはサンプルです。export RouteTableIdPublic="rtb-000a11e6eacc5c263"
これはサンプルです。export RouteTableIdPrivate="rtb-077b87e7eb65d1f43"
これはサンプルです。export PublicSecurityGroupsId="sg-065a7c8eceb9759d4"
これはサンプルです。export PrivateSecurityGroupsId="sg-0f59547a1185820b5"
これはサンプルです。export InstanceId="i-0ddf413a91a008a52"
これはサンプルです。export LoadBalancersDnsName="ContainerHandsOn-681708310.ap-northeast-1.elb.amazonaws.com"
これはサンプルです。export LoadBalancerArn="arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:loadbalancer/app/ContainerHandsOn/b392eaa096f09053"
これはサンプルです。export TargetGroupArn="arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/ContainerHandsOn/b2da630c91ed7148"
これはサンプルです。export RevisionNo="11"
Positive
: RevisionNoは基本的には1になる予定です、再作成をする度にカウントアップされていきます。
■サービスの作成
- 実行数やネットワーク周りを定義したサービスを作成します
cmd
aws ecs create-service \
--cluster ContainerHandsOn \
--service-name ContainerHandsOn \
--task-definition ContainerHandsOn:${RevisionNo} \
--deployment-controller type=CODE_DEPLOY \
--desired-count 2 \
--launch-type FARGATE \
--platform-version LATEST \
--network-configuration "awsvpcConfiguration={subnets=[${SubnetId1aPrivate},${SubnetId1cPrivate}],securityGroups=[${PrivateSecurityGroupsId}],assignPublicIp=DISABLED}" \
--load-balancers targetGroupArn=${TargetGroupArn},containerName=ContainerHandsOn,containerPort=80
result
{
"service": {
"serviceArn": "arn:aws:ecs:ap-northeast-1:123456789012:service/ContainerHandsOn/ContainerHandsOn",
"serviceName": "ContainerHandsOn",
"clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ContainerHandsOn",
"loadBalancers": [
{
"targetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/ContainerHandsOn/b2da630c91ed7148",
"containerName": "ContainerHandsOn",
"containerPort": 80
}
],
"serviceRegistries": [],
"status": "ACTIVE",
"desiredCount": 2,
"runningCount": 0,
"pendingCount": 0,
"launchType": "FARGATE",
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"taskDefinition": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/ContainerHandsOn:11",
"deploymentConfiguration": {
"maximumPercent": 200,
"minimumHealthyPercent": 100
},
"taskSets": [
{
"id": "ecs-svc/1465112757677924538",
"taskSetArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-set/ContainerHandsOn/ContainerHandsOn/ecs-svc/1465112757677924538",
"serviceArn": "arn:aws:ecs:ap-northeast-1:123456789012:service/ContainerHandsOn",
"clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ContainerHandsOn",
"status": "PRIMARY",
"taskDefinition": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/ContainerHandsOn:11",
"computedDesiredCount": 2,
"pendingCount": 0,
"runningCount": 0,
"createdAt": 1663243874.599,
"updatedAt": 1663243874.599,
"launchType": "FARGATE",
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"networkConfiguration": {
"awsvpcConfiguration": {
"subnets": [
"subnet-0d99180ac3baeb5fa",
"subnet-0a66f1c2d5ce3b939"
],
"securityGroups": [
"sg-0f59547a1185820b5"
],
"assignPublicIp": "DISABLED"
}
},
"loadBalancers": [
{
"targetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/ContainerHandsOn/b2da630c91ed7148",
"containerName": "ContainerHandsOn",
"containerPort": 80
}
],
"serviceRegistries": [],
"scale": {
"value": 100.0,
"unit": "PERCENT"
},
"stabilityStatus": "STABILIZING",
"stabilityStatusAt": 1663243874.599,
"tags": []
}
],
"deployments": [],
"roleArn": "arn:aws:iam::123456789012:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
"events": [],
"createdAt": 1663243874.599,
"placementConstraints": [],
"placementStrategy": [],
"networkConfiguration": {
"awsvpcConfiguration": {
"subnets": [
"subnet-0d99180ac3baeb5fa",
"subnet-0a66f1c2d5ce3b939"
],
"securityGroups": [
"sg-0f59547a1185820b5"
],
"assignPublicIp": "DISABLED"
}
},
"healthCheckGracePeriodSeconds": 0,
"schedulingStrategy": "REPLICA",
"deploymentController": {
"type": "CODE_DEPLOY"
},
"createdBy": "arn:aws:iam::123456789012:role/ContainerHandsOnForCloud9",
"enableECSManagedTags": false,
"propagateTags": "NONE",
"enableExecuteCommand": false
}
}