AWS CLI를 사용한 Amazon ECS Service Connect 구성 - Amazon Elastic Container Service

AWS CLI를 사용한 Amazon ECS Service Connect 구성

AWS CLI를 통해 Service Connect를 사용하는 Fargate 태스크에 대한 Amazon ECS 서비스를 생성할 수 있습니다.

참고

듀얼 스택 서비스 엔드포인트를 사용하면 AWS CLI, SDK 및 Amazon ECS API에서 IPv4 및 IPv6 모두를 통해 Amazon ECS와 상호 작용할 수 있습니다. 자세한 내용은 Amazon ECS 듀얼 스택 엔드포인트 사용 섹션을 참조하세요.

사전 조건

다음은 Service Connect의 사전 조건입니다.

  • 최신 버전의 AWS CLI가 설치되고 구성되어 있는지 확인합니다. 자세한 내용은 Installing or updating to the latest version of the AWS CLI를 참조하세요.

  • IAM 사용자는 AmazonECS_FullAccess IAM 정책 예제에 지정된 필수 권한을 가집니다.

  • 사용할 VPC, 서브넷, 라우팅 테이블 및 보안 그룹이 생성되었습니다. 자세한 내용은 Virtual Private Cloud 생성 섹션을 참조하세요.

  • 이름이 ecsTaskExecutionRole인 작업 실행 역할이 있고 AmazonECSTaskExecutionRolePolicy 관리형 정책이 역할에 연결되어 있습니다. 이 역할을 통해 Fargate는 NGINX 애플리케이션 로그와 Service Connect 프록시 로그를 Amazon CloudWatch Logs에 쓸 수 있습니다. 자세한 내용은 작업 실행 역할 생성 섹션을 참조하세요.

1단계: 클러스터 생성

다음 단계에 따라 Amazon ECS 클러스터 및 네임스페이스를 생성합니다.

Amazon ECS 클러스터와 AWS Cloud Map 네임스페이스 생성
  1. 사용할 tutorial이라는 Amazon ECS 클러스터를 생성합니다. 파라미터 --service-connect-defaults는 클러스터의 기본 네임스페이스를 설정합니다. 예제 출력에서는 이름이 service-connect인 AWS Cloud Map 네임스페이스가 이 계정과 AWS 리전에 존재하지 않으므로 Amazon ECS에서 네임스페이스를 생성합니다. 네임스페이스는 계정의 AWS Cloud Map에서 생성되고, 다른 모든 네임스페이스에서 볼 수 있으므로 용도를 나타내는 이름을 사용합니다.

    aws ecs create-cluster --cluster-name tutorial --service-connect-defaults namespace=service-connect

    출력:

    {
        "cluster": {
            "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
            "clusterName": "tutorial",
            "serviceConnectDefaults": {
                "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
            },
            "status": "PROVISIONING",
            "registeredContainerInstancesCount": 0,
            "runningTasksCount": 0,
            "pendingTasksCount": 0,
            "activeServicesCount": 0,
            "statistics": [],
            "tags": [],
            "settings": [
                {
                    "name": "containerInsights",
                    "value": "disabled"
                }
            ],
            "capacityProviders": [],
            "defaultCapacityProviderStrategy": [],
            "attachments": [
                {
                    "id": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
                    "type": "sc",
                    "status": "ATTACHING",
                    "details": []
                }
            ],
            "attachmentsStatus": "UPDATE_IN_PROGRESS"
        }
    }
    }
  2. 클러스터가 생성되었는지 확인합니다.

    aws ecs describe-clusters --clusters tutorial

    출력:

    {
        "clusters": [
            {
                "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
                "clusterName": "tutorial",
                "serviceConnectDefaults": {
                    "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
                },
                "status": "ACTIVE",
                "registeredContainerInstancesCount": 0,
                "runningTasksCount": 0,
                "pendingTasksCount": 0,
                "activeServicesCount": 0,
                "statistics": [],
                "tags": [],
                "settings": [],
                "capacityProviders": [],
                "defaultCapacityProviderStrategy": []
            }
        ],
        "failures": []
    }
                    
  3. (선택 사항) AWS Cloud Map에서 네임스페이스가 생성되었는지 확인합니다. AWS Cloud Map에서 생성되었으므로 AWS Management Console 또는 일반 AWS CLI 구성을 사용할 수 있습니다.

    예를 들어 AWS CLI를 사용합니다.

    aws servicediscovery get-namespace --id ns-EXAMPLE

    출력:

    {
        "Namespace": {
            "Id": "ns-EXAMPLE",
            "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE",
            "Name": "service-connect",
            "Type": "HTTP",
            "Properties": {
                "DnsProperties": {
                    "SOA": {}
                },
                "HttpProperties": {
                    "HttpName": "service-connect"
                }
            },
            "CreateDate": 1661749852.422,
            "CreatorRequestId": "service-connect"
        }
    }
                    

2단계: 서버용 서비스 생성

Service Connect 기능은 Amazon ECS에서 여러 애플리케이션을 상호 연결하는 데 사용됩니다. 이러한 애플리케이션 중 하나 이상은 연결할 웹 서비스를 제공해야 합니다. 이 단계에서는 다음을 생성합니다.

  • 수정되지 않은 공식 NGINX 컨테이너 이미지를 사용하고 Service Connect 구성을 포함하는 작업 정의.

  • 이 서비스에 대한 트래픽에 대해 서비스 검색 및 서비스 메시 프록시를 제공하도록 Service Connect를 구성하는 Amazon ECS 서비스 정의입니다. 구성은 클러스터 구성의 기본 네임스페이스를 재사용하여 각 서비스에 대한 서비스 구성의 양을 줄입니다.

  • Amazon ECS 서비스입니다. 작업 정의를 사용하여 하나의 작업을 실행하고, Service Connect 프록시에 대한 추가 컨테이너를 삽입합니다. 프록시는 작업 정의의 컨테이너 포트 매핑에 지정된 포트에서 수신을 대기합니다. Amazon ECS에서 실행되는 클라이언트 애플리케이션에서 클라이언트 작업의 프록시는 작업 정의 포트 이름, 서비스 검색 이름 또는 서비스 클라이언트 별칭 이름, 클라이언트 별칭의 포트 번호에 대한 아웃바운드 연결을 수신 대기합니다.

Service Connect를 사용하여 웹 서비스를 생성하려면
  1. Fargate와 호환되며 awsvpc 네트워크 모드를 사용하는 태스크 정의를 등록합니다. 다음 단계를 따릅니다.

    1. 다음과 같은 태스크 정의의 내용으로 이름이 service-connect-nginx.json인 파일을 생성합니다.

      이 작업 정의는 포트 매핑에 nameappProtocol 파라미터를 추가하여 Service Connect를 구성합니다. 포트 이름을 사용하면 여러 포트가 사용될 때 서비스 구성에서 이 포트를 더욱 쉽게 식별할 수 있습니다. 포트 이름은 기본적으로 네임스페이스의 다른 애플리케이션에서 사용할 검색 가능한 이름으로도 사용됩니다.

      서비스에서 ECS Exec이 활성화되어 있으므로 작업 정의에 작업 IAM 역할이 포함됩니다.

      중요

      이 작업 정의는 logConfiguration을 사용하여 stdoutstderr의 nginx 출력을 Amazon CloudWatch Logs로 전송합니다. 이 작업 실행 역할에는 CloudWatch Logs 로그 그룹을 만드는 데 필요한 추가 권한이 없습니다. AWS Management Console 또는 AWS CLI를 사용하여 CloudWatch Logs에서 로그 그룹을 생성합니다. nginx 로그를 CloudWatch Logs로 전송하지 않으려면 logConfiguration을 제거합니다.

      태스크 실행 역할의 AWS 계정 ID를 사용자의 AWS 계정 ID로 바꿉니다.

      { "family": "service-connect-nginx", "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole", "networkMode": "awsvpc", "containerDefinitions": [ { "name": "webserver", "image": "public.ecr.aws/docker/library/nginx:latest", "cpu": 100, "portMappings": [ { "name": "nginx", "containerPort": 80, "protocol": "tcp", "appProtocol": "http" } ], "essential": true, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/service-connect-nginx", "awslogs-region": "region", "awslogs-stream-prefix": "nginx" } } } ], "cpu": "256", "memory": "512" }
    2. service-connect-nginx.json 파일을 사용하여 작업 정의를 등록합니다.

      aws ecs register-task-definition --cli-input-json file://service-connect-nginx.json
  2. 서비스 생성:

    1. 생성하려는 Amazon ECS 서비스의 내용으로 이름이 service-connect-nginx-service.json인 파일을 생성합니다. 이 예에서는 이전 단계에서 생성된 태스크 정의를 사용합니다. 예제 태스크 정의에서 awsvpcConfiguration 네트워크 모드가 사용되기 때문에 awsvpc이 필요합니다.

      Fargate 시작 유형을 지정하고 Service Connect를 지원하는 LATEST 플랫폼 버전을 지정하여 ECS 서비스를 생성합니다. securityGroupssubnets는 Amazon ECS 사용에 대한 요구 사항을 갖춘 VPC에 속해야 합니다. Amazon VPC 콘솔에서 보안 그룹 및 서브넷 ID를 얻을 수 있습니다.

      이 서비스는 serviceConnectConfiguration 파라미터를 추가하여 Service Connect를 구성합니다. 클러스터에는 기본 네임스페이스가 구성되어 있으므로 네임스페이스는 필요하지 않습니다. 네임스페이스의 ECS에서 실행되는 클라이언트 애플리케이션은 portNameclientAliases의 포트를 사용하여 이 서비스에 연결합니다. 예를 들어, nginx는 루트 위치 /에 시작 페이지를 제공하므로 http://nginx:80/을 사용하여 이 서비스에 연결할 수 있습니다. Amazon ECS에서 실행되지 않거나 동일한 네임스페이스에 있지 않은 외부 애플리케이션은 작업의 IP 주소와 작업 정의의 포트 번호를 사용하여 Service Connect 프록시를 통해 이 애플리케이션에 연결할 수 있습니다. tls 구성을 위해 awsPcaAuthorityArn, kmsKey, IAM 역할의 roleArn에 대한 인증서 arn을 추가합니다.

      이 서비스는 logConfiguration을 사용하여 stdoutstderr의 서비스 연결 프록시 출력을 Amazon CloudWatch Logs로 전송합니다. 이 작업 실행 역할에는 CloudWatch Logs 로그 그룹을 만드는 데 필요한 추가 권한이 없습니다. AWS Management Console 또는 AWS CLI를 사용하여 CloudWatch Logs에서 로그 그룹을 생성합니다. 이 로그 그룹을 생성하고 CloudWatch Logs에 프록시 로그를 저장하는 것이 좋습니다. 프록시 로그를 CloudWatch Logs로 전송하지 않으려면 logConfiguration을 제거합니다.

      { "cluster": "tutorial", "deploymentConfiguration": { "maximumPercent": 200, "minimumHealthyPercent": 0 }, "deploymentController": { "type": "ECS" }, "desiredCount": 1, "enableECSManagedTags": true, "enableExecuteCommand": true, "launchType": "FARGATE", "networkConfiguration": { "awsvpcConfiguration": { "assignPublicIp": "ENABLED", "securityGroups": [ "sg-EXAMPLE" ], "subnets": [ "subnet-EXAMPLE", "subnet-EXAMPLE", "subnet-EXAMPLE" ] } }, "platformVersion": "LATEST", "propagateTags": "SERVICE", "serviceName": "service-connect-nginx-service", "serviceConnectConfiguration": { "enabled": true, "services": [ { "portName": "nginx", "clientAliases": [ { "port": 80 } ], "tls": { "issuerCertificateAuthority": { "awsPcaAuthorityArn": "certificateArn" }, "kmsKey": "kmsKey", "roleArn": "iamRoleArn" } } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/service-connect-proxy", "awslogs-region": "region", "awslogs-stream-prefix": "service-connect-proxy" } } }, "taskDefinition": "service-connect-nginx" }
    2. service-connect-nginx-service.json 파일을 사용하여 서비스 생성:

      aws ecs create-service --cluster tutorial --cli-input-json file://service-connect-nginx-service.json

      출력:

      {
          "service": {
              "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/tutorial/service-connect-nginx-service",
              "serviceName": "service-connect-nginx-service",
              "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
              "loadBalancers": [],
              "serviceRegistries": [],
              "status": "ACTIVE",
              "desiredCount": 1,
              "runningCount": 0,
              "pendingCount": 0,
              "launchType": "FARGATE",
              "platformVersion": "LATEST",
              "platformFamily": "Linux",
              "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
              "deploymentConfiguration": {
                  "deploymentCircuitBreaker": {
                      "enable": false,
                      "rollback": false
                  },
                  "maximumPercent": 200,
                  "minimumHealthyPercent": 0
              },
              "deployments": [
                  {
                      "id": "ecs-svc/3763308422771520962",
                      "status": "PRIMARY",
                      "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
                      "desiredCount": 1,
                      "pendingCount": 0,
                      "runningCount": 0,
                      "failedTasks": 0,
                      "createdAt": 1661210032.602,
                      "updatedAt": 1661210032.602,
                      "launchType": "FARGATE",
                      "platformVersion": "1.4.0",
                      "platformFamily": "Linux",
                      "networkConfiguration": {
                          "awsvpcConfiguration": {
                              "assignPublicIp": "ENABLED",
                              "securityGroups": [
                                  "sg-EXAMPLE"
                              ],
                              "subnets": [
                                  "subnet-EXAMPLEf",
                                  "subnet-EXAMPLE",
                                  "subnet-EXAMPLE"
                              ]
                          }
                      },
                      "rolloutState": "IN_PROGRESS",
                      "rolloutStateReason": "ECS deployment ecs-svc/3763308422771520962 in progress.",
                      "failedLaunchTaskCount": 0,
                      "replacedTaskCount": 0,
                      "serviceConnectConfiguration": {
                          "enabled": true,
                          "namespace": "service-connect",
                          "services": [
                              {
                                  "portName": "nginx",
                                  "clientAliases": [
                                      {
                                          "port": 80
                                      }
                                  ]
                              }
                          ],
                          "logConfiguration": {
                              "logDriver": "awslogs",
                              "options": {
                                  "awslogs-group": "/ecs/service-connect-proxy",
                                  "awslogs-region": "us-west-2",
                                  "awslogs-stream-prefix": "service-connect-proxy"
                              },
                              "secretOptions": []
                          }
                      },
                      "serviceConnectResources": [
                          {
                              "discoveryName": "nginx",
                              "discoveryArn": "arn:aws:servicediscovery:us-west-2:123456789012:service/srv-EXAMPLE"
                          }
                      ]
                  }
              ],
              "roleArn": "arn:aws:iam::123456789012:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
              "version": 0,
              "events": [],
              "createdAt": 1661210032.602,
              "placementConstraints": [],
              "placementStrategy": [],
              "networkConfiguration": {
                  "awsvpcConfiguration": {
                      "assignPublicIp": "ENABLED",
                      "securityGroups": [
                          "sg-EXAMPLE"
                      ],
                      "subnets": [
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE"
                      ]
                  }
              },
              "schedulingStrategy": "REPLICA",
              "enableECSManagedTags": true,
              "propagateTags": "SERVICE",
              "enableExecuteCommand": true
          }
      }
                              

      제공한 serviceConnectConfiguration이 출력의 첫 번째 deployment 내부에 표시됩니다. 작업을 변경해야 하는 방식으로 ECS 서비스를 변경하면 Amazon ECS에서 새 배포를 생성합니다.

3단계: 연결할 수 있는지 확인

Service Connect의 구성 및 작동 여부를 확인하려면 다음 단계를 따라 외부 애플리케이션에서 웹 서비스에 연결합니다. 그런 다음 Service Connect 프록시가 생성하는 CloudWatch의 추가 지표를 참조하세요.

외부 애플리케이션에서 웹 서비스에 연결
  • 작업 IP 주소와 작업 IP 주소를 사용하는 컨테이너 포트에 연결

    AWS CLI를 사용하여 aws ecs list-tasks --cluster tutorial로 작업 ID를 가져옵니다.

    서브넷과 보안 그룹이 작업 정의의 포트에서 퍼블릭 인터넷의 트래픽을 허용하는 경우 컴퓨터에서 퍼블릭 IP에 연결할 수 있습니다. 하지만 퍼블릭 IP는 'describe-tasks'에서 제공되지 않으므로 단계 중 Amazon EC2 AWS Management Console 또는 AWS CLI로 이동하여 탄력적 네트워크 인터페이스의 세부 정보를 가져오는 작업이 포함됩니다.

    이 예시에서는 동일한 VPC의 Amazon EC2 인스턴스가 작업의 프라이빗 IP를 사용합니다. 애플리케이션은 nginx지만 server: envoy 헤더는 Service Connect 프록시가 사용됨을 보여줍니다. Service Connect 프록시는 작업 정의의 컨테이너 포트에서 수신 대기합니다.

    $ curl -v 10.0.19.50:80/
    *   Trying 10.0.19.50:80...
    * Connected to 10.0.19.50 (10.0.19.50) port 80 (#0)
    > GET / HTTP/1.1
    > Host: 10.0.19.50
    > User-Agent: curl/7.79.1
    > Accept: */*
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < server: envoy
    < date: Tue, 23 Aug 2022 03:53:06 GMT
    < content-type: text/html
    < content-length: 612
    < last-modified: Tue, 16 Apr 2019 13:08:19 GMT
    < etag: "5cb5d3c3-264"
    < accept-ranges: bytes
    < x-envoy-upstream-service-time: 0
    <
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html> 
                    
Service Connect 지표 보기

Service Connect 프록시는 CloudWatch 지표에 애플리케이션(HTTP, HTTP2, gRPC 또는 TCP 연결) 지표를 생성합니다. CloudWatch 콘솔을 사용하는 경우 Amazon ECS 네임스페이스에서 DiscoveryName, (DiscoveryName, ServiceName, ClusterName), TargetDiscoveryName, (TargetDiscoveryName, ServiceName, ClusterName)의 추가 지표 차원을 확인합니다. 이러한 지표 및 차원에 대한 자세한 내용은 Amazon CloudWatch Logs 사용 설명서의 View Available Metrics를 참조하세요.