채널코퍼레이션 DevOps팀이 2025년 3월부터 11월까지 약 8개월에 걸쳐 Istio를 프로덕션에 도입한 시리즈의 1편이다. 기존 Sidecar mode가 아니라 2024년 말 GA된 Ambient mode를 골랐고, 왜 Service mesh를 도입했는지, 왜 Sidecar가 아닌지, Ambient mode가 어떻게 동작하는지를 다룬다. 리소스 절약 외에는 Sidecar mode가 낫다고 솔직히 인정하면서도, 커지는 서비스 규모와 확장성을 기준으로 Ambient를 택한 판단 과정을 담았다.
핵심 포인트- 개별 기능만 보면 Service mesh가 꼭 필요하냐는 질문에 아니라고 답할 수도 있다. 가시성은 APM으로, 카나리는 Ingress 트래픽 제어로, rate-limit은 애플리케이션에서 각각 풀 수 있다.
- Linkerd는 가볍지만 참고 자료가 적었고 Cilium은 CNI로 더 알려져 Service mesh만을 위해 채택하기 부담스러웠다. Istio를 고른 이유는 문제가 생겼을 때 고민을 함께할 커뮤니티가 가장 크기 때문이다.
- Sidecar mode의 부담은 전파해야 할 설정 크기 × 전파 대상 수인데, Pod 수가 곧 proxy 수라 서비스가 늘수록 가파르게 커진다.
- 약 4,000개 Pod에 모두 sidecar를 붙이면 idle 상태에서만 수십~수백 vCPU와 약 240Gi 메모리가 순수하게 프록시에 소모된다.
- 대가도 분명하다. Sidecar에는 없던 SPoF가 생기고, ztunnel이나 waypoint 장애는 노드 전체나 namespace 전체로 번진다.
상세 정리- 도입 배경: Service mesh는 여러 해 전부터 논의됐지만 매번 지금은 아니라는 결론으로 미뤄지다 2025년 초 시작됐다. 서로 다른 역할의 서비스가 계속 늘어나는 상황에서 기능을 통합 제공하는 기반에 투자하는 것이 장기적으로 맞다고 판단했다.
- 기대한 것: L7 네트워크 metrics부터 서비스 간 호출 관계까지의 네트워크 가시성, 그리고 L7 통제력을 강화한 더 정교한 카나리 배포다. 모든 기능을 당장 쓰려는 것은 아니고 기반을 마련해두면 필요할 때 쉽게 적용할 수 있다는 점이 매력이었다.
- 리소스 실측: 공식 기준으로 1,000 RPS에서 sidecar가 약 0.2 vCPU와 60Mi, ztunnel이 약 0.06 vCPU와 12Mi다. 자체 측정에서는 2,000 RPS 기준 Envoy가 약 0.8~1.2 vCPU와 300~500Mi를 썼다.
- Ambient에서도 노드가 늘면 ztunnel도 늘지만 Pod 수에 1:1로 비례하는 Sidecar보다 증가폭이 훨씬 완만하다.
- Gateway API 요인: Ingress 리소스 업데이트가 freeze되고 Gateway API가 표준이 되는 흐름에서, Ambient mode의 공식 문서와 예제가 처음부터 Gateway API 기준으로 쓰여 있어 함께 도입하기 자연스러웠다.
- 단점 인정: 디버깅 난이도가 올라간다. ztunnel·waypoint·HBONE 같은 새 개념을 익혀야 하고 proxy와 hop이 늘어 원인 추적이 까다롭다. GA 직후라 프로덕션 검증 사례가 적고 Istio API 대비 덜 성숙하다는 점도 짚는다.
- 팀 논의에서 나온 의견들: 2~3년 동안 건드리지 않을 것을 고르고 싶다, 네트워크 조작과 가시성만 잘 되면 Ambient도 상관없지만 안정성이 걸린다, 다양한 기능을 안 쓸 거면 Ambient이고 발생 빈도보다 복구 속도에 집중해야 한다는 의견이 나왔다.
- 결론: Sidecar를 도입한 뒤 다시 Ambient로 마이그레이션하는 상황을 피하고 싶어, 팀 내 Istio와 Envoy 이해도를 높이며 신중히 리서치하는 방향으로 Ambient를 택했다.
- 구조: istiod가 xDS API로 data plane에 설정과 정책을 전파하는 역할은 Sidecar와 다르지 않고, 전파 대상이 sidecar proxy에서 waypoint와 ztunnel로 바뀐 것이 차이다.
- ztunnel은 노드당 1개로 mTLS 터널과 기본 정책을 처리하고, waypoint는 필요한 namespace나 서비스에만 선택적으로 배치돼 정교한 라우팅과 관측을 담당한다.
- workload는 세 경우로 나뉜다. 양쪽 Pod이 모두 mesh 밖이면 kube-proxy 경유의 기존 Kubernetes 네트워크와 동일하게 동작한다.
- mesh에 속한 경우 outbound는 destination이 mesh에 포함되면 암호화된 HBONE 채널로 전달되고, inbound도 해당 노드의 ztunnel을 거쳐 들어온다. Pod은 HBONE 트래픽과 plaintext 트래픽을 모두 받을 수 있다.
- mTLS 방식: mesh 안 workload들은 HBONE·ztunnel·x509 인증서로 mTLS를 맺고, source와 destination 모두 고유한 인증서를 갖는다. ztunnel은 자신이 속한 노드 workload들의 인증서를 쓰며 Pod 간 mTLS 과정에서 자기 identity를 쓰지 않는다.
- waypoint가 켜지면 그 범위의 트래픽은 모두 waypoint를 거쳐 L7 정책이 적용되며, ztunnel과 달리 source나 destination Pod과 같은 노드에 있지 않을 수 있다.
- HBONE의 실체: 이름은 복잡해 보이지만 HTTP CONNECT 메서드로 터널을 열고 그 위에 TLS를 씌운 것이 전부다. 이미 검증된 표준들을 Envoy config로 조립한 것이라고 이해하면 된다.
- HBONE의 장점은 Istio 고유 메타데이터를 트래픽에 삽입하지 않고도 프록시 처리를 할 수 있다는 점이지만, 디버깅에서는 양날의 검이다. TCP connection reset을 추적할 때 tcpdump를 떠도 HBONE 구간은 암호화된 TLS 내용만 보였고, destination의 모든 네트워크 인터페이스를 캡처해야 ztunnel이 복호화한 트래픽을 볼 수 있었다.
- 트래픽 리다이렉션: istio-cni가 삽입한 iptables 규칙으로 Pod의 TCP 패킷이 특정 포트들로 리다이렉트되고, Pod에서 ztunnel을 거쳐 waypoint나 외부로 이어진다. 리다이렉트는 모두 Pod network 안에서 이뤄지고 host side에서 하지 않는다.
- 주의점 둘: ztunnel이 우회되면 mesh에 설정한 모든 Authorization policy도 함께 무시된다. 그리고 ztunnel과 istio-cni는 항상 Running이어야 하며, istio-cni가 준비되지 않은 상태에서 Pod이 스케줄되면 그 Pod은 mesh에 불완전하게 참여하는 상태가 될 수 있다.
왜 읽나Service mesh 도입을 앞두고 Sidecar와 Ambient 사이에서 저울질하는 인프라 엔지니어에게 리소스 실측과 단점까지 함께 놓인 의사결정 기록이 된다.