Skip to content
Published on

Istio Ambient Mesh 내부 구조: 사이드카 없는 서비스 메시

Authors

들어가며

Istio Ambient Mesh는 사이드카 프록시 없이 서비스 메시 기능을 제공하는 새로운 데이터 플레인 모드입니다. 기존 사이드카 방식의 근본적인 한계를 해결하기 위해 설계되었습니다.

이 글에서는 Ambient Mesh의 내부 아키텍처, 핵심 컴포넌트, 그리고 사이드카 방식과의 차이점을 심층적으로 분석합니다.

사이드카 방식의 한계

리소스 오버헤드

기존 사이드카 모드:
┌─────────────────────────────────┐
Pod│  ┌───────────┐ ┌─────────────┐ │
│  │    App    │ │ istio-proxy │ │  ← 파드당 약 100MB RAM, 0.1 CPU
│  │           │   (Envoy)    │ │
│  └───────────┘ └─────────────┘ │
└─────────────────────────────────┘

100개 파드 = 약 10GB 추가 메모리

시작 지연

사이드카 주입은 파드 시작 시간에 영향을 미칩니다:

  • istio-init 컨테이너가 iptables 규칙 설정 (1-2초)
  • istio-proxy가 istiod에서 구성 수신 대기 (2-5초)
  • 전체 시작 시간에 3-7초 추가

업그레이드 복잡성

사이드카 업그레이드 시 모든 파드를 재시작해야 합니다:

  • 롤링 업데이트로 파드를 하나씩 재생성
  • 대규모 클러스터에서 수 시간 소요
  • 애플리케이션 가용성에 영향

Ambient Mesh 아키텍처

┌─────────────────────────────────────────────────────────┐
Control Plane│                      istiod                              │
└─────────────────────┬───────────────────────────────────┘
                      │ xDS
          ┌───────────┼───────────┐
          ▼           ▼           ▼
┌─────────────┐ ┌──────────┐ ┌──────────┐
│   ztunnel   │ │ ztunnel  │ │ waypoint │
  (Node 1) (Node 2) │ │  proxy   │
DaemonSet  │ │ DaemonSet│ (per-ns)└──────┬──────┘ └────┬─────┘ └────┬─────┘
       │              │            │
  ┌────┴────┐   ┌────┴────┐      │
Pod A   │   │ Pod B   │      │
  (no scar)(no scar)│      │
  └─────────┘   └─────────┘      │
       │              │            │
       └──── HBONE tunnel ────────┘

ztunnel: 노드 수준 L4 프록시

개요

ztunnel(Zero Trust Tunnel)은 각 노드에 DaemonSet으로 배포되는 경량 L4 프록시입니다:

  • Rust로 작성: 높은 성능과 낮은 메모리 사용량
  • L4 전용: TCP 수준의 처리만 담당
  • 노드당 하나: 해당 노드의 모든 파드 트래픽을 처리

ztunnel의 핵심 기능

ztunnel 기능:
├── 1. mTLS 암호화/복호화
│   ├── 워크로드 인증서 관리 (SDS)
│   └── 모든 파드 간 통신 암호화
├── 2. L4 인가
│   ├── AuthorizationPolicy (L4 규칙만)
│   └── 소스/대상 ID 기반 접근 제어
├── 3. HBONE 터널링
│   ├── HTTP/2 CONNECT 기반 터널
│   └── 포트 15008에서 수신
└── 4. L4 텔레메트리
    ├── TCP 연결 메트릭
    └── 바이트 전송량 추적

ztunnel 내부 동작

[아웃바운드 트래픽 처리]

App (Pod A, Node 1) → reviews:9080
[1] 트래픽 인터셉션 (eBPF 또는 iptables)
    → 트래픽을 로컬 ztunnel로 리다이렉트
[2] ztunnel이 대상 확인
    ├── Kubernetes Service 해석
    └── 대상 Pod의 노드 위치 확인
[3] HBONE 터널 수립
    ├── 대상 노드의 ztunnel과 mTLS 연결
    ├── HTTP/2 CONNECT로 터널 생성
    └── 포트 15008 사용
[4] 암호화된 트래픽 전송

[인바운드 트래픽 처리]

[5] 대상 노드의 ztunnel이 HBONE 터널 수신
[6] mTLS 복호화 및 인가 확인
    ├── 소스 SPIFFE ID 검증
    └── AuthorizationPolicy 평가
[7] 평문으로 대상 Pod에 전달

ztunnel의 인증서 관리

ztunnel은 해당 노드의 모든 파드에 대한 인증서를 관리합니다:

ztunnel (Node 1)
├── Pod A의 인증서: spiffe://cluster.local/ns/prod/sa/frontend
├── Pod B의 인증서: spiffe://cluster.local/ns/prod/sa/reviews
└── Pod C의 인증서: spiffe://cluster.local/ns/prod/sa/ratings

인증서 획득 방식:
1. ztunnel이 istiod에 각 워크로드의 인증서 요청
2. Kubernetes ServiceAccount 토큰으로 인증
3. SDS를 통해 인증서 수신 및 갱신

Waypoint Proxy: 네임스페이스 수준 L7 프록시

개요

waypoint proxy는 L7 기능이 필요할 때만 배포되는 Envoy 기반 프록시입니다:

L4만 필요한 경우:
Pod → ztunnel → ztunnel → Pod
(mTLS + L4 인가만)

L7이 필요한 경우:
Pod → ztunnel → waypoint proxy → ztunnel → Pod
(HTTP 라우팅, L7 인가, 폴트 인젝션 등)

Waypoint Proxy 배포

Kubernetes Gateway API를 사용하여 waypoint proxy를 생성합니다:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: waypoint
  namespace: production
  labels:
    istio.io/waypoint-for: service
spec:
  gatewayClassName: istio-waypoint
  listeners:
    - name: mesh
      port: 15008
      protocol: HBONE

또는 istioctl을 사용:

istioctl waypoint apply --namespace production

Waypoint Proxy가 처리하는 기능

Waypoint Proxy (Envoy):
├── L7 트래픽 관리
│   ├── VirtualService (HTTP 라우팅)
│   ├── 가중치 기반 트래픽 분할
│   ├── 리트라이, 타임아웃
│   ├── 폴트 인젝션
│   └── 트래픽 미러링
├── L7 보안
│   ├── AuthorizationPolicy (L7 규칙)
│   ├── RequestAuthentication (JWT)
│   └── HTTP 헤더/경로 기반 인가
└── L7 관찰성
    ├── HTTP 메트릭 (istio_requests_total 등)
    ├── 분산 트레이싱 스팬
    └── 액세스 로깅

HBONE 터널링 프로토콜

HBONE 개요

HBONE(HTTP-Based Overlay Network Environment)은 Ambient Mesh의 핵심 통신 프로토콜입니다:

HBONE 터널 구조:
┌──────────────────────────────────────┐
TCP Connection (port 15008)│  ┌────────────────────────────────┐  │
│  │ TLS (mTLS)                     │  │
│  │  ┌──────────────────────────┐  │  │
│  │  │ HTTP/2 CONNECT           │  │  │
│  │  │  ┌────────────────────┐  │  │  │
│  │  │  │ Tunneled TCP Data  │  │  │  │
│  │  │  └────────────────────┘  │  │  │
│  │  └──────────────────────────┘  │  │
│  └────────────────────────────────┘  │
└──────────────────────────────────────┘

HBONE vs 사이드카 방식 비교

특성사이드카 (iptables)HBONE (Ambient)
트래픽 인터셉션iptables REDIRECTeBPF 또는 iptables
프록시 위치파드 내부노드 수준 (ztunnel)
터널링없음 (직접 연결)HTTP/2 CONNECT
mTLS 종단점사이드카 프록시ztunnel
포트원래 서비스 포트15008 (HBONE)

HBONE 연결 흐름

Source Pod (Node 1)          Destination Pod (Node 2)
     │                              ▲
     ▼                              │
ztunnel (Node 1)              ztunnel (Node 2)
     │                              ▲
TCP: Node1Node2:15008TLS: mTLS handshake       │
HTTP/2: CONNECT method    │
     └──────────────────────────────┘

트래픽 인터셉션

eBPF 기반 인터셉션 (권장)

eBPF 프로그램이 커널 수준에서 트래픽을 리다이렉트:

App (소켓 연결) → eBPF hook → ztunnel
            TC (Traffic Control) 또는
            Socket-level redirection

장점:
- iptables보다 높은 성능
- 커널 수준에서 동작하여 오버헤드 최소화
- 파드별 iptables 규칙 불필요

iptables 기반 인터셉션 (폴백)

eBPF를 지원하지 않는 환경에서는 iptables를 사용합니다:

istio-cni가 노드 수준에서 iptables 규칙 설정:

iptables -t nat -A PREROUTING \
  -p tcp \
  -m mark ! --mark 0x539/0xfff \
  -j REDIRECT --to-ports 15008

iptables -t nat -A OUTPUT \
  -p tcp \
  -m mark ! --mark 0x539/0xfff \
  -j REDIRECT --to-ports 15001

워크로드 등록

Ambient Mesh 활성화

네임스페이스에 라벨을 추가하여 Ambient Mesh에 등록합니다:

kubectl label namespace production istio.io/dataplane-mode=ambient

이 라벨이 추가되면:

  1. 해당 네임스페이스의 파드 트래픽이 ztunnel로 리다이렉트
  2. ztunnel이 해당 파드의 인증서를 관리
  3. 모든 파드 간 통신에 mTLS 적용

L7 기능 활성화

L7 기능이 필요한 경우 waypoint proxy를 추가로 배포합니다:

# 네임스페이스에 waypoint proxy 배포
istioctl waypoint apply --namespace production

# 또는 특정 서비스 계정에만 적용
istioctl waypoint apply --namespace production \
  --service-account reviews

성능 비교: 사이드카 vs Ambient

메모리 사용량

사이드카 모드 (100 파드):
- Envoy 프록시: 100개 x ~100MB = ~10GB
- istio-init: 시작 시에만 사용

Ambient 모드 (100 파드, 3 노드):
- ztunnel: 3개 x ~50MB = ~150MB
- waypoint (필요 시): 1-2개 x ~100MB = ~200MB
-: ~350MB (사이드카 대비 약 97% 절감)

레이턴시

사이드카 모드:
Client AppClient EnvoyNetworkServer EnvoyServer App
             (L4+L7)                    (L4+L7)

Ambient 모드 (L4):
Client App → ztunnel → Network → ztunnel → Server App
             (L4)                 (L4)

Ambient 모드 (L7 포함):
Client App → ztunnel → waypoint → ztunnel → Server App
             (L4)      (L7)       (L4)

L4만 사용하는 경우 Ambient가 더 낮은 레이턴시를 보여줍니다. L7이 필요한 경우 추가 홉(waypoint)이 생기지만, 리소스 효율성이 크게 향상됩니다.

시작 시간

사이드카 모드:
- istio-init iptables 설정: 1-2- Envoy 시작 및 구성 수신: 2-5- 총 추가 시간: 3-7
Ambient 모드:
- ztunnel이 이미 실행  (DaemonSet)
- 파드 시작 시 추가 오버헤드: 거의 없음
- eBPF 규칙 적용: 밀리초 단위

제한사항과 현재 상태

현재 제한사항

  1. 프로토콜 감지: ztunnel은 L4만 처리하므로 프로토콜 자동 감지가 제한적
  2. 일부 Envoy 기능 미지원: EnvoyFilter, 일부 고급 트래픽 관리 기능
  3. 멀티 클러스터: 아직 완전히 지원되지 않는 시나리오 존재
  4. Windows 노드: 현재 미지원

사이드카에서 Ambient로 마이그레이션

권장 마이그레이션 순서:

1. Ambient 모드 설치 (사이드카와 공존 가능)

2. 테스트 네임스페이스에서 Ambient 활성화
   kubectl label namespace test istio.io/dataplane-mode=ambient
   kubectl label namespace test istio-injection-  # 사이드카 비활성화

3. 검증 후 프로덕션 네임스페이스에 적용

4. 필요한 네임스페이스에 waypoint proxy 배포

5. 기존 사이드카 라벨 제거

언제 어떤 모드를 선택할까

사이드카 모드가 적합한 경우:
├── 파드별 세밀한 L7 제어가 필요
├── EnvoyFilter를 사용하는 고급 구성
├── 기존 안정적인 환경 유지
└── Windows 노드 사용

Ambient 모드가 적합한 경우:
├── 리소스 효율성이 중요
├── 빠른 파드 시작이 필요
├── 사이드카 업그레이드 부담 최소화
├── 대부분 L4 보안(mTLS)만 필요
└── 점진적으로 L7 기능 추가 가능

마무리

Istio Ambient Mesh는 서비스 메시의 가장 큰 불만이었던 사이드카 오버헤드 문제를 해결하는 혁신적인 접근입니다. ztunnel(L4)과 waypoint proxy(L7)로 기능을 분리함으로써:

  1. 리소스 절감: 노드당 하나의 ztunnel로 수백 개 파드의 mTLS를 처리
  2. 운영 단순화: 사이드카 주입/업그레이드 불필요
  3. 점진적 채택: L4부터 시작하여 필요 시 L7 기능을 추가

다음 글에서는 Istio 관찰성의 내부 구현을 살펴보겠습니다.