
15개가 넘는 서비스가 서로를 호출하는 상황에서 API 하나가 느려졌을 때, 어디서 병목이 생긴 건지 추적할 방법이 없었습니다. 그때 도입한 것이 Istio였고, 덕분에 많은 것이 보이기 시작했습니다. 하지만 솔직히 말하면, 그 과정이 마냥 순탄하지는 않았습니다. 도입을 권하는 자료는 많지만 도입 과정의 고통을 솔직하게 쓴 글은 드물어서, 제 경험을 있는 그대로 적어봅니다.
서비스가 많아지면 통신이 보이지 않는다 — 사이드카가 해법이 될 수 있을까
마이크로서비스로 전환하고 나서 가장 먼저 맞닥뜨린 문제가 무엇인지 아시나요? 기능이 안 된다거나, 배포가 어렵다거나 그런 게 아니었습니다. 가장 먼저 막힌 건 '지금 뭐가 어디서 잘못되고 있는지 전혀 모르겠다'는 막막함이었습니다.
서비스가 15개를 넘어가던 시점, 특정 API의 응답이 간헐적으로 느려지는 현상이 생겼습니다. 제가 직접 로그를 뒤지기 시작했는데, 팀마다 로그 형식이 달랐고, 어떤 서비스가 어떤 서비스를 얼마나 자주 호출하는지조차 문서화가 안 되어 있었습니다. 분산 추적(Distributed Tracing)은 엄두도 못 냈습니다. 여기서 분산 추적이란 여러 서비스에 걸쳐 이루어지는 단일 요청의 흐름을 처음부터 끝까지 추적하는 기술로, 마이크로서비스 환경에서 병목 지점을 찾아내는 데 필수적입니다. 이 문제를 Istio 없이 손으로 해결하려면 팀마다 로그 형식을 통일하고, 요청 ID를 모든 서비스에 일관되게 전파하는 작업이 선행되어야 하는데, 현실에서 그 작업은 끝이 없습니다.
Istio가 이 문제를 해결하는 방식은 꽤 영리합니다. 각 서비스 파드(Pod) 옆에 Envoy 프록시를 사이드카(Sidecar) 형태로 자동 주입합니다. 사이드카란 메인 컨테이너와 함께 동일한 파드 안에서 실행되는 보조 컨테이너를 말하는데, 이 구조 덕분에 서비스 코드를 단 한 줄도 건드리지 않고 모든 트래픽을 프록시가 가로채어 처리할 수 있게 됩니다. 컨트롤 플레인인 Istiod가 이 모든 프록시의 설정을 중앙에서 관리하고, 서비스 디스커버리와 인증서 관리까지 담당합니다.
Istio가 인프라 계층에서 공통으로 처리해주는 기능을 정리하면 다음과 같습니다. 트래픽 관리(로드 밸런싱, 카나리 배포, 장애 주입), 관찰성(분산 추적, 메트릭 수집, 접근 로그), 보안(mTLS 기반 서비스 간 암호화, 인증 및 인가), 정책 적용(속도 제한, 접근 제어)입니다.
실제 설치, 생각보다 쉬웠고 생각보다 어려웠다 — Kiali로 처음 본 트래픽 지도
EKS 클러스터에 istioctl을 이용해 설치하는 과정 자체는 예상보다 빠르게 끝났습니다. 각 네임스페이스에 istio-injection=enabled 레이블을 붙이는 것도 어렵지 않았습니다. 그런데 사이드카가 실제로 주입되기 시작하면서 기존 파드들이 줄줄이 재시작되었고, 일부 서비스에서 초기화 순서 문제로 기동 시 타임아웃이 발생했습니다.
문제의 원인은 사이드카 프록시가 완전히 준비되기 전에 메인 컨테이너가 외부 서비스로 요청을 보내려 했기 때문이었습니다. Istio에서 권장하는 대로 파드의 readinessProbe 설정과 초기화 지연 값을 조정해서 해결했지만, 제가 뒤늦게 깨달은 진짜 문제는 따로 있었습니다. 팀원들에게 Istio의 동작 방식을 충분히 사전 교육하지 않은 채로 배포부터 진행했던 것입니다. 에러 메시지가 떴을 때 팀원들이 원인을 찾는 데 한참 헤맨 것도 그 때문이었습니다. 기술 도입 실패의 절반은 기술 자체보다 팀 준비 부족에서 온다는 걸 그때 다시 한번 확인했습니다.
그래도 Kiali 대시보드를 처음 열었을 때의 장면은 지금도 기억에 남습니다. 서비스 간 트래픽 흐름이 그래프로 시각화되어 있었고, 어떤 서비스가 어디로 호출을 날리는지, 오류율은 얼마인지, P99 레이턴시는 어떤 상태인지가 한눈에 들어왔습니다. 여기서 P99 레이턴시란 전체 요청 중 상위 99%가 응답을 받기까지 걸린 최대 시간을 의미하는 지표로, 평균 응답 속도보다 실제 사용자 경험에 훨씬 가까운 수치입니다. Kiali 하나로 그동안 팀이 손으로 뒤지던 것들이 자동으로 보이기 시작했습니다. "우리 서비스 의존 관계가 이렇게 복잡했어?"라는 반응이 팀에서 나왔고, 그걸 계기로 불필요한 서비스 호출을 정리하는 작업도 시작됐습니다. 시각화가 아키텍처 개선의 계기가 된 셈이었습니다.
CNCF(Cloud Native Computing Foundation) 프로젝트 현황에 따르면 Istio는 2023년 CNCF 졸업 프로젝트로 승격되었으며, 현재 엔터프라이즈 환경에서 가장 널리 채택되는 서비스 메시 솔루션 중 하나입니다.
mTLS 전환, 단계를 건너뛰면 반드시 탈이 난다
Istio를 도입한 이후 보안 측면에서 가장 공을 들인 부분이 mTLS 설정이었습니다. mTLS(Mutual TLS)란 클라이언트와 서버 양쪽이 모두 인증서를 교환하여 서로의 신원을 검증하는 상호 인증 방식입니다. 일반 HTTPS가 서버만 인증서를 제시하는 것과 달리, mTLS는 양방향으로 신뢰를 확인하기 때문에 서비스 간 통신 보안 수준이 크게 올라갑니다.
처음에는 Permissive 모드로 시작했습니다. Permissive 모드에서는 mTLS와 일반 평문 트래픽을 동시에 허용하기 때문에, 기존 서비스가 영향을 받지 않으면서 점진적으로 전환할 수 있습니다. 그런데 Strict 모드로 전환하려 했을 때 문제가 생겼습니다. 일부 레거시 서비스가 mTLS를 지원하지 않아서 통신이 끊겼고, PeerAuthentication 정책을 네임스페이스별로 세밀하게 조정해야 했습니다. PeerAuthentication이란 Istio에서 특정 네임스페이스 또는 워크로드에 대해 어떤 TLS 모드를 적용할지 정의하는 정책 리소스입니다.
제가 직접 겪어보니, mTLS 전환은 전체 클러스터를 한 번에 바꾸려고 하면 반드시 문제가 생깁니다. 네임스페이스 단위로 Permissive → Strict를 순차적으로 적용하고, 각 단계마다 Kiali에서 오류율을 확인하면서 진행하는 것이 훨씬 안전합니다. Strict 모드로 전환했다가 특정 서비스 장애가 터지고, 되돌리는 데 다시 시간을 쓴 경험이 있습니다. 그 이후로 mTLS 전환은 절대 서두르지 않게 됐습니다.
Istio가 만능은 아니다 — 복잡도 비용을 냉정하게 따져야 한다
솔직히 이 부분이 가장 하고 싶었던 이야기입니다. Istio 도입 후 가시성이 높아진 것은 분명한 사실이지만, 그와 동시에 팀이 감당해야 할 복잡도도 함께 높아졌습니다.
사이드카 방식의 가장 큰 단점은 리소스 오버헤드입니다. 파드마다 Envoy 프록시가 하나씩 붙으니, 서비스 수가 늘어날수록 CPU와 메모리 사용량이 누적됩니다. 소규모 클러스터나 리소스가 제한된 환경에서는 Istio 자체가 부담이 될 수 있습니다. 실제로 저도 일부 노드에서 프록시 컨테이너들이 생각보다 많은 메모리를 점유하고 있는 것을 확인하고 놀란 적이 있습니다. 서비스가 20개를 넘어서자 Envoy 프록시들이 전체 메모리 사용량의 상당 부분을 차지하고 있었고, 처음 예산을 잡을 때 이걸 고려하지 못했습니다.
또 하나 간과하기 쉬운 문제가 있습니다. 통신 오류가 발생했을 때, 그게 애플리케이션 코드 문제인지, Envoy 프록시 설정 문제인지, 아니면 하위 네트워크 레이어의 문제인지 구분하기가 생각보다 까다롭습니다. 레이어가 하나 더 생긴 만큼 디버깅 경로도 복잡해집니다. 가시성이 높아졌다고 해서 디버깅이 반드시 쉬워지는 건 아니라는 역설이었습니다. 최근에는 이 오버헤드를 줄이기 위해 사이드카 없이 노드 레벨에서 프록시를 처리하는 Ambient Mesh 모드도 등장했는데, 이 방식은 아직 성숙도 측면에서 검토가 필요합니다.
Linkerd처럼 더 가벼운 서비스 메시 대안도 있으므로, 도입 전에 팀 규모와 운영 역량을 냉정하게 평가해야 합니다. Istio 공식 문서에서도 프로덕션 환경에서의 리소스 요구사항과 업그레이드 전략을 충분히 검토할 것을 권고하고 있습니다. 저는 Istio가 좋은 도구라는 생각에는 변함이 없지만, 만약 다시 처음으로 돌아간다면 팀에게 Linkerd를 먼저 써보게 하고 나서 Istio 도입 여부를 결정했을 것 같습니다.
Istio가 적합한 환경과 그렇지 않은 환경을 구분하는 핵심 기준은 다음과 같습니다. 서비스 수가 10개 이상이고 팀 간 통신 경로가 복잡한 경우에는 도입 효과가 큽니다. 전담 인프라 엔지니어 없이 소수 팀이 운영하는 경우에는 복잡도 부담을 먼저 고려해야 합니다. 보안 컴플라이언스 요건이 엄격하여 서비스 간 mTLS가 필수인 경우에는 Istio가 강력한 선택지입니다. 리소스가 제한된 소규모 클러스터에서는 Linkerd 등 경량 대안을 검토할 것을 권합니다.
서비스 메시는 도입 자체가 목적이 되어선 안 됩니다. Istio는 분명 강력한 도구지만, 그 복잡성이 조직의 운영 역량을 초과하는 순간 오히려 장애 요인이 됩니다. 도입을 고민하고 계신다면, 먼저 팀 내에서 Envoy, Istiod, mTLS의 기본 개념을 충분히 학습한 뒤 소규모 네임스페이스에서 파일럿 테스트를 해보시길 권합니다. 제가 겪은 가장 큰 교훈은, 기술보다 팀의 준비 상태가 먼저라는 것이었습니다.
참고:
- 이스티오 이해하기 – Istio와 서비스 메시: https://velog.io/@yin/이스티오-이해하기-Istio와-서비스-메시
- NGINX Store Blog – Istio Service Mesh 클러스터 배포 (2024.05): https://nginxstore.com/blog/istio/
- kimsehwan96.com – Istio란 무엇이고 무엇을 할 수 있을까 (2024.03): https://www.kimsehwan96.com/what-is-istio-and-service-mesh/
- Microsoft Learn – Istio 서비스 메시 AKS 추가 기능: https://learn.microsoft.com/ko-kr/azure/aks/istio-deploy-ingress