Skip to content
Published on

Kubernetes Istio Ambient Mesh 실전 가이드: 사이드카 없는 서비스 메시의 새 패러다임

Authors
  • Name
    Twitter
Kubernetes Istio Ambient Mesh

들어가며

서비스 메시(Service Mesh)는 마이크로서비스 아키텍처에서 서비스 간 통신을 투명하게 관리하는 핵심 인프라 계층입니다. Istio는 이 분야에서 가장 널리 사용되는 오픈소스 프로젝트이지만, 전통적인 사이드카 프록시 모델은 운영 복잡성과 리소스 오버헤드라는 근본적인 과제를 안고 있었습니다.

모든 Pod에 Envoy 사이드카를 주입하는 방식은 Pod당 50100MB의 메모리 오버헤드, 25초의 시작 지연, 사이드카 업그레이드 시 전체 워크로드 롤링 재시작 등 무시할 수 없는 비용을 수반합니다. 수천 개의 Pod를 운영하는 대규모 클러스터에서는 사이드카 자체가 상당한 인프라 비용이 됩니다.

Istio Ambient Mesh는 이 문제를 근본적으로 해결합니다. 사이드카를 완전히 제거하고, 노드 수준의 공유 프록시(ztunnel)와 선택적 L7 프록시(waypoint proxy)라는 두 계층 아키텍처를 도입하여 메모리 사용량 90% 이상 절감, CPU 사용량 50% 이상 절감을 달성합니다. Istio 1.22에서 Beta에 도달한 이후 프로덕션 환경에서의 채택이 빠르게 늘어나고 있습니다.

이 글에서는 Ambient Mesh의 아키텍처 원리부터 설치, 트래픽 정책, 관찰가능성, 사이드카에서의 마이그레이션 전략, 그리고 프로덕션 운영에서 마주치는 실패 사례와 복구 절차까지 실전 중심으로 다룹니다.

Istio Ambient Mesh 아키텍처 이해

두 계층 데이터 플레인

Ambient Mesh의 핵심 설계 철학은 **기능 분리(separation of concerns)**입니다. 전통적인 사이드카 모델에서는 하나의 Envoy 프록시가 L4부터 L7까지 모든 기능을 처리했지만, Ambient Mesh는 이를 두 개의 명확한 계층으로 분리합니다.

+------------------------------------------------------------------+
|                    Istio Ambient Mesh 아키텍처                      |
+------------------------------------------------------------------+
|                                                                    |
|  [Service A Pod]    [Service B Pod]    [Service C Pod]             |
|       |                   |                   |                    |
|       v                   v                   v                    |
|  +----------------------------------------------------------+     |
|  |              ztunnel (DaemonSet, 각 노드)                  |     |
|  |  - mTLS 터널링 (HBONE)                                    |     |
|  |  - L4 인증 / 인가                                         |     |
|  |  - L4 텔레메트리                                          |     |
|  |  - TCP 연결 관리                                          |     |
|  +----------------------------------------------------------+     |
|       |                                                            |
|       | HBONE (HTTP CONNECT 기반 터널링)                           |
|       v                                                            |
|  +----------------------------------------------------------+     |
|  |         Waypoint Proxy (선택적, 네임스페이스/SA)           |     |
|  |  - HTTP 라우팅                                            |     |
|  |  - L7 인증 / 인가 정책                                    |     |
|  |  - L7 텔레메트리                                          |     |
|  |  - 트래픽 미러링, 카나리 배포                               |     |
|  |  - 헤더 기반 라우팅                                        |     |
|  +----------------------------------------------------------+     |
|       |                                                            |
|       | HBONE                                                      |
|       v                                                            |
|  +----------------------------------------------------------+     |
|  |              ztunnel (대상 노드)                            |     |
|  +----------------------------------------------------------+     |
|       |                                                            |
|       v                                                            |
|  [Destination Pod]                                                 |
|                                                                    |
+------------------------------------------------------------------+

L4 Secure Overlay (ztunnel): 모든 메시 트래픽에 대해 기본적으로 활성화됩니다. mTLS 암호화, L4 접근 제어, TCP 수준 텔레메트리를 제공합니다. 극도로 가벼운 Rust 기반 프록시로 구현되어 있습니다.

L7 Processing (Waypoint Proxy): HTTP 라우팅, 헤더 기반 정책, gRPC 메트릭 수집 등 L7 기능이 필요한 경우에만 선택적으로 배포됩니다. 표준 Envoy 프록시를 사용합니다.

이 설계 덕분에 L7 기능이 필요 없는 서비스(전체 서비스의 상당수)는 ztunnel만으로 충분히 메시의 보안과 관찰가능성을 확보할 수 있으며, L7 프록시 비용을 지불하지 않아도 됩니다.

트래픽 흐름 상세

Ambient Mesh에서 트래픽이 처리되는 과정을 단계별로 살펴보겠습니다.

L4 전용 흐름 (Waypoint 없음):
  Pod A ---> ztunnel(노드1) ===HBONE===> ztunnel(노드2) ---> Pod B

L7 처리가 필요한 흐름:
  Pod A ---> ztunnel(노드1) ===HBONE===> Waypoint Proxy ===HBONE===> ztunnel(노드2) ---> Pod B
  1. 출발지 Pod에서 나가는 트래픽을 같은 노드의 ztunnel이 투명하게 가로챕니다
  2. ztunnel은 HBONE(HTTP CONNECT 기반) 프로토콜로 트래픽을 암호화하여 터널링합니다
  3. L7 정책이 설정된 대상이면 waypoint proxy로 먼저 전달합니다
  4. waypoint proxy에서 L7 정책(라우팅, 인가 등)을 적용한 후 대상 노드의 ztunnel로 전달합니다
  5. 대상 노드의 ztunnel이 복호화하여 대상 Pod로 전달합니다

ztunnel: L4 처리 계층

ztunnel이란

ztunnel(Zero Trust Tunnel)은 Ambient Mesh의 기반 계층을 구성하는 경량 프록시입니다. 각 노드에 DaemonSet으로 배포되어 해당 노드의 모든 워크로드 트래픽을 처리합니다.

핵심 특성:

  • Rust로 작성: C/C++ 수준의 성능을 제공하면서도 메모리 안전성을 보장합니다
  • 의도적으로 제한된 범위: L3/L4 기능만 처리하도록 설계되어 공격 표면이 작습니다
  • HTTP 트래픽을 파싱하지 않음: 워크로드의 HTTP 헤더를 읽거나 수정하지 않아 보안성이 높습니다
  • HBONE 프로토콜: HTTP CONNECT 기반의 터널링 프로토콜로 mTLS 통신을 구현합니다

ztunnel 기능 상세

# ztunnel이 제공하는 기능 범위
ztunnel_capabilities:
  security:
    - mTLS 자동 암호화/복호화
    - SPIFFE 기반 워크로드 ID 발급
    - L4 AuthorizationPolicy 적용
  networking:
    - TCP 연결 프록시
    - HBONE 터널링
    - 로드밸런싱 (L4)
  observability:
    - TCP 연결 메트릭 (바이트, 연결 수, 지속시간)
    - L4 접근 로그
    - Prometheus 메트릭 노출
  not_supported:
    - HTTP 라우팅
    - 헤더 기반 정책
    - gRPC 프로토콜 파싱
    - 트래픽 미러링/분할

ztunnel 리소스 프로필

ztunnel은 사이드카 Envoy와 비교할 수 없을 정도로 가볍습니다. 일반적인 프로덕션 환경에서의 리소스 사용량을 비교하면 다음과 같습니다.

항목Envoy 사이드카 (Pod당)ztunnel (노드당)
메모리 기본50~100MB20~40MB
CPU 기본10~50m10~30m
100개 Pod 클러스터 총 비용5~10GB 메모리60~120MB (3노드 기준)
바이너리 크기~40MB~10MB

ztunnel 상태 확인

# ztunnel DaemonSet 상태 확인
kubectl get daemonset -n istio-system ztunnel

# ztunnel Pod 로그 확인
kubectl logs -n istio-system -l app=ztunnel --tail=50

# ztunnel 프록시 상태 확인 (특정 노드)
kubectl exec -n istio-system $(kubectl get pod -n istio-system -l app=ztunnel --field-selector spec.nodeName=worker-1 -o jsonpath='{.items[0].metadata.name}') -- curl -s localhost:15000/config_dump

# ztunnel이 관리하는 워크로드 목록 확인
kubectl exec -n istio-system $(kubectl get pod -n istio-system -l app=ztunnel -o jsonpath='{.items[0].metadata.name}') -- curl -s localhost:15020/debug/workloadz

Waypoint Proxy: L7 처리 계층

Waypoint Proxy의 역할

Waypoint Proxy는 L7 수준의 트래픽 관리가 필요한 경우에만 배포하는 선택적 컴포넌트입니다. 표준 Envoy 프록시 엔진을 사용하며, 네임스페이스 또는 서비스 어카운트 단위로 배포됩니다.

ztunnel과의 핵심 차이점은 다음과 같습니다.

  • HTTP/gRPC 프로토콜을 이해하고 헤더를 파싱합니다
  • 요청 수준의 라우팅, 재시도, 타임아웃을 적용합니다
  • L7 AuthorizationPolicy(경로, 메서드 기반)를 실행합니다
  • HTTP 메트릭과 분산 추적 데이터를 수집합니다

Waypoint Proxy 배포

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

# 특정 서비스 어카운트용 waypoint 배포
istioctl waypoint apply -n my-namespace --name sa-waypoint --for service

# waypoint proxy 상태 확인
kubectl get gateway -n my-namespace

Waypoint Proxy는 Kubernetes Gateway API의 Gateway 리소스로 관리됩니다.

# waypoint proxy Gateway 리소스 예시
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-namespace-waypoint
  namespace: my-namespace
  labels:
    istio.io/waypoint-for: service
spec:
  gatewayClassName: istio-waypoint
  listeners:
    - name: mesh
      port: 15008
      protocol: HBONE

Waypoint Proxy 스케일링

프로덕션 환경에서는 waypoint proxy의 리소스와 레플리카 수를 적절히 조정해야 합니다.

# waypoint proxy에 대한 HPA 설정
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-namespace-waypoint
  namespace: my-namespace
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-namespace-waypoint
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

Sidecar vs Ambient 비교

두 모드를 다양한 관점에서 비교합니다. 같은 클러스터에서 사이드카 모드와 ambient 모드를 네임스페이스별로 혼합 사용할 수 있지만, 같은 네임스페이스에 두 모드를 동시에 적용해서는 안 됩니다.

비교 항목사이드카 모드Ambient 모드
프록시 배치Pod당 1개 Envoy노드당 ztunnel + 선택적 waypoint
메모리 오버헤드Pod당 50~100MB노드당 20~40MB (ztunnel)
CPU 오버헤드Pod당 10~50m노드당 10~30m (ztunnel)
100 Pod 총 비용5~10GB 메모리60~120MB (3노드 기준)
네트워크 지연출발/도착 각 1홉 추가L4: 유사, L7: waypoint 추가 홉
Pod 시작 영향2~5초 지연 (사이드카 초기화)영향 없음
메시 추가 방법Pod 재시작 필요 (사이드카 주입)네임스페이스 레이블만 추가
메시 제거 방법Pod 재시작 필요레이블 제거 (재시작 불필요)
L7 정책 적용모든 트래픽에 기본 적용waypoint 배포 후에만 적용
워크로드 격리Pod별 완전 격리노드별 공유 (ztunnel)
EnvoyFilter 지원완전 지원제한적 (waypoint에서만 가능)
멀티클러스터완전 지원개선 중
성숙도GA (프로덕션 안정)Beta (v1.22+, 프로덕션 권장)
업그레이드 방식Pod 롤링 재시작 필요ztunnel DaemonSet 롤링 업데이트

어떤 모드를 선택해야 하는가

Ambient 모드가 적합한 경우:

  • 대규모 클러스터에서 리소스 효율성이 중요한 경우
  • 대부분의 서비스가 L4 보안(mTLS, 네트워크 정책)만 필요한 경우
  • Pod 재시작 없이 메시를 점진적으로 도입하고 싶은 경우
  • 사이드카 관리 운영 부담을 줄이고 싶은 경우

사이드카 모드가 적합한 경우:

  • Pod별 완전한 네트워크 격리가 필요한 경우
  • EnvoyFilter를 활용한 세밀한 프록시 커스터마이징이 필요한 경우
  • 멀티클러스터 또는 VM 네트워킹이 핵심인 경우
  • L7 정책을 모든 서비스에 기본 적용해야 하는 경우

설치와 구성

사전 요구사항

# Kubernetes 클러스터 버전 확인 (1.27+ 권장)
kubectl version --short

# istioctl 설치 (최신 버전)
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH

# istioctl 버전 확인
istioctl version

Ambient 프로필로 Istio 설치

# ambient 프로필로 Istio 설치
istioctl install --set profile=ambient --skip-confirmation

# 설치 확인
kubectl get pods -n istio-system

# 예상 출력:
# NAME                      READY   STATUS    RESTARTS   AGE
# istiod-xxxx               1/1     Running   0          2m
# ztunnel-xxxxx             1/1     Running   0          2m
# ztunnel-yyyyy             1/1     Running   0          2m
# ztunnel-zzzzz             1/1     Running   0          2m
# istio-cni-node-xxxxx      1/1     Running   0          2m
# istio-cni-node-yyyyy      1/1     Running   0          2m
# istio-cni-node-zzzzz      1/1     Running   0          2m

ambient 프로필은 다음 컴포넌트를 설치합니다:

  • istiod: 컨트롤 플레인 (Pilot, Citadel, Galley 통합)
  • ztunnel: 각 노드의 L4 프록시 (DaemonSet)
  • istio-cni: 트래픽 리디렉션을 위한 CNI 플러그인 (DaemonSet)

네임스페이스를 메시에 추가

# 네임스페이스를 ambient 메시에 추가 (Pod 재시작 불필요!)
kubectl label namespace my-app istio.io/dataplane-mode=ambient

# 레이블 확인
kubectl get namespace my-app --show-labels

# 특정 Pod만 메시에서 제외
kubectl label pod my-pod -n my-app istio.io/dataplane-mode=none

# 메시에서 네임스페이스 제거 (Pod 재시작 불필요!)
kubectl label namespace my-app istio.io/dataplane-mode-

주의사항: 하나의 네임스페이스에 사이드카 모드(istio-injection=enabled)와 ambient 모드(istio.io/dataplane-mode=ambient) 레이블을 동시에 적용해서는 안 됩니다.

Helm을 사용한 설치

프로덕션 환경에서는 Helm을 사용하여 세밀한 설정 관리가 권장됩니다.

# Istio Helm 저장소 추가
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update

# istio-base (CRDs) 설치
helm install istio-base istio/base -n istio-system --create-namespace

# istiod 설치 (ambient 프로필)
helm install istiod istio/istiod -n istio-system \
  --set profile=ambient \
  --set pilot.resources.requests.memory=256Mi \
  --set pilot.resources.requests.cpu=200m

# ztunnel 설치
helm install ztunnel istio/ztunnel -n istio-system \
  --set resources.requests.memory=64Mi \
  --set resources.requests.cpu=50m

# istio-cni 설치
helm install istio-cni istio/cni -n istio-system \
  --set ambient.enabled=true

트래픽 정책 구성

L4 AuthorizationPolicy

ztunnel에서 처리되는 L4 수준의 접근 제어 정책입니다. Waypoint proxy 없이도 동작합니다.

# L4 AuthorizationPolicy: 특정 서비스만 접근 허용
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: my-app
spec:
  targetRefs:
    - kind: Service
      group: ''
      name: backend
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - 'cluster.local/ns/my-app/sa/frontend'
      to:
        - operation:
            ports: ['8080']
---
# L4 기본 거부 정책
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: my-app
spec:
  targetRefs:
    - kind: Service
      group: ''
      name: backend
  action: DENY
  rules: []

L7 AuthorizationPolicy (Waypoint 필요)

HTTP 경로, 메서드 기반의 세밀한 접근 제어는 waypoint proxy 배포 후 사용할 수 있습니다.

# 먼저 waypoint proxy 배포
# istioctl waypoint apply -n my-app

# L7 AuthorizationPolicy: HTTP 경로 기반 제어
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: api-access-control
  namespace: my-app
spec:
  targetRefs:
    - kind: Service
      group: ''
      name: api-server
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - 'cluster.local/ns/my-app/sa/web-frontend'
      to:
        - operation:
            methods: ['GET']
            paths: ['/api/v1/products/*']
    - from:
        - source:
            principals:
              - 'cluster.local/ns/my-app/sa/admin-service'
      to:
        - operation:
            methods: ['GET', 'POST', 'PUT', 'DELETE']
            paths: ['/api/v1/*']

VirtualService를 활용한 트래픽 분할

# 카나리 배포를 위한 트래픽 분할 (Waypoint 필요)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: reviews-canary
  namespace: my-app
spec:
  hosts:
    - reviews
  http:
    - match:
        - headers:
            x-canary:
              exact: 'true'
      route:
        - destination:
            host: reviews
            subset: v2
          weight: 100
    - route:
        - destination:
            host: reviews
            subset: v1
          weight: 90
        - destination:
            host: reviews
            subset: v2
          weight: 10
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: reviews-dr
  namespace: my-app
spec:
  host: reviews
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

PeerAuthentication 설정

# Strict mTLS 적용 (ambient 모드에서는 기본적으로 활성화)
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: strict-mtls
  namespace: my-app
spec:
  mtls:
    mode: STRICT

관찰가능성 통합

Prometheus 메트릭 수집

Ambient Mesh는 ztunnel과 waypoint proxy 모두 Prometheus 메트릭을 노출합니다.

# Prometheus ServiceMonitor for ztunnel
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: ztunnel-monitor
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: ztunnel
  endpoints:
    - port: http-monitoring
      path: /metrics
      interval: 15s
---
# Prometheus ServiceMonitor for waypoint proxies
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: waypoint-monitor
  namespace: my-app
spec:
  selector:
    matchLabels:
      gateway.istio.io/managed: istio.io-mesh-controller
  endpoints:
    - port: http-envoy-prom
      path: /stats/prometheus
      interval: 15s

주요 메트릭 모니터링

# ztunnel 메트릭 확인
kubectl exec -n istio-system $(kubectl get pod -n istio-system -l app=ztunnel -o jsonpath='{.items[0].metadata.name}') -- curl -s localhost:15020/metrics | grep istio_tcp

# 주요 ztunnel 메트릭:
# istio_tcp_connections_opened_total     - 열린 TCP 연결 수
# istio_tcp_connections_closed_total     - 닫힌 TCP 연결 수
# istio_tcp_sent_bytes_total             - 전송 바이트
# istio_tcp_received_bytes_total         - 수신 바이트
# istio_tcp_connection_duration_seconds  - 연결 지속 시간

# waypoint proxy 메트릭 확인 (L7 메트릭 포함)
kubectl exec -n my-app $(kubectl get pod -n my-app -l gateway.istio.io/managed=istio.io-mesh-controller -o jsonpath='{.items[0].metadata.name}') -- curl -s localhost:15090/stats/prometheus | grep istio_request

# 주요 waypoint 메트릭:
# istio_requests_total                   - 총 요청 수 (L7)
# istio_request_duration_milliseconds    - 요청 지연 (L7)
# istio_request_bytes                    - 요청 크기
# istio_response_bytes                   - 응답 크기

Kiali 통합

Kiali는 Ambient Mesh를 지원하여 ztunnel과 waypoint proxy를 포함한 서비스 그래프를 시각화할 수 있습니다.

# Kiali 설치 (Ambient 지원 포함)
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/kiali.yaml

# Kiali 대시보드 접속
istioctl dashboard kiali

Grafana 대시보드

# Grafana + Prometheus 스택 설치
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/prometheus.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/grafana.yaml

# Grafana 대시보드 접속
istioctl dashboard grafana

Ambient Mesh용 Grafana 대시보드에서 확인해야 할 핵심 패널:

  • ztunnel 노드별 TCP 연결 수 및 바이트 트래픽
  • Waypoint proxy별 HTTP 요청률 및 에러율
  • mTLS 핸드셰이크 성공/실패율
  • HBONE 터널 지연 시간

마이그레이션 전략

사이드카에서 Ambient 모드로의 전환

기존 Istio 사이드카 모드에서 Ambient 모드로의 마이그레이션은 단계적으로 수행해야 합니다. 두 모드는 같은 클러스터에서 공존할 수 있으므로, 네임스페이스별로 점진적인 전환이 가능합니다.

단계 1: 사전 준비

# 현재 Istio 버전이 ambient을 지원하는지 확인 (1.22+)
istioctl version

# ambient 프로필 컴포넌트 설치 (기존 istiod 유지)
istioctl install --set profile=ambient --skip-confirmation

# ztunnel과 istio-cni가 정상 동작하는지 확인
kubectl get daemonset -n istio-system ztunnel
kubectl get daemonset -n istio-system istio-cni-node

단계 2: 비핵심 네임스페이스부터 전환

# 테스트용 네임스페이스에서 먼저 검증
# 1. 사이드카 레이블 제거
kubectl label namespace test-app istio-injection-

# 2. ambient 레이블 추가
kubectl label namespace test-app istio.io/dataplane-mode=ambient

# 3. 기존 사이드카를 제거하기 위해 Pod 재시작
kubectl rollout restart deployment -n test-app

# 4. 사이드카가 제거되고 ztunnel을 통해 통신하는지 확인
kubectl get pods -n test-app
# 모든 Pod이 1/1 (사이드카 없음)으로 표시되어야 함

# 5. mTLS 통신 확인
istioctl proxy-status

단계 3: L7 기능이 필요한 네임스페이스에 Waypoint 배포

# 기존에 L7 정책을 사용하던 네임스페이스에 waypoint 배포
istioctl waypoint apply -n test-app

# VirtualService, AuthorizationPolicy 등 기존 L7 정책이
# waypoint를 통해 정상 동작하는지 확인
kubectl get gateway -n test-app

단계 4: 검증 후 프로덕션 네임스페이스 전환

# 프로덕션 네임스페이스 전환 (동일 절차)
kubectl label namespace production istio-injection-
kubectl label namespace production istio.io/dataplane-mode=ambient
kubectl rollout restart deployment -n production

# waypoint 필요 시 배포
istioctl waypoint apply -n production

마이그레이션 시 주의사항

HBONE 호환성: 사이드카 모드의 Pod이 ambient 모드의 Pod와 통신하려면 사이드카에 ENABLE_HBONE 플래그가 설정되어 있어야 합니다. 마이그레이션 전에 사이드카를 HBONE 지원 버전으로 업데이트하고 재시작해야 합니다.

Waypoint 인식: 사이드카는 waypoint proxy를 인식하지 못합니다. 사이드카 모드의 클라이언트가 ambient 모드의 서버에 요청을 보내면 waypoint를 우회할 수 있습니다. 가능한 한 같은 통신 경로의 서비스들을 동일한 모드로 전환하는 것이 권장됩니다.

CNI 호환성: Cilium을 CNI로 사용하는 경우, Cilium이 기본적으로 다른 CNI 플러그인을 제거하려고 합니다. cni.exclusive=false 설정으로 이를 방지해야 합니다.

트러블슈팅

일반적인 문제와 해결 방법

문제 1: Pod 간 통신 실패 (mTLS 핸드셰이크 오류)

# 증상: Pod 간 연결이 거부되거나 타임아웃
# 원인: ztunnel이 정상 동작하지 않거나 인증서 문제

# 진단 1: ztunnel 상태 확인
kubectl get pods -n istio-system -l app=ztunnel
kubectl logs -n istio-system -l app=ztunnel --tail=100 | grep -i error

# 진단 2: 인증서 상태 확인
istioctl proxy-status

# 진단 3: 워크로드 ID 확인
kubectl exec -n istio-system $(kubectl get pod -n istio-system -l app=ztunnel -o jsonpath='{.items[0].metadata.name}') -- curl -s localhost:15020/debug/workloadz

# 해결: ztunnel 재시작
kubectl rollout restart daemonset ztunnel -n istio-system

문제 2: L7 정책이 적용되지 않음

# 증상: AuthorizationPolicy의 HTTP 경로/메서드 기반 규칙이 무시됨
# 원인: waypoint proxy가 배포되지 않았거나 올바르게 연결되지 않음

# 진단 1: waypoint proxy 존재 여부 확인
kubectl get gateway -n my-app
istioctl waypoint list -n my-app

# 진단 2: waypoint proxy Pod 상태 확인
kubectl get pods -n my-app -l gateway.istio.io/managed=istio.io-mesh-controller

# 진단 3: waypoint proxy 로그 확인
kubectl logs -n my-app -l gateway.istio.io/managed=istio.io-mesh-controller --tail=100

# 해결: waypoint 재배포
istioctl waypoint delete -n my-app
istioctl waypoint apply -n my-app

문제 3: CNI 플러그인 충돌

# 증상: ztunnel이 트래픽을 가로채지 못함, Pod이 메시 외부처럼 동작
# 원인: istio-cni와 기존 CNI 플러그인 간 충돌

# 진단: istio-cni 로그 확인
kubectl logs -n istio-system -l k8s-app=istio-cni-node --tail=100

# 해결 (Cilium 환경):
# Cilium의 exclusive CNI 설정 비활성화
helm upgrade cilium cilium/cilium -n kube-system \
  --set cni.exclusive=false

# istio-cni 재시작
kubectl rollout restart daemonset istio-cni-node -n istio-system

문제 4: 메시 외부 서비스와의 통신 문제

# 증상: ambient 메시 내 Pod이 메시 외부 서비스에 접근 불가
# 원인: ztunnel이 외부 트래픽도 가로채서 HBONE 터널링을 시도

# 진단: ztunnel 로그에서 외부 목적지 관련 오류 확인
kubectl logs -n istio-system -l app=ztunnel --tail=200 | grep "external"

# 해결: ServiceEntry로 외부 서비스를 명시적으로 등록
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: external-api
  namespace: my-app
spec:
  hosts:
    - api.external-service.com
  location: MESH_EXTERNAL
  ports:
    - number: 443
      name: https
      protocol: TLS
  resolution: DNS
EOF

문제 5: ztunnel 메모리 사용량 급증

# 증상: ztunnel Pod의 메모리 사용량이 지속적으로 증가
# 원인: 대량의 동시 연결 또는 메모리 누수

# 진단: 현재 메모리 사용량 확인
kubectl top pods -n istio-system -l app=ztunnel

# 진단: 연결 수 확인
kubectl exec -n istio-system $(kubectl get pod -n istio-system -l app=ztunnel -o jsonpath='{.items[0].metadata.name}') -- curl -s localhost:15020/metrics | grep tcp_connections

# 해결: ztunnel 리소스 제한 조정
helm upgrade ztunnel istio/ztunnel -n istio-system \
  --set resources.limits.memory=256Mi \
  --set resources.requests.memory=128Mi

프로덕션 체크리스트

Ambient Mesh를 프로덕션 환경에 배포하기 전 반드시 확인해야 할 항목들입니다.

설치 전 확인

  • Kubernetes 클러스터 버전이 1.27 이상인지 확인
  • Istio 버전이 1.22 이상(ambient Beta)인지 확인
  • CNI 플러그인 호환성 검증 (Calico, Cilium 등)
  • Gateway API CRD가 설치되어 있는지 확인
  • 노드 리소스 여유분 확인 (ztunnel DaemonSet용)

네트워크 설정

  • 기존 사이드카 모드와 ambient 모드의 네임스페이스가 겹치지 않는지 확인
  • HBONE 포트(15008)가 노드 간 방화벽에서 허용되는지 확인
  • ztunnel 메트릭 포트(15020)가 Prometheus에서 접근 가능한지 확인
  • 메시 외부 서비스에 대한 ServiceEntry가 구성되어 있는지 확인

보안 설정

  • PeerAuthentication이 STRICT mTLS로 설정되어 있는지 확인
  • L4 AuthorizationPolicy 기본 거부 정책이 설정되어 있는지 확인
  • L7 정책이 필요한 네임스페이스에 waypoint proxy가 배포되어 있는지 확인
  • SPIFFE ID 기반의 서비스 간 접근 제어가 구성되어 있는지 확인

관찰가능성

  • Prometheus가 ztunnel과 waypoint 메트릭을 수집하도록 설정되어 있는지 확인
  • Grafana 대시보드에 ambient mesh 전용 패널이 구성되어 있는지 확인
  • Kiali가 ambient 모드를 지원하는 버전인지 확인
  • 알림 규칙이 ztunnel 장애, waypoint 에러율에 대해 설정되어 있는지 확인

고가용성

  • ztunnel DaemonSet의 updateStrategy가 RollingUpdate인지 확인
  • waypoint proxy의 replicas가 최소 2개 이상인지 확인
  • waypoint proxy에 PodDisruptionBudget이 설정되어 있는지 확인
  • istiod의 replicas가 최소 2개 이상인지 확인

마이그레이션 (사이드카에서 전환 시)

  • 비핵심 네임스페이스에서 먼저 검증을 완료했는지 확인
  • 사이드카 모드의 Pod이 HBONE을 지원하는 버전인지 확인
  • 기존 VirtualService/DestinationRule이 waypoint에서 정상 동작하는지 확인
  • 롤백 절차가 문서화되어 있는지 확인

실패 사례와 복구 절차

사례 1: ztunnel DaemonSet 업데이트 중 서비스 중단

상황: ztunnel DaemonSet을 업데이트할 때 특정 노드에서 새 ztunnel Pod이 시작되기 전에 기존 ztunnel Pod이 종료되어 해당 노드의 모든 메시 트래픽이 중단됨.

원인: maxUnavailable 설정이 너무 높거나, 새 ztunnel Pod의 시작이 지연됨.

복구 절차:

# 1. 영향받는 노드 확인
kubectl get pods -n istio-system -l app=ztunnel -o wide

# 2. 업데이트 일시 중지 (가능한 경우)
kubectl rollout pause daemonset ztunnel -n istio-system

# 3. 영향받는 노드에서 ztunnel 수동 복구
kubectl delete pod -n istio-system $(kubectl get pod -n istio-system -l app=ztunnel --field-selector spec.nodeName=affected-node -o jsonpath='{.items[0].metadata.name}')

# 4. ztunnel 복구 확인
kubectl get pods -n istio-system -l app=ztunnel -o wide

# 예방 조치: maxUnavailable을 1로 설정
kubectl patch daemonset ztunnel -n istio-system -p '{"spec":{"updateStrategy":{"rollingUpdate":{"maxUnavailable":1}}}}'

사례 2: Waypoint Proxy 과부하로 인한 L7 정책 지연

상황: 특정 네임스페이스의 waypoint proxy에 트래픽이 집중되어 응답 지연이 급증.

원인: waypoint proxy 레플리카 수가 트래픽 볼륨에 비해 부족함.

복구 절차:

# 1. waypoint proxy 상태 확인
kubectl get pods -n affected-namespace -l gateway.istio.io/managed=istio.io-mesh-controller
kubectl top pods -n affected-namespace -l gateway.istio.io/managed=istio.io-mesh-controller

# 2. 즉각적 스케일 아웃
kubectl scale deployment -n affected-namespace $(kubectl get deployment -n affected-namespace -l gateway.istio.io/managed=istio.io-mesh-controller -o jsonpath='{.items[0].metadata.name}') --replicas=5

# 3. HPA 설정으로 자동 스케일링 적용 (위의 HPA 예시 참조)

# 4. 필요시 일시적으로 L7 정책을 L4로 완화
# waypoint를 제거하면 L7 정책이 비활성화되고 L4(ztunnel)로 폴백
# istioctl waypoint delete -n affected-namespace
# (주의: L7 정책이 모두 비활성화됨)

사례 3: 사이드카-Ambient 혼합 모드에서 통신 장애

상황: 마이그레이션 중 사이드카 모드 네임스페이스의 서비스가 ambient 모드 네임스페이스의 서비스를 호출할 때 간헐적으로 실패.

원인: 사이드카가 HBONE 프로토콜을 지원하지 않는 이전 버전이거나, 사이드카가 waypoint proxy를 인식하지 못해 트래픽을 직접 백엔드로 보냄.

복구 절차:

# 1. 사이드카의 HBONE 지원 여부 확인
kubectl exec -n sidecar-namespace deployment/my-app -c istio-proxy -- pilot-agent request GET /debug/config_dump | grep ENABLE_HBONE

# 2. HBONE이 비활성화된 경우, 사이드카 재시작으로 최신 설정 반영
kubectl rollout restart deployment -n sidecar-namespace

# 3. 여전히 문제가 있으면 해당 네임스페이스도 ambient 모드로 전환
kubectl label namespace sidecar-namespace istio-injection-
kubectl label namespace sidecar-namespace istio.io/dataplane-mode=ambient
kubectl rollout restart deployment -n sidecar-namespace

사례 4: istiod 장애 시 ambient 메시 영향

상황: istiod Pod이 모두 비정상이 되어 인증서 갱신이 중단됨.

원인: istiod 리소스 부족, etcd 연결 문제, 또는 Webhook 설정 오류.

복구 절차:

# 1. istiod 상태 확인
kubectl get pods -n istio-system -l app=istiod
kubectl logs -n istio-system -l app=istiod --tail=200

# 2. istiod 재시작
kubectl rollout restart deployment istiod -n istio-system

# 3. 인증서 갱신 상태 확인
istioctl proxy-status

# 참고: istiod가 다운되더라도 기존 mTLS 연결은 인증서 만료 전까지 유지됨
# 기본 인증서 TTL은 24시간이므로, istiod를 24시간 내에 복구해야 함

# 예방 조치: istiod HA 구성
helm upgrade istiod istio/istiod -n istio-system \
  --set pilot.replicaCount=3 \
  --set pilot.resources.requests.memory=512Mi \
  --set pilot.resources.requests.cpu=500m

참고자료