포스트

EKS -> ECS 전환하면서 깨달은 것


EKS -> ECS 전환하면서 깨달은 것

최근 팀에서 Kubernetes 기반의 Amazon EKS 환경을 Amazon ECS로 전환하는 프로젝트를 진행했습니다. EKS의 유연성과 강력한 생태계는 마이크로서비스 아키텍처를 운영하는 데 큰 장점을 제공했지만, 비용 최적화와 운영 단순화를 목표로 ECS로의 전환을 결정했습니다. 하지만 이 과정에서 예상치 못한 수많은 기술적 도전과제들이 있었고, 그 중에 2가지 정도를 공유드리면서 회고를 진행하고자 합니다.

Istio 는 많은 것을 해준다.

EKS 환경에서는 Istio 서비스 메시를 활용해 마이크로서비스 간 통신을 효율적으로 관리했습니다. Istio는 트래픽 라우팅, 인증, 로드 밸런싱 같은 복잡한 네트워킹 로직을 중앙에서 처리해 개발자가 세부 구현에 신경 쓰지 않아도 됐습니다. 예를 들어, Spring Cloud Gateway는 인증 회원 플로우를 처리했지만, Istio의 VirtualService 설정을 통해 비회원 플로우는 Gateway를 우회해 비회원 마이크로서비스로 직접 라우팅할 수 있었습니다. 비회원 플로우는 별도의 인가 로직을 해당 마이크로서비스에서 독립적으로 처리했기 때문에 이런 유연한 설계가 가능했습니다.
그러나 ECS로 전환하면서 Istio와 같은 서비스 메시를 사용할 수 없었습니다. ECS는 Kubernetes처럼 풍부한 네트워킹 생태계를 제공하지 않아 모든 트래픽을 Spring Cloud Gateway를 통해 처리하도록 아키텍처를 재설계해야 했습니다. 특히, Private ALB가 Gateway만 바라보도록 설정되면서 비회원 플로우도 Gateway를 거쳐야 했습니다.

주요 어려움

EKS에서는 Istio가 비회원 플로우의 트래픽을 직접 라우팅해 Gateway의 부담을 줄였지만, ECS에서는 모든 요청이 Gateway를 통과해야 했습니다. 기존에 비회원 마이크로서비스가 독립적으로 처리하던 토큰 검증 로직을 Gateway로 옮겨야 했고, 이를 위해 새로운 필터 로직을 구현하는 데 상당한 노력이 들었습니다. 또한, EKS 환경에서의 비회원 접근 포인트와의 하위호환을 유지하면서 인증 회원 플로우와의 충돌을 피하는 것이 주요 과제였습니다.

해결 방안

비회원 플로우를 지원하기 위해 Spring Cloud Gateway에 커스텀 필터를 추가했습니다. 이 필터는 요청 헤더의 비회원 토큰을 검증해 비회원 플로우를 처리하고, 인증 회원 요청과 구분해 적절한 마이크로서비스로 라우팅하도록 설계했습니다. 하위호환을 위해 기존에 생성된 비회원 전용 접근 포인트의 특정 요청 패턴(예: /non-member/*)을 감지해 비회원 플로우를 Gateway 를 거쳐 비회원 마이크로서비스로 돌려 처리하도록 로직을 추가했습니다.

Helm 으로 설정을 관리하는 것은 편리하다.

EKS 환경에서는 Helm 차트와 ArgoCD를 활용해 환경 변수를 손쉽게 부여할 뿐만 아니라, 레플리카 개수 제어나 무중단 배포, 롤백 등을 쉽게 수행할 수 있었습니다. 이 모든 작업이 몇 줄의 설정 변경으로 완료되며 추가 스크립트 작업이 거의 필요 없었습니다.
반면, ECS에서는 Helm 차트나 ArgoCD 같은 선언적 도구를 사용할 수 없어 개발자가 직접 AWS 콘솔에서 태스크 정의를 수정하거나 Terraform 코드를 수정해야만 했습니다. 예를 들면, Datadog 에이전트와 태스크를 연결하기 위해서 Datadog 에이전트의 설정을 ECS Task Definition에 포함시키고 연결 스크립트와 커맨드를 수동으로 설정해야 했습니다. 이 과정에서 초기 설정의 복잡성과 반복적인 시행착오가 큰 도전이었습니다.

주요 어려움

  • 수동 설정의 복잡성: EKS에서는 Helm 차트가 포트 매핑, 환경 변수, 로그 포맷 같은 설정을 자동으로 처리했지만, ECS에서는 Task Definition JSON에 모든 세부 사항을 직접 입력해야 했습니다. 예를 들어, 에이전트 이미지 버전, API 키, 로그 수집 경로 등을 명시적으로 정의해야 했고, 문서화 부족으로 인해 초기 설정 오류가 빈번했습니다.

  • 환경 변수와 커맨드 문제: Datadog 에이전트는 DD_API_KEY, DD_LOGS_ENABLED 같은 환경 변수와 agent run 같은 커맨드를 조합해 동작합니다. ECS에서는 이를 Task Definition에 정확히 매핑하는 데 어려움이 있었고, 변수 누락이나 잘못된 커맨드 순서로 에이전트가 시작되지 않거나 메트릭 전송이 실패했습니다. 심지어, 처음에 컨테이너가 구동될 때 Agent 연결이 되도록 하는데도 꽤나 삽질이 필요했습니다.

  • 디버깅의 어려움: EKS에서는 Helm 로그와 ArgoCD 배포 상태로 문제를 빠르게 진단했지만, ECS에서는 CloudWatch Logs를 통해 에이전트 로그를 일일이 확인해야 했습니다. 로그 포맷이 비표준적이거나 에러 메시지가 모호해 원인 파악에 시간이 걸렸습니다.

해결 방안

Datadog 에이전트를 안정적으로 연동하기 위해 Task Definition에 에이전트를 별도 컨테이너로 추가하고, 환경 변수와 커맨드를 체계적으로 정리했습니다. Datadog 공식 문서와 AWS ECS 문서를 참고해 최소 필수 설정을 먼저 적용한 뒤, 로그 수집과 메트릭 전송을 점진적으로 확장했습니다.

결론

EKS에서 ECS로 전환하며 마이크로서비스 간 통신과 모니터링 툴 설정에서 많은 것을 배웠습니다. Istio의 네트워킹 편의성과 Helm 차트의 선언적 설정은 EKS의 강점이지만, ECS에서는 Spring Cloud Gateway와 Task Definition을 통해 이를 대체할 수 있었습니다. 비록 초기 삽질이 많았지만, 체계적인 설정과 자동화를 통해 안정적인 운영 환경을 구축했습니다. 이번 경험을 통해 ECS의 단순함이 비용 절감에 기여할 수 있음을 알았지만, 복잡한 마이크로서비스 환경에서는 Kubernetes의 생태계가 여전히 강력하다는 점도 깨달았습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.