Yebali

AWS ECS 구축하기 (근데 이제 ALB를 곁드린...) 본문

AWS

AWS ECS 구축하기 (근데 이제 ALB를 곁드린...)

예발이 2024. 11. 4. 15:52

세상에는 서버를 배포하는 많은 방법이 존재합니다.

FTP로 수정된 파일을 서버에 직접 올리고 stop.sh, start.sh으로 Tomcat을 끄고키는 방법부터

k8s 환경에서 argocd를 사용하는 방법까지 다양합니다.

 

이번 포스트는 그중 AWS의 CodePipeline과 ECS를 사용해서 CI/CD를 만드는 방법에 대한 내용입니다.

 

AWS ECR 생성 및 Docker 이미지 업로드하기

가장 먼저 해야 할 일은 ECR을 생성하고 Docker 이미지를 업로드하는 일입니다.

이 포스트에서는 ECR에 Docker 이미지를 업로드하고 ECS가 ECR에서 이미지를 가져다가 배포하는 방식으로 다룰 예정입니다.

 

ECR(Elatic Container Repository)은 Docker이미지를 업로드할 수 있는 저장소입니다.

ECR은 AWS 콘솔에서 간단하게 생성할 수 있습니다.

 

ECR을 생성했다면 jib을 사용해 ECR에 이미지를 올려줍니다.

이것도 여러 방법이 있지만 저에게 가장 익숙한 jib을 사용했습니다.

// gradle.build.kts
plugins {
    id("com.google.cloud.tools.jib") version "3.4.4"
}

jib {
    from {
        image = "amazoncorretto:21"
    }

    to {
        image = "354918373096.dkr.ecr.ap-northeast-2.amazonaws.com/ecs-example"
        tags = setOf("latest")
        auth {
            username = "AWS"
            // aws ecr get-login-password --region ap-northeast-2
            password = "<TOKEN>"
        }
    }
}

 

gradle.build.kts 에 위와 같이 jib 플러그인을 추가하고, jib 블록에 base 이미지 정보와 업로드할 ECR 주소, 태그 등을 입력합니다.

'auth {}' 블록에는 ECR에 접근하기 위한 인증 정보를 넣어줍니다.

'username'은 'AWS'로 고정하고 'password'는 'aws ecr get-login-password --region ap-northeast-2' 명령을 실행해서 나오는 토큰 값을 입력해 줍니다.

참고로 'aws ecr get-login-password --region ap-northeast-2' 명령을 사용하기 위해서는
AWS콘솔에서 사용자를 만들고 해당 사용자에게 ECR에 업로드할 수 있는 권한을 주고 Access Key를 발급받아
'aws configure' 명령을 사용하여 aws cli를 사용하기 위한 자격증명을 설정해야 합니다.

 

위 설정들을 한 후 'gradle jib' 명령을 실행하면 AWS ECR에 이미지가 업로드됩니다.

 

Application Load Balancer 생성하기

일반적인 인프라 구성에서는 ECS를 외부에서 직접 호출하도록 허용하지 않습니다.

이 예시에서도 ECS 보다 앞에서 트래픽을 전달받아 ECS로 전달해 줄 ALB(Application Load Balancer)를 생성합니다.

 

 

ALB도 AWS 콘솔에서 간단하게 생성할 수 있습니다.

Load Balancer 생성에 가면 Application, Network, Gateway 3가지 타입이 있는데
외부에서 호출 가능한 간단한 LB로 만들기 위해 Application으로 생성해 주세요.

 

네트워크 매핑 부분에서는 VPC를 설정하는 과정이 있습니다.

만약 생성한 게 없다면 Default VPC를 사용해도 되고, 별도로 만들어 사용하고 싶다면 만드시면 됩니다.

단, 중요한 점은 추후 생성할 ECS Service와 동일한 VPC를 사용해야 합니다.

 

보안 그룹은 ALB를 위한 별도의 보안그룹을 만들어 할당해 주는 것을 추천합니다.

예제에서는 HTTPS는 사용하지 않을 예정이라 HTTP 통신 포트인 80번 포트를 보안 그룹 인바운드 규칙에 추가해 주세요.

만약 HTTPS를 사용하신다면 443번 포트를 규칙에 추가해 주시면 됩니다.

 

리스너는 추후 ECS Service에서 다시 추가해 줄 예정이기 때문에 ALB 생성 과정에서는 더미로 아무렇게나 만들어 주셔도 됩니다.

 

이후 위 과정을 마치면 '프로비저닝'과정을 거치고 ALB가 잘 생성된 것을 확인할 수 있습니다.

 

ECS Cluster 구성

ALB로 받은 트래픽을 라우딩할 ECS Cluster를 만들고 연결하는 과정입니다.

ECS Cluster 생성

 

ECS cluster 역시 AWS 콘솔에서 간단하게 생성할 수 있습니다.

인프라 탭에서 ECS Task가 실행할 환경을 별도로 관리하지 않는 AWS Fargate(서버리스)를 선택했습니다.

 

Task Definition 생성

ECS에서 실행 할 Task를 정의하는 과정입니다.

ECS Cluster를 생성할 때와 동일하게 Fargate를 선택하고, Task에 할당할 리소스(CPU, 메모리)를 선택합니다.

태스크 실행 역할은 새 역할을 생성하거나 'AmazonECSTaskExecutionRolePolicy' 정책을 가진 역할을 할당해주어야 합니다.

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

AmazonECSTaskExecutionRolePolicy 정책에는 ECR에 대한 접근 권한과 CloudWatch에 로그를 쌓기 위한 권한이 있습니다.

 

이미지 URI은 위에서 생성한 ECR의 주소 입력합니다.

그리고 항상 최신 버전을 배포하기 위해 ':latest' 태그를 포함시켰습니다.

 

예시로 배포하는 앱은 Spring 앱이고 actuator포트는 8081번으로 설정했기 때문에 

포트 매핑에서 각각 8080, 8081 포트를 매핑합니다.

 

ECS Service 생성

Task를 생성하고 관리하는 ECS Service를 생성합니다.

 

ECS Cluster 화면에서 '서비스'탭에 생성 버튼을 눌러 생성할 수 있습니다.

 

서비스 이름을 잘 지어줍시다.

 

아까 생성한 ALB와 동일한 VPC를 선택하고, 역시 별도의 보안 그룹을 생성해서 할당해주세요.

위 Task Definition 생성 과정에서 매핑한 8080, 8081 포트에 접속을 하기 위해 보안 그룹에서도
8080, 8081 포트를 인바운드 규칙에 추가해주어야 합니다.

 

'로드 밸런싱' 탭에서 아까 생성한 ALB를 설정합니다. 

트래픽을 수신할 포트는 8080으로 설정합니다.

 

ECS Service를 생성할 때 ALB를 설정해주지 않고, ALB '대상 그룹'에서 직접 '대상'에 Task를 추가하면
Task가 새로 배포되었을 때 ALB가 트래픽을 라우팅 할 Task를 찾지 못하는 문제가 발생합니다.

 

Service 생성할 때 설정하는 방법 외에 다른 해결 방법을 아시는 분은 댓글로 알려주시면 감사하겠습니다.

 

새로운 대상 그룹을 추가할 때, 모든 트래픽이 해당 대상 그룹으로 라우팅 될 수 있게 '/*' 경로를 설정합니다.

그리고 sprint actuaotor의 health check 경로인 '/actuator/health'를 상태 확인 경로 값으로 설정합니다.

 

다만, Service를 생성할 때는 상태 확인 경로의 포트까진 설정할 수 없어서 추후 '대상 그룹' 메뉴에서 수정해주어야 합니다.

 

ECS Service를 생성을 완료하면 위 사진처럼 Service가 관리하는 Task가 생성되는 것을 확인할 수 있습니다.

 

그리고 ALB에서 '리소스 맵'을 확인하면 ALB -> 리스너 -> 대상그룹 -> 대상(Task)까지 잘 연결된 것을 확인할 수 있습니다.

 

이때 'DNS 이름'이 ALB를 호출할 수 있는 경로입니다.

배포한 앱에 만들어둔 '/hello' API를 호출하면 정상적으로 요청이 처리된 것을 확인할 수 있습니다. 

 

이로써 ALB + ECS를 사용해 간단하게 인프라를 구축했습니다.

다음 과정은 AWS CodePipeline을 사용하여 코드가 수정되면 자동으로 ECS의 Task를 배포하는 방법을 알아보겠습니다.

 

AWS CodePipeline으로 ECS 배포하기

AWS ECS 구축하기 (근데 이제 ALB를 곁드린...)세상에는 서버를 배포하는 많은 방법이 존재합니다.FTP로 수정된 파일을 서버에 직접 올리고 stop.sh, start.sh으로 Tomcat을 끄고키는 방법부터k8s 환경에서 a

yebali.tistory.com

 

'AWS' 카테고리의 다른 글

AWS CodePipeline으로 ECS 배포하기  (0) 2024.11.04
EC2 Linux Java 11 설치하기  (0) 2022.01.31
EC2 인스턴스 가상메모리 추가하기  (0) 2022.01.31