반응형
저번 포스트에서는 Deploy단계에서 S3에서 이미지를 불러와서 오류가 발생했던 부분을 수정했었다. 이번에는 그 다음에 새롭게 발생한 ECS 실행 오류를 해결한다.
1. 배포오류 (Memory 부족 문제)
1-1. 오류 파악
- 저번 포스트에 이어서 빌드를 진행했더니 아래와 같이 배포단계에서 무한로딩이 발생했다.
- 계속 진행중이 떠서 답답해서 ECS 클러스터에 들어가서 확인해 봤다. 아래와 같이 배포에서 실패한 작업이3번이었다.
1-2. 이벤트 메시지 확인
- 이벤트의 메시지를 확인해봤더니 다음과 같았다. "Amazon ECS가 recipia-member-service 서비스의 요구 사항을 충족하는 컨테이너 인스턴스를 찾지 못했음을 나타낸다." 특히, 가장 근접한 매치인 컨테이너 인스턴스 15ce592c569442ec8c9437a689ed8191는 필요한 메모리가 부족하여 태스크를 배치할 수 없다.
즉, 이 오류는 메모리가 부족하다는 것이었다… 프리티어인 t2.micro를 사용중인데 이것때문인것 같다.
1-3. 오류 해결
- 간단했다. t2.micro를 t2.small로 1GB의 메모리를 2GB로 올려주었다.
- 기존의 ECS클러스터를 삭제하고 새롭게 EC2설정을 해서 클러스터를 만들었다.
1-4. Codepipeline 실행하기
- 이후 다시 Codepipe를 실행했다. 우측 상단에 있는 “변경 사항 릴리스”를 클릭한다.
- “릴리스” 버튼을 클릭하면 다시 Codepipe가 실행된다.
- 근데 이번에도 Deploy가 무한로딩이었다....
2. 배포오류 (포트 충돌 문제)
2-1. Deploy 무한로딩
- 이번에도 Deploy에서 실패메시지는 안나왔지만 계속해서 무한로딩을 하는 현상이 발생했다.
2-2. ECS 컨테이너 배포상황 확인
- ECS 컨테이너로 들어와서 태스크가 제대로 실행되었는지를 확인했는데 "실패한 작업"이 5개나 있었다.
2-3. ECS 서비스 진행 메시지 확인하기
- “ECS클러스터 > 서비스”로 들어가서 상단의 “이벤트”를 눌러서 메시지를 확인했다.
2-4. 이벤트 메시지 분석
- 지금 이 상황에서는 기존에 실행 중인 ECS 태스크와 새로 배포하려는 태스크 사이에 포트 충돌이 발생하고 있는 것으로 보인다. AWS ECS에서는 기본적으로 동일한 호스트 인스턴스에서 동일한 포트를 사용할 수 없으므로, 이 문제를 해결하기 위해 몇 가지 접근 방법을 고려할 수 있다.
service recipia-member-service was unable to place a task because no container instance met all of its requirements. The closest matching container-instance f2af4a66bcce497d9c29d441598d2831 is already using a port required by your task. For more information, see the Troubleshooting section of the Amazon ECS Developer Guide.
- 동적 포트 매핑 사용:
- ECS 태스크 정의에서 동적 포트 매핑을 활성화하여 ECS가 사용 가능한 호스트 포트를 자동으로 선택하도록 할 수 있다. 그러나 이 방법은 Spring Boot 어플리케이션의 포트 설정을 변경해야 하므로, 어플리케이션의 구성을 변경해야 할 수 있다.
- 블루/그린 배포 사용:
- 블루/그린 배포 전략을 사용하여 새 서비스를 동일한 클러스터의 다른 호스트 인스턴스 또는 다른 클러스터에 배포할 수 있다. 이 방법을 사용하면 기존 서비스와 새 서비스를 동시에 실행할 수 있으며, 테스트 및 검증을 완료한 후 트래픽을 새 서비스로 전환할 수 있다.
- 기존 태스크 중지:
- 배포 프로세스의 일부로 기존 태스크를 수동으로 중지하고 새 태스크를 시작할 수 있다. 이 방법을 사용하면 포트 충돌을 방지할 수 있지만, 서비스 중단 시간이 발생할 수 있다.
- 다른 포트 사용:
- 새 태스크의 포트를 변경하여 포트 충돌을 방지할 수 있다. 그러나 이 방법은 어플리케이션의 구성과 ECS 태스크 정의를 변경해야 하므로, 추가 작업이 필요할 수 있다.
2-5. 오류 해결: 새로운 태스크 정의 만들기 (동적 포트 매핑 사용)
- 동적 포트 매핑 사용방식을 적용해보기로 했다. (포트 충돌 방지하기)
- 컨테이너에 동적 매핑을 해줘야 하므로 컨테이너 관련 포트 설정을 하는 "태스크 정의" 부터 새롭게 만들었다.
- 여기서 아래처럼 호스트 포트를 0으로 설정하고 컨테이너 포트를 8081로 설정하면 AWS ECS는 동적 포트 매핑을 사용하여 사용 가능한 호스트 포트를 자동으로 선택하고 할당한다.
2-6. ECS 서비스 만들기
- 기존에 존재하던 ECS서비스는 삭제하고 새롭게 서비스를 만들었다. 기존 서비스 설정은 그대로 따라가고 "패밀리"에만 방금 만든 "태스크 정의"를 선택해 줬다.
주의사항
- 참고로 Codepipeline을 작성할때 Deploy단계에서는 ECS의 클러스터와 서비스를 등록하게 되는데 만약 기존에 등록한 서비스의 이름이 지금 새롭게 생성하면서 바뀌었다면 CodePipeline에 들어가서 "편집"을 클릭해서 들어간다.
- 맨 하단의 Deploy단계에 등록된 것을 편집해줘야 한다.
- 아래와 같이 새로 만든 서비스를 다시 등록해줘야 동작한다. (서비스 이름이 같았다면 그냥 그대로둬도됨)
2-7. 다시 Codepipeline 실행
- 다시 Codepipeline을 실행했다. 그리고 배포에 성공했다.
- 배포 성공후에 Codepipeline 대시보드에는 아래와 같이 표시되었다.
3. 배포 성공 검증하기
당연히 배포후에는 SpringBoot가 잘 돌아가는지 검증을 해야한다. 다음과 같이 검증을 실시한다.
3-1. 로드 밸런서 확인하기
- EC2 메뉴로 들어가서 상단의 "리소스"를 확인한다. 여기서 "로드 밸런서"를 클릭해서 들어가 준다.
- 로드 밸런서에서 하단의 내가 만든 밸런서의 "이름"을 클릭해서 들어간다.
- 로드 밸런서의 "세부 정보"가 나올것이다.
- 여기서 하단의 DNS이름을 복사한다. (이게 앞으로 우리가 접속에 사용할 DNS다.)
3-2. tomcat 접속 확인하기
- 잠시 확인할 것은 나는 SpringBoot의 API로 "/member/test"에 요청을 보내면 "aws test success"를 return하도록 했다.
- 이제 ALB의 DNS명령어 뒤에 내가 Spring API로 생성한 GetMapping URI을 입력해 준다.
- 아래와 같이 성공적으로 결과를 반환했다.
많은 우여곡절을 통해 Github, ECR, ECS, ALB, IAM, S3, CodePipeline을 통해 CI/CD 구축에 성공했다. 다음 포스트에서는 중간중간 만났던 오류에 대한 분석과 앞으로의 개선 사항들에 대해서 적을 예정이다.
지금까지 CodePipeline CI/CD 시리즈의 긴 글을 봐주신 분들께 감사하는 마음을 전하고 싶다.
또한 이 CI/CD 구축 내용들은 혼자서 이룬것이 아니고 많은 도움을 준 동료가 있었다.
그 동료에게도 감사하는 마음을 전하고 싶다.
다음 시리즈는 ECS를 배포할때 Secrets Manager로 환경변수를 설정하는 방법을 설명한다. application.yml에 환경변수 값을 key로 작성해서 github에 push하고 ECS 태스크 정의에서 환경변수를 주입하는 방식이다. 아래의 글을 보는것을 추천한다.
2023.11.03 - [AWS] - AWS Secrets & ECS SpringBoot 설정 (1): Secret 생성
2023.10.30 - [AWS] - AWS CI/CD: CodePipeline 배포 오류 수정 (7편)
반응형
'AWS > CodePipeline, CICD' 카테고리의 다른 글
AWS CI/CD: CodePipeline 배포 오류 수정 (7편) (1) | 2023.10.30 |
---|---|
AWS CI/CD: CodePipeline 세 번째 빌드 오류 해결 (6편) (1) | 2023.10.30 |
AWS CI/CD: CodePipeline 두 번째 빌드 오류 해결 (5편) (1) | 2023.10.30 |
AWS CI/CD: CodePipeline 첫 번째 빌드 오류 해결 (4편) (2) | 2023.10.29 |
AWS CI/CD: CodePipeline 배포 및 검토 (3편) (0) | 2023.10.29 |