ECS에서 Zipkin을 통한 스프링 부트 서비스 트레이싱 구축하기
AWS ECS 환경에서 서비스 간 효율적인 통신 모니터링은 시스템의 안정성과 성능 향상에 필수적이다.
이 글에서는 ECS에서 이미 실행 중인 두 개의 스프링 부트 서비스 간의 통신을 Zipkin을 통해 모니터링하는 방법을 단계별로 설명한다. Zipkin은 분산 시스템에서 서비스 간 요청을 추적할 수 있는 강력한 도구이며, ECS 환경에서의 구현은 서비스의 성능 분석과 문제 해결에 큰 도움을 준다.
1. ECR 리포지토리 생성 및 Docker 이미지 빌드
💡 ECR에 Zipkin 이미지를 저장하는 것: 효율성과 안정성을 위한 전략
배경
- 이전 프로젝트에서 무중단 배포 과정 중 buildspec.yml을 통해 Docker Hub에서 이미지를 반복적으로 pull 받는 상황이 발생했다. 이 과정에서 Docker Hub의 요청 제한으로 인한 문제가 발생했고, 이로 인해 "과도한 이미지 pull 요청으로 인한 잠시 제한"이라는 에러 메시지를 받았다.
Zipkin 서버 설정을 변경하는 이유
- 이 경험을 바탕으로, Zipkin 서버 설정을 변경하기로 결정했다. 이제 Zipkin 이미지는 최초 한 번만 Docker Hub에서 로컬로 pull 받아 ECR에 저장하고, 이후 Zipkin 서버의 재기동이 필요할 때는 ECR에 저장된 이미지를 사용하기로 했다.
이점
- 이 접근 방식은 네트워크 지연 시간을 줄이고, AWS 내부 리소스를 활용함으로써 이미지 접근 속도를 향상시킨다. 또한, 이는 Zipkin 서비스 관리를 단순화하며 AWS 환경에서의 서비스 운영을 최적화하는데 중요한 역할을 한다. 결과적으로, 이 방법은 안정적인 서비스 제공과 빠른 반응 시간을 동시에 달성하는 데 기여한다.
결론
- ECR에 Zipkin 이미지를 저장하는 것은 선택 사항이지만, 이전 경험을 통해 배운 교훈을 바탕으로, 이러한 접근법을 채택함으로써 서비스의 안정성과 효율성을 크게 향상시킬 수 있다. 이는 무중단 배포 환경에서 매우 중요한 고려 사항이며, AWS를 사용하는 환경에서 더욱 효과적이다.
1-1. AWS ECR에 Zipkin 용 리포지토리를 생성한다.
- ECR 생성하는 방법은 아래 링크에 정리되어있다.
[AWS] ECS 생성1 - ECR 생성하기 (M1 Mac 제외)
1-2. 로컬 환경에서 Dockerfile을 생성한다.
- Dockerfile에는 아래와 같이 Zipkin의 공식 Docker Hub 이미지를 작성한다.
FROM openzipkin/zipkin
1-3. 로컬에서 터미널에 접속해 AWS ECR에 로그인한다.
aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com
1-4. Docker 명령어를 이용해 도커 이미지를 빌드하고 푸시한다.
- 내가 사용할 서비스를 실행할 컨테이너 EC2가 ARM 아키텍처이므로, 'buildx' 명령어를 사용하여 ARM용 도커 이미지를 빌드한다.
docker buildx build --no-cache --platform=linux/arm64 -t <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/<ECR_REPOSITORY_NAME>:<TAG> . --push
멀티 플랫폼에서 도커 이미지를 빌드하는 과정은 아래 링크에 정리되어 있다.
[Docker] 멀티-플랫폼 이미지 빌드 명령어 (여러 운영체제 호환 가능한 도커 이미지 빌드)
2. NACL(네트워크 ACL) 설정하기
💡 ECS에서 Zipkin 사용을 위한 보안 설정: 포트 9411 열기
Zipkin 서비스의 포트 이해
- Zipkin은 기본적으로 9411 포트를 사용하여 서비스를 제공한다. 이 포트는 Zipkin의 UI에 접근하고, Zipkin 서버로 트레이스 데이터를 전송하는 데 사용된다.
보안 그룹 설정의 중요성
- 보안 그룹은 AWS에서 인스턴스로의 네트워크 트래픽을 제어하는 데 사용된다.
- Zipkin 서비스가 ECS에서 실행될 때, 보안 그룹에서 9411 포트를 열어줌으로써, 외부의 사용자 및 다른 서비스가 Zipkin 서버에 접근할 수 있도록 한다.
- 특히, 이 포트를 통해 애플리케이션은 Zipkin 서버에 트레이스 데이터를 보낼 수 있으며, 사용자는 웹 브라우저를 통해 Zipkin의 UI에 접근할 수 있다.
NACL 설정의 역할
- NACL은 서브넷 레벨에서 트래픽을 제어한다.
- 보안 그룹이 인스턴스 레벨에서 트래픽을 제어하는 것과 달리, NACL은 보다 넓은 범위의 네트워크 트래픽을 제어한다.
- NACL에서도 9411 포트를 열어줌으로써, Zipkin 서버가 위치한 서브넷에서 들어오고 나가는 트래픽이 원활하게 이루어지도록 한다.
결론
- Zipkin 서비스를 ECS 환경에서 효과적으로 운영하기 위해서는 9411 포트의 네트워크 트래픽이 보안 그룹과 NACL 양쪽에서 모두 허용되어야 한다. 이는 Zipkin 서비스의 접근성과 기능성을 보장하며, 서비스 간 트레이싱과 모니터링을 원활하게 수행할 수 있도록 한다. 이러한 설정은 서비스의 안정성과 가용성을 높이는 데 필수적이며, AWS 환경에서의 서비스 관리에 있어서 중요한 부분이다.
2-1. NACL 콘솔 들어가기
2-2. 지금 사용 중인 VPC 선택
- 내가 사용중인 VPC가 뭔지 잘 모르겠자면 스크롤을 오른쪽으로 넘겨서 "인바운드 규칙 수"가 가장 많은 걸 선택하면 대체로 맞다.
- 해당 ACL을 클릭해 들어간다.
2-3. 9411 port 열어주기
- 상세 정보로 들어와 "인바운드 규칙 편집"을 클릭한다.
2-4. 아래와 같은 화면에서 "새 규칙 추가"를 눌러 zipkin 포트인 9411을 TCP로 추가한다.
- 지금 규칙번호 200을 보면 모두 허용으로 되어있는데 이는 아직 개발 단계이기 때문에 이렇게 허용한 거고 추후에는 거부로 수정해야 한다.
2-5. "변경 사항 저장"을 누르면 NACL 인바운드 규칙에 9411이 잘 추가된 모습을 볼 수 있다.
3. 보안 그룹 설정하기 (NACL은 이미 모든 연결 허용인 상태)
3-1. 보안 그룹 들어가기
- EC2 콘솔 창에서 "보안 그룹"을 클릭한다.
3-2. 보안 그룹 선택
- 나는 Zipkin 서버를 ECS 서비스로 올릴 예정이다.
- 그렇기 때문에 ECS 클러스터에서 사용 중인 보안 그룹을 선택해야 한다.
- (사실 이때도 잘 모르겠다면 스크롤 넘겨서 "인바운드 규칙 수"가 가장 높은 걸 선택하면 대체로 맞다.)
3-3. 인바운드 규칙 편집
- 보안 그룹 상세페이지로 넘어와서 "인바운드 규칙 편집"을 클릭한다.
3-4. 9411 port 추가
- 아래와 같이 TCP 9411 포트를 추가해 준다.
3-5. 인바운드 그룹 편집 완료
4. ECS 태스크 정의 생성
나는 기존에 사용하던 ECS 클러스터에 Zipkin 서비스를 등록할 예정이므로, ECS 클러스터 생성 과정은 여기서는 생략한다.
아래 링크에서 ECS 생성 예제를 확인할 수 있다.
4-1. 태스크 정의 생성
- ECS 대시보드에서 왼쪽 메뉴의 "태스크 정의"를 클릭한다.
4-2. 새 태스크 정의 생성
- 태스크 정의 목록 화면 우측에 "새 태스크 정의 생성 > 새 태스크 정의 생성"을 클릭한다.
4-3. 태스크 정의 구성 설정
- 여기서 작성하는 패밀리 명이 나중에 서비스 생성에서 보일 이름이다.
4-4. 인프라 요구 사항 설정
- 나는 EC2 인스턴스를 선택했다.
- 이미 사용 중인 클러스터 인스턴스 유형이 t4g라서 운영 체제는 "Linux/ARM64"를 선택했다.
- 네트워크 모드는 default로 둔다.
- 태스크 크기는 각자의 프로젝트에 맞춰서 설정해 준다.
- 태스크 실행 역할도 기본값으로 둔다.
4-5. 컨테이너 설정
- 이름에는 컨테이너 이름을 작성한다.
- 이미지 URI에는 위에서 생성한 Zipkin ECR URI를 복사해 온다.
- 포트 매핑은 호스트 포트, 컨테이너 포트 전부 9411로 설정해 준다.
- 로그 수집 사용을 체크해 준다.
- 그 뒤로 아무 설정은 건들지 않고 바로 "생성"버튼을 클릭한다.
5. ECS 클러스터에 Zipkin 서비스 생성
5-1. 클러스터 확인
- 나는 기존에 사용하던 클러스터에서 서비스를 생성할것이다. (기존에 사용중이던 클러스터가 없다면 만들고 오자.)
- 서비스 탭에서 "생성"버튼을 클릭한다.
5-2. 서비스 생성
- 컴퓨팅 구성은 "시작 유형"으로 선택한다.
- "시작 유형"을 EC2로 선택한다.
5-3. 배포 구성
- 애플리케이션 유형은 "서비스"로 둔다.
- 패밀리에는 아까 생성한 패밀리를 선택하고 개정은 "최신"을 선택한다.
- 서비스 이름을 작성한다.
5-4. 나머지 설정
- 나머지 설정은 건들지 않고 넘어간다.
- Zipkin은 주로 내부 서비스 간의 요청을 추적하며, 외부 트래픽에 대한 처리가 중점이 아니다. 그렇기 때문에 ALB(Application Load Balancer) 같은 외부 로드 밸런서가 필요 없으며, 내부 네트워크를 통한 연결만으로 충분하다.
5-5. 서비스가 생성이 되고 배포까지 완료되었다면 Zipkin 인스턴스의 EC2 대시보드로 이동한다.
- 인스턴스 상세 페이지에서 퍼블릭 DNS를 확인하고 "퍼블릭 DNS 주소:9411"로 접속한다.
- 아래와 같이 Zipkin UI가 보인다면 연동에 성공한것이다.
6. Spring Boot 연동
6-1. 의존성 추가
- build.gradle에 Zipkin 의존성을 추가한다.
// zipkin
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
6-2. application.yml에 설정 추가하기
- endpoint에 꼭 /api/v2/spans 까지 적어줘야 정삭 작동된다.
logging:
level:
com.recipia.member: debug
org.springframework.web.servlet: debug
org.hibernate.orm.jdbc.bind: trace
org.springframework.cloud.sleuth: info
pattern:
level: '%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]'
spring:
application:
name: member
management:
tracing:
sampling:
probability: 1.0
propagation:
consume: B3
produce: B3
zipkin:
tracing:
endpoint: http://<zipkin 실행중인 ec2 퍼블릭 IPv4 DNS 주소>:9411/api/v2/spans
application.yml을 작성하는데 아래 블로그글에서 큰 도움을 받았다.
6-3. 실행
- 테스트로 Http 요청을 날렸을때 잘 추적되는 모습을 확인할 수 있다.
7. 마무리
이로써 ECS에서 Zipkin 서버 구축 과정은 마무리되었다.
하지만, Zipkin의 완전한 작동은 아직 진행 중이다. 기존에 사용하던 스프링 부트와 연결된 로드 밸런서가 몇 초 간격으로 /test URL을 요청하고, 이 요청들까지 Zipkin에서 추적되어 불필요한 리소스를 소모하고 있다.
Zipkin 설정에서 HTTP 클라이언트와 서버 요청 추적을 비활성화할 수 있음에도 불구하고, ALB가 발생시키는 /test 요청이 계속 추적되고 있다. 이 부분에 대해 추가 분석이 필요하다.
다음 글에서는 Zipkin의 TraceId를 사용하여 여러 서버 간의 SNS, SQS 통신을 추적하는 프로세스 구성에 대해 논의할 예정이다.
이 포스트는 Team chillwave에서 사이드 프로젝트 중 적용했던 부분을 다시 공부하며 기록한 것입니다.
시간이 괜찮다면 팀원 '개발자의 서랍'님의 블로그도 한번 봐주세요 :)
'AWS' 카테고리의 다른 글
[AWS] Lambda로 RDS 시작 및 중지 설정 (0) | 2023.12.04 |
---|---|
[AWS] AWS ALB 헬스 체크(상태 검사) 간격 및 경로 수정을 통한 서비스 최적화 (0) | 2023.11.22 |
[AWS] SNS, SQS 연동하기 (2) - Spring Boot 3.X.X 버전과 SNS, SQS 연동하기 (2) | 2023.11.06 |
[AWS] SNS, SQS 연동하기 (1) - SNS, SQS 생성하기 (0) | 2023.11.06 |
[AWS] IAM MFA 설정하기 (1) | 2023.11.05 |