AWS 배포 완벽 가이드 | Section 11

김민지·2024년 12월 25일

Section 11 | AWS Elastic Container Service (ECS)

Redis service 생성하고 Service Discovery 적용하기

  1. ECS로 들어가서 my-express-cluster라는 이름의 cluster 하나 만들기 (Fargate 사용하도록 설정)
  2. task definition 들어가서 redis-td 생성하기: 0.5 CPU, 1GB 메모리로 생성
    container 이름은 redis, image URL은 redis, container PORT는 6379, container App protocol은 None으로 설정해야 함


  3. 앞서 만들어둔 my-express-cluster Cluster에 들어가서 service 생성: LaunchType으로 설정!! Task definition에 미리 생성해둔 redis-td 선택

  4. 내부적인 통신을 위해 Service Connect를 활용 (덕분에 Loadbalancing이 필요없어짐)
    client / server 구분방법: 요청을 받으면 무조건 server, 요청을 보내면 client임. 따라서 redis는 서버이고, express app은 client일 것임.
    Port mapping이 최소한 하나는 필수라서, Port alias로는 task definition의 port 이름을 선택해주고, PORT는 6379로 통일해줌
  5. 나머지는 디폴트로 두고 서비스 생성
  • 💥 계속 생성 실패
    IAM 검색해서 들어가서 Roles 중에 ecsTaskExecutionRole에 들어가서 add Permission 들어가고, create inline policy 선택, Cloud watch log 검색해서 선택, Write 중 CreateLogGroup 체크, Resorces로는 All에 체크, policy 생성 후 다시 시도해보기

Private Image 배포 전략 알아보기

  • AWS ECR에 이미지를 안전하게 올리기 위해 먼저 AWS CLI 설치하기
    이를 위해서는 먼저 IAM User를 생성해야 함 (콘솔에 접근하기 위해서)

1. AWS Elastic Container Registry (ECR)에 private repository 생성하기

ECR 검색해서 들어간 후 아래와 같이 repository 생성 클릭

디폴트가 Private repository이므로 그대로 두고, 이름에 Express라고 적기
나머지 설정은 디폴트로 두고 생성!

2. ECR private repository에 이미지 push할 수 있는 IAM user 만들기

  1. policy 만들기
  • 참고 AWS docs: 링크의 2개의 json 코드 중, resorce를 현재 push하고자 하는 resorce로 제한하는 버전의 코드를 선택하기 (아래)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:CompleteLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:InitiateLayerUpload",
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage",
                "ecr:BatchGetImage"
            ],
            "Resource": "arn:aws:ecr:region:111122223333:repository/repository-name"
        },
        {
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        }
    ]
}
  • IAM 검색해서 들어가기 → Policy 에 들어가기 → 새로운 Policy 만들기 → JSON 선택하기 → 앞에서 복사해둔 JSON 코드 붙여넣기
  • 코드의 resource 부분만 수정해주면 됨
    region: 현재 URL의 region 정보만 복사해서 붙여넣기

    ID: repository의 맨 앞 숫자 복사해서 붙여넣기

    repository-name: 마지막 부분 이름 복사해서 붙여넣기
"Resource": "arn:aws:ecr:<region>:<ID>:repository/<repository-name>"
  • 그 후에 Policy detail 입력 부분에서 Policy 이름으로는 privateExpressECR_imagePush로 설정 후 policy 생성
  1. user 만들기
    이름: expressGithubAction

3. AWS CLI 설치 및 로그인

  1. AWS CLI 설치 확인: aws --version
  2. AWS CLI 로그인을 위한 키 생성
    앞서 생성해둔 User에서 Create Access key 선택하기


    이후에는 특별히 다른 것 선택 없이 키 생성
  3. AWS CLI 로그인
    aws configure 입력 후 키를 차례로 입력해주기

4. AWS CLI 이용해서 안전하게 ECR로 이미지 업로드하기

  • repository로 들어가서 view push commands 클릭 후 Use the AWS CLI로 끝나는 1번 명령어 복사해서 express 프로젝트에서 연 VSCode 터미널에 4개의 command 모두 순서대로 붙여넣어서 실행하기



  • push 후에는 다시 repository 들어가서 image 확인하면 다음과 같이 push되어있음

5. ECR private repository 이미지로 AWS ECS service 생성하기

  1. task definition 생성하기
  • ECS 검색 후 task definition에 들어가서 my-express라는 이름의 새로운 task definition 생성하기
  • Container에 들어갈 Image URI로는 ECR의 repository로 다시 가서 URL을 복사해오기

  • 환경변수 설정을 해줘야 함
  • 이 때, REDIS_URL로는 cluster 열어서 들어가고, service 들어가고, configuration and networking 들어가서 Service Connect services에서tcp:// 부분은 빼고 복사해서 붙여넣고 맨 앞에는 redis://를 추가하기

  • 나머지는 디폴트로 그대로 둔 채로 task definition 생성하기
  1. service 생성하기
  • cluster에 들어가서 service create 누르기

  • Namespace로는 my-express-cluster로 설정


  • Load balancer의 DNS URL으로 연결
  • Cluster의 Service redisexpress-serviceexpress-service로 들어가서 view load balancer 눌러서 들어가고, load balancer의 DNS name으로 접속하면 express 서버 접속 가능!


무중단 배포: Green/Blue Strategy

  • 코드 버전을 업데이트할 때 어떻게 변화해야 할지 생각해보자

  • 명령어의 가장 끝에 latest 대신에 버전을 명시해주자.

  • task definition에서, 아래의 사진과 같이 선택하고 create new revision을 누르면 my-express:1을 기준으로 새로운 버전을 만들어달라는 의미임

  • 나머지는 전부 그대로 두고 container의 image URL에서 :latest만 2로 바꿔주면 새로운 버전의 task definition이 생김

  • service로 들어가서 update service 클릭하고 다른 수정사항 없이 revision만 2 (latest)로 수정해주기


  • Self-healing: AWS ECS service는 죽은 서버(테스크)를 자동으로 살려낸다.

AWS ECS Service를 이용한 Autoscaling 적용하기

  • 설정해야 하는 3가지 종류:
    (1) trigger 조건
    (2) scale-out (확장), scale-in (축소)
    (3) 변화 단위 (예: n개, n% ...)
  1. update service 들어가기
  2. service auto scaling 사용 선택
  3. Add scaling policies 선택: Target tracking에 비해 Step scaling은 좀 더 복잡하고 컨트롤할 수 있는게 많음
    예: 최대/최소/평균 값이, n분/n시간 동안 <threshold> %에 비해 클 때/크거나 작을 때/작거나 같을 때/작을 때 알람을 n분 이내에 trigger 해라.
    trigger 되면task/percentagen 만큼 추가해라/으로 설정해라/만큼 제거해라
    사진의 설정: 평균 값이 1분 동안 50%에 비해 크면 1분 안에 trigger해라.
    trigger 되면 task를 1만큼 추가해라.

    cooldown period는 디폴트대로 300으로 설정
  4. load-test.yml 에서 loadbalancer의 DNS 주소를 가지고 부하를 주기: artillery run load-test.yml
# load-test.yml
config: 
  target: http://express-lb-2076134438.ap-northeast-2.elb.amazonaws.com
  phases: 
    - duration: 3000
      arrivalRate: 1500

scenarios: 
  - flow: 
    - get: 
        url: "/fibo/35"
  • 하나 늘어나서 4 desired 가 됨.

AWS Secret Manager를 이용해서 시크릿키 안전하게 관리하기

  1. 환경변수를 secret manager에서 잘 불러왔는지를 확인하기 위한 코드 추가하기
const { hello } = process.env;
console.log({ hello });
  1. ver.3으로 해서 다시 push
    ECR > Private Repository > Repositories > express 로 들어가서 push commands 확인 후 버전명만 바꿔가며 push해주기
  2. AWS Secret Manager로 검색해서 들어가기
  3. dummy data를 secret에 저장해주기: secret 이름은 my-express-secrets
  4. Secret ARN 복사해두기
  5. IAM 검색해서 들어가고, Role 중 현재 사용중인 Role인 ecsTaskExecutionRole에 들어가서 createInlinePolicies 클릭
  6. JSON 타입 선택 후 Action과 Resorce 수정
    "Action": "secretsmanager:GetSecretValue", "Resource": <ARN값>
  7. policy 이름 expressSecretManagerReadAccess 로 짓고 생성
  8. ECS로 돌아가서 task definition 업데이트: container에서 imageURL 버전 수정
  9. 환경변수 추가 후 value에 앞서 복사했던 ARN 값 붙여넣고 뒤에 :hello:: 추가하기
  10. Update service


0개의 댓글