AWS CLI로 Fargate용 Amazon ECS Linux 태스크 만들기

AWS CLI로 Fargate용 Amazon ECS Linux 태스크 만들기

다음 단계는 AWS CLI를 사용해 Amazon ECS에서 클러스터를 설정하고, 태스크 정의를 등록하고, Linux 태스크를 실행하는 방법과 기타 일반적인 시나리오를 수행하는 데 도움이 돼요. 최신 버전의 AWS CLI를 사용하세요. 최신 버전으로 업그레이드하는 방법은 최신 버전의 AWS CLI 설치 또는 업데이트(Installing or updating to the latest version of the AWS CLI)를 참고하세요.

출처: 문서

본문

참고: dual-stack 서비스 엔드포인트를 사용해 AWS CLI, SDK, Amazon ECS API에서 IPv4와 IPv6 모두로 Amazon ECS와 상호 작용할 수 있어요. 자세한 내용은 Amazon ECS dual-stack 엔드포인트 사용(Using Amazon ECS dual-stack endpoints)을 참고하세요.

주제:

  • 사전 요구 사항(Prerequisites)
  • 1단계: 클러스터 만들기
  • 2단계: Linux 태스크 정의 등록
  • 3단계: 태스크 정의 나열
  • 4단계: 서비스 만들기
  • 5단계: 서비스 나열
  • 6단계: 실행 중인 서비스 describe
  • 7단계: 테스트
  • 8단계: 정리

사전 요구 사항

이 튜토리얼은 다음 사전 요구 사항이 완료되었다고 가정합니다.

  • 최신 버전의 AWS CLI가 설치되고 구성되었습니다. AWS CLI 설치 또는 업그레이드에 대한 자세한 내용은 최신 버전의 AWS CLI 설치 또는 업데이트를 참고하세요.
  • Amazon ECS 사용 설정(Set up to use Amazon ECS) 단계를 완료했습니다.
  • IAM 사용자에게 AmazonECS_FullAccess IAM 정책 예시에 지정된 필요한 권한이 있습니다.
  • 사용할 VPC와 보안 그룹이 있습니다. 이 튜토리얼은 Amazon ECR Public에 호스팅된 컨테이너 이미지를 사용하므로 태스크에 인터넷 액세스가 있어야 해요. 태스크에 인터넷 라우트를 제공하려면 다음 옵션 중 하나를 사용하세요:
    • 탄력적 IP 주소가 있는 NAT 게이트웨이가 설정된 프라이빗 서브넷 사용
    • 퍼블릭 서브넷을 사용하고 태스크에 퍼블릭 IP 주소 할당
    • 자세한 내용은 가상 프라이빗 클라우드 만들기(Create a virtual private cloud)를 참고하세요. 보안 그룹과 규칙에 대한 정보는 Amazon Virtual Private Cloud 사용자 가이드의 VPC용 기본 보안 그룹(Default security groups for your VPCs)과 규칙 예시(Example rules)를 참고하세요.
  • 프라이빗 서브넷을 사용해 이 튜토리얼을 따른다면, Amazon ECS Exec을 사용해 컨테이너와 직접 상호 작용하고 배포를 테스트할 수 있어요. ECS Exec을 사용하려면 태스크 IAM 역할을 만들어야 합니다. 태스크 IAM 역할과 기타 사전 요구 사항에 대한 자세한 내용은 Amazon ECS Exec으로 Amazon ECS 컨테이너 모니터링(Monitor Amazon ECS containers with Amazon ECS Exec)을 참고하세요.
  • (선택 사항) AWS CloudShell은 자체 EC2 인스턴스를 만들 필요 없이 고객에게 명령줄을 제공하는 도구예요. 자세한 내용은 AWS CloudShell 사용자 가이드의 AWS CloudShell이란 무엇인가요?(What is AWS CloudShell?)를 참고하세요.

1단계: 클러스터 만들기

기본적으로 계정에는 기본 클러스터(default cluster)가 제공돼요. 참고: 제공된 기본 클러스터를 사용하면 이후 명령에서 --cluster cluster_name 옵션을 지정할 필요가 없는 이점이 있습니다. 자체 비기본 클러스터를 만들면, 그 클러스터에 사용하려는 각 명령에 --cluster cluster_name을 지정해야 해요.

다음 명령으로 고유한 이름의 클러스터를 만듭니다:

aws ecs create-cluster --cluster-name fargate-cluster

출력:

{
    "cluster": {
        "status": "ACTIVE",
        "defaultCapacityProviderStrategy": [],
        "statistics": [],
        "capacityProviders": [],
        "tags": [],
        "clusterName": "fargate-cluster",
        "settings": [
            {
                "name": "containerInsights",
                "value": "disabled"
            }
        ],
        "registeredContainerInstancesCount": 0,
        "pendingTasksCount": 0,
        "runningTasksCount": 0,
        "activeServicesCount": 0,
        "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/fargate-cluster"
    }
}

2단계: Linux 태스크 정의 등록

ECS 클러스터에서 태스크를 실행하려면 먼저 태스크 정의를 등록해야 해요. 태스크 정의는 함께 그룹화된 컨테이너 목록입니다. 다음 예시는 Docker Hub에 호스팅된 httpd 컨테이너 이미지를 사용해 PHP 웹 앱을 만드는 간단한 태스크 정의입니다. 사용 가능한 태스크 정의 파라미터에 대한 자세한 내용은 Amazon ECS 태스크 정의(Amazon ECS task definitions)를 참고하세요.

이 튜토리얼에서 taskRoleArn은 프라이빗 서브넷에 태스크를 배포하고 배포를 테스트하려는 경우에만 필요해요. 사전 요구 사항에서 언급한 대로 ECS Exec을 사용하기 위해 만든 IAM 태스크 역할로 taskRoleArn을 바꾸세요.

{
        "family": "sample-fargate",
        "networkMode": "awsvpc",
        "taskRoleArn": "arn:aws:iam::aws_account_id:role/execCommandRole",
        "containerDefinitions": [
            {
                "name": "fargate-app",
                "image": "public.ecr.aws/docker/library/httpd:latest",
                "portMappings": [
                    {
                        "containerPort": 80,
                        "hostPort": 80,
                        "protocol": "tcp"
                    }
                ],
                "essential": true,
                "entryPoint": [
                    "sh",
                    "-c"
                ],
                "command": [
                    "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
                ]
            }
        ],
        "requiresCompatibilities": [
            "FARGATE"
        ],
        "cpu": "256",
        "memory": "512"
}

태스크 정의 JSON을 파일로 저장하고 --cli-input-json file://path_to_file.json 옵션과 함께 전달합니다.

컨테이너 정의용 JSON 파일을 사용하려면:

aws ecs register-task-definition --cli-input-json file://$HOME/tasks/fargate-task.json

register-task-definition 명령은 등록이 완료된 후 태스크 정의에 대한 설명을 반환합니다.

3단계: 태스크 정의 나열

list-task-definitions 명령으로 계정의 태스크 정의를 언제든 나열할 수 있어요. 이 명령의 출력은 run-task나 start-task를 호출할 때 함께 사용할 수 있는 family와 revision 값을 보여줍니다.

aws ecs list-task-definitions

출력:

{
    "taskDefinitionArns": [
        "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate:1"
    ]
}

4단계: 서비스 만들기

계정에 태스크를 등록한 후에는 등록된 태스크에 대한 서비스를 클러스터에 만들 수 있어요. 이 예시에서는 클러스터에서 sample-fargate:1 태스크 정의의 인스턴스 하나를 실행하는 서비스를 만듭니다. 태스크는 인터넷으로의 라우트가 필요하므로 두 가지 방법이 있습니다. 하나는 퍼블릭 서브넷의 탄력적 IP 주소가 있는 NAT 게이트웨이로 구성된 프라이빗 서브넷을 사용하는 것입니다. 다른 하나는 퍼블릭 서브넷을 사용하고 태스크에 퍼블릭 IP 주소를 할당하는 것입니다. 다음 섹션에서 두 예시를 모두 제공합니다.

프라이빗 서브넷을 사용한 예시. enable-execute-command 옵션은 Amazon ECS Exec을 사용하는 데 필요합니다.

aws ecs create-service --cluster fargate-cluster --service-name fargate-service --task-definition sample-fargate:1 --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234]}" --enable-execute-command

퍼블릭 서브넷을 사용한 예시:

aws ecs create-service --cluster fargate-cluster --service-name fargate-service --task-definition sample-fargate:1 --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234],assignPublicIp=ENABLED}"

create-service 명령은 등록이 완료된 후 태스크 정의에 대한 설명을 반환합니다.

5단계: 서비스 나열

클러스터의 서비스를 나열합니다. 이전 섹션에서 만든 서비스가 보여야 해요. 이 명령에서 반환된 서비스 이름이나 전체 ARN을 가져와 나중에 서비스를 describe하는 데 사용할 수 있습니다.

aws ecs list-services --cluster fargate-cluster

출력:

{
    "serviceArns": [
        "arn:aws:ecs:region:aws_account_id:service/fargate-cluster/fargate-service"
    ]
}

6단계: 실행 중인 서비스 describe

앞서 가져온 서비스 이름으로 서비스를 describe해 태스크에 대한 자세한 정보를 얻습니다:

aws ecs describe-services --cluster fargate-cluster --services fargate-service

성공하면 이 호출은 서비스 실패와 서비스에 대한 설명을 반환해요. 예를 들어 services 섹션에서는 실행 중 또는 보류 중인 태스크 상태 같은 배포 정보를 찾을 수 있습니다. 태스크 정의, 네트워크 구성, 타임스탬프 이벤트에 대한 정보도 찾을 수 있어요. failures 섹션에서는 호출과 관련된 실패 정보가 있다면 볼 수 있습니다. 트러블슈팅은 서비스 이벤트 메시지(Service Event Messages)를 참고하세요. 서비스 설명에 대한 자세한 내용은 Describe Services를 참고하세요.

{
    "services": [
        {
            "networkConfiguration": {
                "awsvpcConfiguration": {
                    "subnets": [
                        "subnet-abcd1234"
                    ],
                    "securityGroups": [
                        "sg-abcd1234"
                    ],
                    "assignPublicIp": "ENABLED"
                }
            },
            "launchType": "FARGATE",
            "enableECSManagedTags": false,
            "loadBalancers": [],
            "deploymentController": {
                "type": "ECS"
            },
            "desiredCount": 1,
            "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/fargate-cluster",
            "serviceArn": "arn:aws:ecs:region:aws_account_id:service/fargate-cluster/fargate-service",
            "deploymentConfiguration": {
                "maximumPercent": 200,
                "minimumHealthyPercent": 100
            },
            "createdAt": 1692283199.771,
            "schedulingStrategy": "REPLICA",
            "placementConstraints": [],
            "deployments": [
                {
                    "status": "PRIMARY",
                    "networkConfiguration": {
                        "awsvpcConfiguration": {
                            "subnets": [
                                "subnet-abcd1234"
                            ],
                            "securityGroups": [
                                "sg-abcd1234"
                            ],
                            "assignPublicIp": "ENABLED"
                        }
                    },
                    "pendingCount": 0,
                    "launchType": "FARGATE",
                    "createdAt": 1692283199.771,
                    "desiredCount": 1,
                    "taskDefinition": "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate:1",
                    "updatedAt": 1692283199.771,
                    "platformVersion": "1.4.0",
                    "id": "ecs-svc/9223370526043414679",
                    "runningCount": 0
                }
            ],
            "serviceName": "fargate-service",
            "events": [
                {
                    "message": "(service fargate-service) has started 2 tasks: (task 53c0de40-ea3b-489f-a352-623bf1235f08) (task d0aec985-901b-488f-9fb4-61b991b332a3).",
                    "id": "92b8443e-67fb-4886-880c-07e73383ea83",
                    "createdAt": 1510811841.408
                },
                {
                    "message": "(service fargate-service) has started 2 tasks: (task b4911bee-7203-4113-99d4-e89ba457c626) (task cc5853e3-6e2d-4678-8312-74f8a7d76474).",
                    "id": "d85c6ec6-a693-43b3-904a-a997e1fc844d",
                    "createdAt": 1510811601.938
                },
                {
                    "message": "(service fargate-service) has started 2 tasks: (task cba86182-52bf-42d7-9df8-b744699e6cfc) (task f4c1ad74-a5c6-4620-90cf-2aff118df5fc).",
                    "id": "095703e1-0ca3-4379-a7c8-c0f1b8b95ace",
                    "createdAt": 1510811364.691
                }
            ],
            "runningCount": 0,
            "status": "ACTIVE",
            "serviceRegistries": [],
            "pendingCount": 0,
            "createdBy": "arn:aws:iam::aws_account_id:user/user_name",
            "platformVersion": "LATEST",
            "placementStrategy": [],
            "propagateTags": "NONE",
            "roleArn": "arn:aws:iam::aws_account_id:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
            "taskDefinition": "arn:aws:ecs:region:aws_account_id:task-definition/sample-fargate:1"
        }
    ],
    "failures": []
}

7단계: 테스트

퍼블릭 서브넷을 사용해 배포된 태스크 테스트

태스크의 탄력적 네트워크 인터페이스(ENI)를 얻기 위해 서비스의 태스크를 describe합니다.

먼저 태스크 ARN을 가져옵니다:

aws ecs list-tasks --cluster fargate-cluster --service fargate-service

출력에 태스크 ARN이 포함됩니다:

{
    "taskArns": [
        "arn:aws:ecs:us-east-1:123456789012:task/fargate-service/EXAMPLE"
    ]
}

태스크를 describe하고 ENI ID를 찾습니다. tasks 파라미터에 태스크 ARN을 사용하세요:

aws ecs describe-tasks --cluster fargate-cluster --tasks arn:aws:ecs:us-east-1:123456789012:task/service/EXAMPLE

첨부(attachment) 정보가 출력에 나열됩니다:

{
    "tasks": [
        {
            "attachments": [
                {
                    "id": "d9e7735a-16aa-4128-bc7a-b2d5115029e9",
                    "type": "ElasticNetworkInterface",
                    "status": "ATTACHED",
                    "details": [
                        {
                            "name": "subnetId",
                            "value": "subnetabcd1234"
                        },
                        {
                            "name": "networkInterfaceId",
                            "value": "eni-0fa40520aeEXAMPLE"
                        },
                    ]
                }
…
}

퍼블릭 IP 주소를 얻기 위해 ENI를 describe합니다:

aws ec2 describe-network-interfaces --network-interface-id eni-0fa40520aeEXAMPLE

퍼블릭 IP 주소가 출력에 있습니다:

{
    "NetworkInterfaces": [
        {
            "Association": {
                "IpOwnerId": "amazon",
                "PublicDnsName": "ec2-34-229-42-222.compute-1.amazonaws.com",
                "PublicIp": "198.51.100.2"
            },
…
}

웹 브라우저에 퍼블릭 IP 주소를 입력하면 Amazon ECS 샘플 애플리케이션을 표시하는 웹페이지가 보일 거예요.

프라이빗 서브넷을 사용해 배포된 태스크 테스트

ExecuteCommandAgent가 실행 중인지 확인하려면 태스크를 describe하고 managedAgents를 찾습니다. 나중에 사용할 수 있도록 privateIPv4Address를 기록해 두세요.

aws ecs describe-tasks --cluster fargate-cluster --tasks arn:aws:ecs:us-east-1:123456789012:task/fargate-service/EXAMPLE

관리형 에이전트 정보가 출력에 나열됩니다:

{
     "tasks": [
        {
            "attachments": [
                {
                    "id": "d9e7735a-16aa-4128-bc7a-b2d5115029e9",
                    "type": "ElasticNetworkInterface",
                    "status": "ATTACHED",
                    "details": [
                        {
                            "name": "subnetId",
                            "value": "subnetabcd1234"
                        },
                        {
                            "name": "networkInterfaceId",
                            "value": "eni-0fa40520aeEXAMPLE"
                        },
                        {
                            "name": "privateIPv4Address",
                            "value": "10.0.143.156"
                        }
                    ]
                }
            ],
     ...
     "containers": [
         {
         ...
        "managedAgents": [
                        {
                            "lastStartedAt": "2023-08-01T16:10:13.002000+00:00",
                            "name": "ExecuteCommandAgent",
                            "lastStatus": "RUNNING"
                        }
                ],
        ...
    }

ExecuteCommandAgent가 실행 중임을 확인한 후 다음 명령으로 태스크의 컨테이너에서 대화형 셸을 실행할 수 있어요.

aws ecs execute-command --cluster fargate-cluster \
     --task arn:aws:ecs:us-east-1:123456789012:task/fargate-service/EXAMPLE \
     --container fargate-app \
     --interactive \
     --command "/bin/sh"

대화형 셸이 실행된 후 다음 명령으로 cURL을 설치합니다:

apt update
apt install curl

cURL을 설치한 후 앞서 얻은 프라이빗 IP 주소로 다음 명령을 실행합니다:

curl 10.0.143.156

Amazon ECS 샘플 애플리케이션 웹페이지에 해당하는 HTML이 보일 거예요:

<html>
    <head>
     <title>Amazon ECS Sample App</title>
     <style>body {margin-top: 40px; background-color: #333;} </style>
    </head>
      <body>
      <div style=color:white;text-align:center>
      <h1>Amazon ECS Sample App</h1>
      <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p>
      </div>
      </body>
</html>

8단계: 정리

튜토리얼을 마치면 관련 리소스를 정리해 사용하지 않는 리소스에 대한 요금이 부과되지 않도록 해야 해요.

서비스를 삭제합니다:

aws ecs delete-service --cluster fargate-cluster --service fargate-service --force

클러스터를 삭제합니다:

aws ecs delete-cluster --cluster fargate-cluster