AWS 기술 블로그

Amazon ECS에서 기존에 사용하던 서비스 검색 기능을 Amazon ECS Service Connect로 전환하기

본 게시글은 AWS Container Blog에 게시된 ‘Migrate existing Amazon ECS services from service discovery to Amazon ECS Service Connect by Jessica Deen, Hemanth AVS, and Satya Vajrapu’을 한국어 번역 및 편집하였습니다.

2022년 11월 re:Invent에서 서비스 간 통신을 위한 새로운 Amazon ECS(Amazon Elastic Container Service)의 새로운 기능인 Amazon ECS Service Connect출시했습니다. Amazon ECS Service Connect는 AWS Cloud Map 네임스페이스와 논리적 서비스 이름을 활용하여 마이크로서비스 간 통신 또는 Amazon Virtual Private Cloud(Amazon VPC) 간에 손쉽게 통신할 수 있게 해줍니다. 이를 통해 별도의 로드 밸런서를 배포, 구성, 유지 관리할 필요 없이 Amazon ECS 작업 간에 트래픽을 원활하게 분산할 수 있습니다.

이 게시글에서는 서비스 검색 및 내부 로드 밸런서를 사용하던 기존 Amazon ECS 작업을 Amazon ECS Service Connect로 전환하는 방법을 중점적으로 알아보겠습니다.

개요

기존 Amazon ECS 서비스를 Amazon ECS Service Connect로 전환하는 것이 얼마나 쉬운지 보여드리기 위해 GitHub에서 호스팅되는 샘플 Yelb 애플리케이션을 사용하겠습니다. 이 애플리케이션은 내부 로드 밸런서와 프라이빗 호스팅 영역의 별칭 레코드를 사용하여 yelb-appserver 서비스 검색을 수행하고, AWS Cloud Map을 사용하여 yelb-redis 및 yelb-db 서비스 검색을 수행합니다. 또한 최종 사용자가 yelb-ui 서비스에 접속할 수 있도록 외부 로드 밸런서를 사용합니다. 다음은 샘플 애플리케이션의 아키텍처 다이어그램입니다:

실습하기

이 샘플 애플리케이션이 제대로 작동하려면 1단계에서 다음 리소스를 생성해야 합니다:

  • Amazon VPC
  • 두 개의 가용 영역(Availability Zone, AZ)에 분산된 한 쌍의 퍼블릭 및 프라이빗 서브넷
  • 퍼블릭 서브넷에 기본 경로가 있는 인터넷 게이트웨이
  • 한 쌍의 NAT(Network Address Translation) 게이트웨이(각 AZ에 하나씩)
  • 프라이빗 서브넷에 기본 경로가 있는 NAT 게이트웨이
  • 샘플 Yelb 애플리케이션 작업 및 작업 실행 역할에 대한 AWS IAM(AWS Identity and Access Management) 역할
  • Yelb 앱 서비스 구성 요소에 대한 보안 그룹
  • Yelb 앱 구성 요소를 위한 서비스 검색 네임스페이스
  • 외부 로드 밸런서 1개 및 Yelb UI(User Interface) App을 노출하기 위한 대상 그룹
  • 내부 로드 밸런서 1개 및 Yelb App 서버를 노출할 대상 그룹
  • Amazon ECS 클러스터 1개
  • 배포된 Amazon ECS 서비스 및 작업 정의

사전 요구 사항

이 실습을 수행하려면 다음과 같은 사전 요구 사항이 필요합니다:

  • AWS 계정
  • 셸 환경에 대한 액세스. 셸 환경은 AWS Cloud9 인스턴스, AWS CloudShell 또는 시스템에서 로컬로 실행되는 셸일 수 있습니다.
  • 셸 환경에는 git이 설치되어 있어야 하며 AWS CLI(Command Line Interface)가 버전9.2 이상으로 구성되어 있어야 합니다.
  • 이 실습에 사용하려는 AWS 계정에 대한 액세스 권한으로 구성된 프로필이 AWS CLI에 있어야 합니다.
  • 아직 사용 설정하지 않은 경우 새 Amazon ECS 콘솔을 사용하도록 설정합니다. Amazon ECS 콘솔의 왼쪽 상단 모서리에 있는 라디오 버튼을 토글하여 활성화할 수 있습니다.

클래식 콘솔 환경과 새 콘솔 환경의 차이점에 대해 알아보려면 설명서를 확인합니다.

1단계  : 인프라 설정 샘플 배포

이 연습에 사용할 컴퓨터 또는 셸 환경에 샘플 코드를 다운로드합니다. 아직 수행하지 않은 경우 다음 명령을 실행하여 제공된 GitHub Repo의 복사본을 터미널에서 시스템으로 복제합니다.

git clone https://github.com/aws-samples/ecs-service-connect-yelb-sample-app && cd ecs-service-connect-yelb-sample-app

설치 과정을 간소화하기 위해 단계별 안내에 필요한 인프라, 서비스 및 작업 정의를 프로비저닝하는데 AWS CloudFormation 템플릿을 사용하게 됩니다.

선택한 셸 환경에서 간단한 설정 스크립트를 실행하여 제공된 AWS CloudFormation 템플릿을 배포합니다. 이 스크립트는 선택적으로 네 가지 인수를 허용합니다:

  1. AWS_PROFILE: 사용하려는 AWS CLI Profile 이름입니다. 값을 제공하지 않으면 기본값이 사용됩니다.
  2. AWS_DEFAULT_REGION: AWS CloudFormation 리소스가 배포될 기본 리전입니다. 값을 제공하지 않으면 오레곤 리전(us-west-2)이 사용됩니다.
  3. ENVIRONMENT_NAME : Amazon ECS 클러스터의 환경 이름입니다. 값을 제공하지 않으면 ecs로 사용됩니다.
  4. CLUSTER_NAME : Amazon ECS 클러스터의 이름입니다. 값을 제공하지 않으면 yelb-cluster가 사용됩니다.

오하이오(us-east-2) 리전에서 설치 스크립트를 네 가지 인수를 활용하여 다음 명령을 실행합니다.

./scripts/setup.sh my-profile us-east-2 my-ecs-environment my-ecs-cluster

콘솔을 통해 AWS CloudFormation 배포하려는 경우 여기에서 수행합니다.

참고: 배포한 위치에 대해 콘솔에서 올바른 리전을 선택해야 합니다.

설치 스크립트가 완료되는 데 약 5분이 걸립니다.

참고: 설치 스크립트가 완료된 후에도 모든 서비스 및 작업이 RUNNING 상태가 되는 데 약간의 추가 시간이 걸릴 수 있습니다.

배포가 성공적으로 완료되면 다음과 유사한 출력이 표시됩니다.

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - yelb-serviceconnect

 Access your Yelb application here: http://yelb-serviceconnect-382017218.us-east-2.elb.amazonaws.com/

제공된 URL을 사용하여 배포된 로드 밸런서를 통해 샘플 애플리케이션을 봅니다. AWS CloudFormation 출력에서도 이 URL을 찾을 수 있습니다. 다음은 예입니다.

다음은 조금 전 배포한 샘플 애플리케이션의 예입니다.

Amazon ECS 콘솔로 이동하여 모든 서비스 및 작업이 실행 중 상태인지 시각적으로 확인합니다.

참고: AWS CloudFormation 템플릿을 배포하기 위해 선택한 리전에 대한 Amazon ECS 콘솔을 보고 있는지 확인해야 합니다.

모든 작업과 서비스가 RUNNING 상태이면 Amazon ECS 클러스터는 다음 예와 같습니다.

2단계  : 내부 로드밸런서를 위한 트래픽 생성

이제 샘플 애플리케이션과 필요한 모든 인프라가 배포되었으므로 애플리케이션 엔드포인트를 사용하여 일부 트래픽을 생성할 준비가 되었습니다. 다음 명령을 실행하여 엔드포인트로 트래픽을 전송합니다.

./scripts/generate-traffic.sh

스크립트가 실행되는 동안 Amazon ECS 클러스터의 서비스, 특히 yelb-appserver를 확인합니다. 과도한 부하로 인해 작업이 실패하기 시작할 수 있습니다. 아래는 아직 자가 복구 중이지만 실패한 작업이 있는 서비스의 예입니다:

이 경우 브라우저에서 애플리케이션 URL과 /api/getvotes 경로(예 – http://yelb-service-connect.us-east-2.elb.amazonaws.com/api/getvotes)로 Yelb 앱서버 API에 액세스하려고 하면 다음과 유사한 500 시리즈 오류가 표시될 수도 있습니다:

이처럼 손실된 요청은 부하 테스트 시 높은 부하로 인해 yelb-appserver 작업이 실패하기 시작했기 때문입니다. Amazon ECS가 자체적으로 복구되고 스핀업되면 새 작업은 필요한 DNS(Domain Name System) 레코드를 생성하는 데 Amazon Route 53에 추가 시간이 걸리므로 DNS 전파가 지연될 수 있습니다. 해당 주제는 Amazon ECS Service Connect로 업그레이드한 후 7단계에서 다시 다룰 예정이므로 이 점을 염두하시기 바랍니다.

스크립트가 완료되면 다음과 유사한 메시지가 표시됩니다.

Successfully created/updated stack - hey-loadtest

 Running Hey Loadtest with 100 workers and 10,000 requests for 2 minutes...

 Please wait...

Hey Loadtest for: http://yelb-serviceconnect-319970139.us-east-2.elb.amazonaws.com/ complete!
View the Amazon EC2 Load Balancer Console here: https://console.thinkwithwp.com/ec2/home#LoadBalancers
Be sure to choose the correct region for your deployment.

 3단계  : 서비스 검색 내부 로드밸런서에 대한 모니터링 지표 보기

방금 생성한 트래픽을 보려면 2단계의 스크립트에서 제공된 링크를 사용하거나 Amazon EC2 로드 밸런서 대시보드의 모니터링 지표 탭을 사용합니다. 반드시 실습 시 배포한 리전을 선택합니다.

로드 밸런서 콘솔에 위치해 있다면 internal-serviceconnect-appserver-xxxx와 유사한 DNS 접두사 이름이 있는 serviceconnect-appserver 인스턴스를 선택합니다. 다음은 예입니다.

serviceconect-appserver 페이지 내에서 모니터링 탭으로 이동합니다.

모니터링 탭에서 시간 설정을 1시간 주기로 변경하면 아래 예와 유사한 스파이크 요청을 볼 수 있습니다.

4단계  : AWS Cloud Map 네임스페이스

Amazon ECS Service Connect로 업그레이드할 준비가 거의 완료되었지만, 업그레이드하기 전에 AWS CloudFormation 템플릿 배포 중에 생성된 AWS Cloud Map 네임스페이스에 대해 말씀드리고자 합니다. AWS Cloud Map 콘솔로 이동하면 생성된 두 개의 네임스페이스를 볼 수 있습니다.

참고: AWS Cloud Map 콘솔에 네임스페이스가 표시되지 않으면 배포한 리전이 맞는지 확인합니다.

다음은 표시되는 내용의 예입니다.

한 네임스페이스는 서비스 검색용이고 다른 네임스페이스는 Amazon ECS Service Connect용입니다. Amazon ECS Service Connect 네임스페이스(예 – yelb.sc.internal)를 클릭하고 아래로 스크롤합니다. 현재 연결된 서비스가 없음을 알 수 있습니다.

또한 왼쪽의 네임스페이스 아래에 있는 새로운 Amazon ECS 콘솔에서 AWS Cloud Map 네임스페이스에 대한 액세스를 찾을 수 있습니다. 다음은 예입니다.

yelb.sc.internal의 네임스페이스를 선택하면 연결된 서비스가 없음을 알 수 있습니다. 서비스를 Amazon ECS Service Connect로 이동하고 변경 사항을 확인한 후 이 네임스페이스를 주시합니다.

5단계  : Amazon ECS Service Connect 전환

이제 서비스 검색에서 Amazon ECS Service Connect로 전환할 준비가 되었습니다. 전환이 완료되면 샘플 애플리케이션 아키텍처는 다음과 같습니다.

이 예제에서는 AWS CLI를 사용하여 이 샘플 애플리케이션을 구성하는 4개의 서비스를 업데이트합니다.

전환에 필요한 명령들을 포함한 스크립트를 실행하여 Amazon ECS Service Connect로 전환을 진행합니다.

./scripts/use-service-connect.sh

스크립트 실행이 완료되면 다음 예와 유사한 출력이 표시됩니다.

Updating yelb-db...
Updating yelb-redis...
Updating yelb-appserver...
Updating yelb-ui...
Amazon ECS Service Connect migration complete!

좋습니다! 이제 Amazon ECS Service Connect로 전환이 완료되었습니다. Amazon ECS 콘솔로 돌아가서 Amazon ECS Service Connect 네임스페이스를 확인하겠습니다. 이제 4개의 yelb 서비스가 연결된 것을 볼 수 있습니다. 다음은 예입니다.

참고: 서비스 검색에서 Amazon ECS Service Connect로 전환이 완료되는 동안 Amazon ECS 서비스 및 작업이 다시 Active 또는 Running 상태가 되는 데 시간이 걸릴 수 있습니다.

6단계  : 무엇이 바뀌었나요?

./scripts/use-service-connect.sh 스크립트를 실행했을 때 변경된 사항을 분석해 보겠습니다.

코드 편집기에서 ./scripts/use-service-connect.sh 파일을 엽니다. 스크립트 끝에 사용된 aws ecs update-service 명령, 특히 -service-connect-configuration 플래그를 주목합니다. 이 플래그는 새로운 Amazon ECS Service Connect 구성을 사용하도록 Amazon ECS 서비스를 업데이트합니다.

ecs update-service 명령에 대한 AWS CLI 설명서를 보면 –service-connect-configuration 플래그가 JSON 구조로 보여지는 것을 알 수 있습니다.

참고: 현재 Service Connect Configuration 구성 파일로 JSON유형 만 사용할 수 있습니다.

위 지침을 스크립트와 상호 참조하면 각 명령이 37행부터 참조되는 JSON 파일과 함께 해당 플래그를 사용한다는 것을 알 수 있습니다. 다음은 yelb-db 서비스에 대한 업데이트 서비스 명령의 예입니다.

aws ecs update-service \
    --region "${AWS_DEFAULT_REGION}" \
    --cluster $CLUSTER_NAME \
    --service $SVC_DB \
    --service-connect-configuration file://sc-update/svc-db.json >/dev/null

–service-connect-configuration 플래그는 GitHub 리포지토리의 sc-update/ 디렉터리에 있는 svc-db.json 파일을 참조합니다. sc-update/svc-db.json 파일을 열어 2번째 줄에 enabled 키 값이 true 값으로 설정되어 있는지 확인합니다. 다음은 동일한 svc-db.json 파일의 예시입니다:

{
  "enabled": true,
  "namespace": "yelb.sc.internal",
  "services": [
    {
      "portName": "yelb-db",
      "clientAliases": [
        {
          "port": 5432,
          "dnsName": "yelb-db.yelb.cloudmap.internal"
        }
      ]
    }
  ],
  "logConfiguration": {
    "logDriver": "awslogs",
    "options": {
      "awslogs-group": "ecs/serviceconnectdemo",
      "awslogs-region": "us-east-2",
      "awslogs-stream-prefix": "db-envoy"
    }
  }
}

위의 샘플 코드 스니펫에서 10번째 줄에 있는 dnsName 키에 주목합니다. 여전히 로드 밸런서의 서비스 검색 ID를 가리키고 있음을 알 수 있습니다. 클라이언트 Amazon ECS 서비스에서 애플리케이션을 변경하지 않으려면 해당 키를 클라이언트 애플리케이션이 기본적으로 사용하는 이름과 동일하게 설정합니다. 이 경우 yelb-db.yelb.cloudmap.internal가 사용됩니다.

더 많은 예제를 보려면 sc-update 디렉터리에 있는 svc JSON 파일을 클릭하여 각 서비스에 대한 Amazon ECS Service Connect 구성을 확인합니다.

7단계  : Amazon ECS Service Connect 내부 로드밸런서에 대한 모니터링 지표 보기

전환이 완료되면 Amazon ECS 콘솔로 이동하여 모든 서비스 및 작업이 실행 중 상태인지 확인합니다. 기존 작업을 중지하고 새 작업으로 교체해야 하므로 시간이 다소 걸릴 수 있습니다. 새 작업은 다음 예제와 같이 표시되어야 합니다:

모든 서비스와 작업이 RUNNING 상태에 있으면 다음 명령을 사용하여 애플리케이션 엔드포인트에 대한 트래픽을 다시 생성합니다.

./scripts/generate-traffic.sh

부하 테스트가 실행되는 동안 이전에 부하 테스트를 실행했을 때와 마찬가지로 Amazon ECS 클러스터의 서비스를 주시합니다.

작업은 실패하고 이전처럼 자가 복구를 시도합니다. 다음은 또 다른 예입니다.

그러나 애플리케이션 URL + /api/getvotes 경로(예: http://yelb-service-connect.us-east-2.elb.amazonaws.com/api/getvotes)를 사용하여 Yelb 앱 서버 API에 액세스하려고 하면 2단계에서와 같은 500 시리즈 오류가 표시되지 않습니다. 이는 Amazon ECS Service Connect가 요청을 처리하는 방식 때문이며, 더 이상 Amazon Route 53의 DNS 호스팅 영역에 의존하지 않기 때문에 지연 시간이 늘어날 수 있지만 요청이 중단되는 일은 없을 것입니다.

3단계에서 수행한 것처럼 Amazon EC2 로드 밸런서 콘솔로 이동하여 앱 서버의 내부 로드 밸런서를 다시 선택합니다. 모니터링 탭에서 서비스 검색에서 Amazon ECS Service Connect로 서비스를 전환한 후 앱 서버 트래픽이 더 이상 내부 로드 밸런서에서 제공되지 않는 것을 확인할 수 있습니다. 이는 요청 대시보드에 새 트래픽이 표시되지 않는 것으로 알 수 있습니다. 다음은 예시입니다:

리소스 정리하기

향후 요금이 부과되지 않도록 하려면 본 게시글에서 생성한 리소스를 정리합니다. 더 쉽게 사용할 수 있도록 ./scripts/cleanup.sh 스크립트를 만들었습니다.

다음 명령을 실행합니다:

./scripts/cleanup.sh

참고: 정리 스크립트를 완료하는 데 약 20 – 25분이 소요됩니다.

결론

축하합니다! 방금 서비스 검색에서 새로운 Amazon ECS Service Connect로 전환하는 방법을 배웠습니다! Amazon ECS Service Connect에 대해 자세히 알아보려면  Amazon ECS Service Connect: Simplified interservice communication sessionAmazon ECS Service Connect documentation를 참조하세요.

Seongjin Ahn

Seongjin Ahn

안성진 Solutions Architect는 다양한 고객 인프라 운영 경험을 바탕으로 AWS 서비스의 효율적인 사용을 위해 Startup 고객에게 기술을 지원하는 역할을 합니다.