Istio 1.24 공식 문서 https://istio.io/v1.24/docs/
Ambient Mesh 공식 문서 https://istio.io/latest/docs/ambient/
스터디 실습 환경 : docker (kind - k8s 1.27+ '24.1.15 - Link) , istio 1.24.0('24.11.07) - Link
이 블로그 포스트는 Istio의 혁신적인 Ambient Mesh 기능에 대해 상세히 설명합니다. Ambient Mesh는 기존 사이드카 모델의 한계를 극복하고 서비스 메시의 새로운 패러다임을 제시하는 획기적인 기술입니다.
Istio의 사이드카 모델은 서비스 메시 분야에 혁신을 가져왔지만, 실제 운영 환경에서는 여러 가지 현실적인 문제들이 드러났습니다.
사이드카 주입의 복잡성
# 사이드카 주입으로 인한 Pod 사양 변경 예시
apiVersion: v1
kind: Pod
metadata:
name: productpage-v1
annotations:
sidecar.istio.io/status: '{"version":"...","initContainers":["istio-init"],"containers":["istio-proxy"]}'
spec:
initContainers:
- name: istio-init
image: docker.io/istio/proxyv2:1.17.8
# iptables 규칙 설정을 위한 특권 모드 필요
securityContext:
capabilities:
add: ["NET_ADMIN", "NET_RAW"]
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.17.0
- name: istio-proxy
image: docker.io/istio/proxyv2:1.17.8
# 사이드카 프록시 추가
운영상의 복잡성
개별 프록시로 인한 리소스 낭비
# 리소스 사용량 비교 분석
사이드카 모델:
- 각 Pod마다 개별 Envoy 프록시 (평균 100MB 메모리)
- 최악의 경우를 대비한 리소스 예약
- 클러스터 전체 리소스 활용도 저하 (30-40%)
실제 사례:
- 100개 Pod × 100MB 사이드카 = 10GB 메모리
- 실제 사용률: 30-40%
- 낭비되는 리소스: 6-7GB
CPU 사용량:
- 각 사이드카당 평균 50m CPU
- 유휴 상태에서도 지속적인 리소스 소비
- 스케일링 시 선형적 리소스 증가
리소스 예약의 문제점
HTTP 파싱 오버헤드
# 트래픽 처리 오버헤드 분석
기존 사이드카 방식:
- 모든 요청에 대한 HTTP 파싱
- L7 프로토콜 처리 비용
- 복잡한 네트워크 스택
- 일부 애플리케이션 호환성 문제
성능 영향:
- 지연시간 증가: 2-5ms 추가
- CPU 사용량 증가: 15-25%
- 메모리 오버헤드: 프록시당 50-100MB
- 네트워크 처리량 감소: 10-20%
애플리케이션 호환성 문제
Ambient Mesh는 이러한 문제들을 두 개의 분리된 계층으로 해결합니다. 이는 서비스 메시의 기능을 계층별로 분리하여 필요에 따라 선택적으로 적용할 수 있게 하는 혁신적인 아키텍처입니다.
Ambient Mesh는 기존 사이드카 모델과 근본적으로 다른 접근 방식을 취합니다. 가장 큰 차이점은 계층화된 아키텍처를 통해 서비스 메시 기능을 분리하고, 필요에 따라 선택적으로 적용할 수 있다는 점입니다.

계층별 상세 설명:
🔹 Application Layer (애플리케이션 계층)
🔹 Secure Overlay Layer (보안 오버레이 계층)
🔹 L7 Processing Layer (L7 처리 계층)
이러한 계층화 접근 방식의 핵심 장점:
1. 점진적 적용 (Progressive Enhancement)
2. 비침입적 배포 (Non-Invasive Deployment)
3. 리소스 효율성 (Resource Efficiency)
4. 운영 단순성 (Operational Simplicity)
| 측면 | 사이드카 모델 | Ambient Mesh |
|---|---|---|
| 배포 방식 | Pod별 사이드카 주입 | 네임스페이스 라벨 설정 |
| 리소스 사용 | Pod당 개별 프록시 | 노드별 공유 프록시 |
| 업그레이드 | 모든 Pod 재시작 | 독립적 컴포넌트 업그레이드 |
| 침입성 | 높음 (Pod 수정 필요) | 낮음 (투명한 적용) |
| 복잡성 | 높음 | 낮음 |
| 메트릭 | 사이드카 모델 | Ambient L4 | Ambient L7 | 개선율 |
|---|---|---|---|---|
| 메모리 사용량 | ~100MB/Pod | ~20MB/Node | +Waypoint | 60-80% 절약 |
| CPU 사용량 | ~50m/Pod | ~10m/Node | +Waypoint | 70-85% 절약 |
| 네트워크 지연 | 2-3ms | 1-2ms | 2-3ms | 30-50% 개선 |
| 시작 시간 | 10-15초 | 즉시 | 즉시 | 90% 개선 |
| 처리량 | 기준 | +15-20% | 기준 | 15-20% 향상 |
| 기능 | 사이드카 | Ambient L4 | Ambient L7 |
|---|---|---|---|
| mTLS | ✅ | ✅ | ✅ |
| L4 정책 | ✅ | ✅ | ✅ |
| HTTP 라우팅 | ✅ | ❌ | ✅ |
| 트래픽 분할 | ✅ | ❌ | ✅ |
| 서킷 브레이커 | ✅ | ❌ | ✅ |
| 재시도 정책 | ✅ | ❌ | ✅ |
| JWT 인증 | ✅ | ❌ | ✅ |
| 텔레메트리 | L7 상세 | L4 기본 | L7 상세 |
ztunnel은 Ambient Mesh의 핵심 구성 요소로, 각 노드에서 DaemonSet으로 실행되는 경량 프록시입니다. Rust 언어로 구현되어 메모리 안전성과 성능을 동시에 확보했습니다.
기술적 특징
구현 언어: Rust
- 메모리 안전성 보장
- 제로 카피 네트워킹
- 높은 성능과 낮은 리소스 사용량
배포 방식: DaemonSet
- 노드당 하나의 인스턴스
- 모든 워크로드 공유
- 자동 스케일링 불필요
처리 레벨: L4 (Transport Layer)
- TCP/UDP 프로토콜 처리
- HTTP 파싱 없음
- 최소한의 오버헤드
핵심 기능
ztunnel은 Ambient Mesh의 핵심 구성 요소로서, 노드별 공유 프록시의 역할을 수행합니다. 기존 사이드카 모델과 달리 각 노드에 하나씩만 배포되어 해당 노드의 모든 워크로드를 담당합니다. 이는 리소스 효율성과 운영 단순성을 크게 향상시키는 핵심 설계입니다.

ztunnel 아키텍처의 핵심 구성 요소:
🔹 Control Plane Interface (컨트롤 플레인 인터페이스)
이 계층은 ztunnel이 Istio 컨트롤 플레인과 통신하는 부분입니다. 각 구성 요소는 특별한 역할을 담당합니다:
xDS Client:
CA Client:
L4 Policy Engine:
🔹 Core Proxy Engine (핵심 프록시 엔진)
ztunnel의 핵심 트래픽 처리 엔진으로, 모든 네트워크 트래픽이 이 계층을 통과합니다:
Inbound Listener (포트 15006):
Outbound Listener (포트 15001):
🔹 L4 Telemetry & Monitoring (L4 텔레메트리 및 모니터링)
ztunnel의 관찰성을 제공하는 계층으로, 운영 및 디버깅에 필수적인 정보를 수집합니다:
Metrics Collection:
Logs Collection:
ztunnel 아키텍처의 설계 철학:
트래픽 인터셉션
# ztunnel 트래픽 처리 과정
1. 트래픽 캡처:
- eBPF 또는 iptables를 통한 투명한 인터셉션
- 애플리케이션 수정 없이 자동 적용
2. 워크로드 식별:
- SPIFFE ID 기반 인증
- 네임스페이스, 서비스 계정 정보 활용
3. 정책 적용:
- L4 네트워크 정책 검증
- 접근 제어 규칙 시행
4. mTLS 처리:
- 자동 인증서 관리
- 투명한 암호화/복호화
5. 라우팅:
- 서비스 디스커버리
- 로드 밸런싱
메모리 및 성능 최적화
// ztunnel의 Rust 구현 예시 (의사 코드)
use tokio::net::{TcpListener, TcpStream};
use rustls::{ServerConfig, ClientConfig};
struct ZTunnel {
inbound_listener: TcpListener,
outbound_listener: TcpListener,
tls_config: ServerConfig,
policy_engine: PolicyEngine,
}
impl ZTunnel {
async fn handle_connection(&self, stream: TcpStream) -> Result<()> {
// 제로 카피 네트워킹으로 성능 최적화
let (read_half, write_half) = stream.into_split();
// 비동기 처리로 동시성 확보
tokio::spawn(async move {
self.process_traffic(read_half, write_half).await
});
Ok(())
}
async fn process_traffic(&self, read: ReadHalf, write: WriteHalf) {
// L4 레벨 처리만 수행 (HTTP 파싱 없음)
// mTLS 적용
// 정책 검증
// 라우팅
}
}
Waypoint Proxy는 필요에 따라 배포되는 Envoy 기반의 L7 프록시입니다. 기존 사이드카의 L7 기능을 선택적으로 제공하며, 목적지 지향적 정책 적용을 통해 확장성을 크게 개선했습니다.
배포 전략
배포 방식:
- 네임스페이스별 (기본 권장)
- 서비스 계정별
- 서비스별
- 크로스 네임스페이스
확장성:
- 수평적 스케일링 지원
- 트래픽 기반 자동 스케일링
- 독립적 업그레이드 가능
리소스 효율성:
- 필요시에만 배포
- 여러 서비스 공유 가능
- 동적 리소스 할당
주요 기능
기존 사이드카 모델의 문제점
# N² 확장 문제
사이드카 모델:
- 소스에서 정책 적용
- 모든 목적지 정보 필요
- 클러스터 크기에 따른 지수적 증가
예시:
- 100개 서비스 × 100개 목적지 = 10,000개 정책 규칙
- 새 서비스 추가 시 모든 사이드카 업데이트 필요
- 설정 복잡성 및 전파 지연 증가
Waypoint 모델의 해결책
# 선형 확장 모델
Waypoint 모델:
- 목적지에서 정책 적용
- 자체 네임스페이스 정보만 필요
- 클러스터 크기에 따른 선형 증가
예시:
- 100개 서비스 × 1개 네임스페이스 = 100개 정책 규칙
- 새 서비스 추가 시 해당 Waypoint만 업데이트
- 설정 단순화 및 빠른 전파
Waypoint Proxy는 Ambient Mesh에서 선택적 L7 처리를 담당하는 핵심 구성 요소입니다. 기존 사이드카 모델과 달리 목적지 지향 정책 적용을 통해 확장성 문제를 해결하고, 필요한 경우에만 배포되어 리소스 효율성을 극대화합니다.

Waypoint Proxy 아키텍처의 핵심 구성 요소:
🔹 Control Plane Integration (컨트롤 플레인 통합)
Waypoint Proxy는 Istio 컨트롤 플레인과 긴밀하게 통합되어 동적 설정 관리를 수행합니다:
xDS Server 연동:
Policy Engine:
🔹 Protocol Handlers (프로토콜 핸들러)
다양한 애플리케이션 프로토콜을 지원하여 폭넓은 호환성을 제공합니다:
HTTP Filters:
gRPC Filters:
🔹 Security & Traffic Control (보안 및 트래픽 제어)
고급 보안 기능과 트래픽 제어 메커니즘을 제공합니다:
Auth Filters:
Traffic Control:
🔹 Observability & Routing (관찰성 및 라우팅)
상세한 관찰성과 고급 라우팅 기능을 제공합니다:
Telemetry Filters:
Routing Engine:
Waypoint Proxy의 핵심 설계 원칙:
HBONE (HTTP-Based Overlay Network Encapsulation)은 Ambient Mesh의 통신 프로토콜입니다. HTTP/2와 CONNECT 메서드를 기반으로 하여 표준 호환성과 효율성을 동시에 확보했습니다.
프로토콜 구성
기반 기술:
- HTTP/2 프로토콜
- CONNECT 메서드 활용
- mTLS 암호화
- 표준 기반 접근
장점:
- 기존 로드 밸런서와 호환
- 멀티플렉싱 지원
- 효율적인 연결 관리
- 방화벽 친화적
표준 호환성
CONNECT 요청 예시
# HBONE CONNECT 요청
:method: CONNECT
:scheme: https
:authority: 10.244.1.5:9080
:path: /api/v1/users?id=123
x-envoy-original-dst-host: 10.244.1.5:9080
x-forwarded-proto: hbone
x-istio-attributes: eyJzb3VyY2UiOnsibmFtZXNwYWNlIjoi...
x-istio-auth-userinfo: eyJ1c2VyIjoidGVzdCIsInJvbGVzIjpb...
user-agent: istio-ztunnel/1.24.0
# 요청 바디 (원본 HTTP 요청)
GET /api/v1/users?id=123 HTTP/1.1
Host: catalog.istioinaction.svc.cluster.local
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
헤더 설명
:authority: 목적지 Pod IP와 포트x-envoy-original-dst-host: 원본 목적지 정보x-forwarded-proto: HBONE 프로토콜 식별x-istio-attributes: 메타데이터 (base64 인코딩)x-istio-auth-userinfo: 인증 정보HBONE 프로토콜의 통신 흐름을 상세히 살펴보겠습니다. 이는 Ambient Mesh에서 노드 간 안전한 통신을 보장하는 핵심 메커니즘입니다.

통신 단계별 설명
1. 요청 생성: 애플리케이션에서 일반 HTTP 요청 생성
2. HBONE 캡슐화: ztunnel이 요청을 HBONE 프로토콜로 래핑
3. mTLS 암호화: SPIFFE 인증서를 사용한 상호 인증 및 암호화
4. CONNECT 터널: HTTP/2 CONNECT 메서드로 터널 생성
5. 멀티플렉싱: 단일 연결에서 여러 요청 동시 처리
6. 목적지 확인: 대상 ztunnel에서 요청 검증
7. 역캡슐화: 원본 HTTP 요청 복원
8. 응답 전달: 동일한 경로로 응답 반환
네트워크 호환성
성능 최적화
보안 강화
이 섹션에서는 Ambient Mesh를 실제로 구현하고 테스트하는 과정을 단계별로 진행합니다. 기존 사이드카 모델과의 비교를 통해 Ambient Mesh의 장점을 직접 확인할 수 있습니다.
먼저 Ambient Mesh를 지원하는 Kubernetes 클러스터를 구성합니다:
# kind 클러스터 생성 (Kubernetes 1.27+)
cat <<EOF | kind create cluster --name ambient-demo --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000 # Istio Ingress Gateway HTTP
hostPort: 30000
- containerPort: 30001 # Prometheus
hostPort: 30001
- containerPort: 30002 # Grafana
hostPort: 30002
- containerPort: 30003 # Kiali
hostPort: 30003
- containerPort: 30004 # Jaeger
hostPort: 30004
- containerPort: 30005 # Istio Ingress Gateway HTTPS
hostPort: 30005
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
controllerManager:
extraArgs:
bind-address: 0.0.0.0
networking:
podSubnet: 10.10.0.0/16
serviceSubnet: 10.200.1.0/24
EOF
# 클러스터 상태 확인
kubectl cluster-info
kubectl get nodes -o wide
예시 응답:
# kubectl cluster-info 출력
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
# kubectl get nodes -o wide 출력
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ambient-demo-control-plane Ready control-plane 2m v1.27.3 172.18.0.2 <none> Ubuntu 22.04.2 LTS 5.15.0-72-generic containerd://1.6.21
Ambient Mesh를 지원하는 Istio 1.24+를 설치합니다:
# Istio 1.24+ 다운로드 (Ambient GA 버전)
export ISTIO_VERSION=1.24.0
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIO_VERSION sh -
cd istio-$ISTIO_VERSION
export PATH=$PWD/bin:$PATH
# Ambient 프로필로 Istio 설치
istioctl install --set values.pilot.env.PILOT_ENABLE_AMBIENT=true -y
# 설치 확인
kubectl get pods -n istio-system
kubectl get daemonset -n istio-system
# ztunnel DaemonSet 확인
kubectl describe daemonset -n istio-system ztunnel
설치 결과 확인
# kubectl get pods -n istio-system 예상 출력
NAME READY STATUS RESTARTS AGE
istiod-7d58d9b7dd-k8s9x 1/1 Running 0 2m15s
ztunnel-h7k2m 1/1 Running 0 2m10s
# kubectl get daemonset -n istio-system 예상 출력
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
ztunnel 1 1 1 1 1 <none> 2m10s
# ztunnel이 모든 노드에 배포되었는지 확인
kubectl get pods -n istio-system -l app=ztunnel -o wide
예시 응답:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ztunnel-h7k2m 1/1 Running 0 2m 172.18.0.2 ambient-demo-control-plane <none> <none>
실습을 위한 네임스페이스와 샘플 애플리케이션을 배포합니다:
# 실습용 네임스페이스 생성
kubectl create namespace ambient-demo
kubectl create namespace sidecar-demo
# 샘플 애플리케이션 배포 (Ambient 모드용)
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n ambient-demo
# 샘플 애플리케이션 배포 (사이드카 모드용 - 비교 목적)
kubectl label namespace sidecar-demo istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n sidecar-demo
# 배포 상태 확인
kubectl get pods -n ambient-demo
kubectl get pods -n sidecar-demo
예시 응답:
# kubectl get pods -n ambient-demo 출력 (Ambient 모드)
NAME READY STATUS RESTARTS AGE
details-v1-5f4d584748-8xk2m 1/1 Running 0 2m
productpage-v1-564d4686f-7v8hn 1/1 Running 0 2m
ratings-v1-686ccfb5d8-htxwz 1/1 Running 0 2m
reviews-v1-86896b7648-z4c8r 1/1 Running 0 2m
reviews-v2-b7dcd98fb-6spzd 1/1 Running 0 2m
reviews-v3-5c5cc7b6d-m8s5f 1/1 Running 0 2m
# kubectl get pods -n sidecar-demo 출력 (사이드카 모드)
NAME READY STATUS RESTARTS AGE
details-v1-5f4d584748-9xm3n 2/2 Running 0 2m
productpage-v1-564d4686f-8w9io 2/2 Running 0 2m
ratings-v1-686ccfb5d8-iuyzx 2/2 Running 0 2m
reviews-v1-86896b7648-a5d9s 2/2 Running 0 2m
reviews-v2-b7dcd98fb-7tqae 2/2 Running 0 2m
reviews-v3-5c5cc7b6d-n9t6g 2/2 Running 0 2m
주목할 점:
1/1 Ready (애플리케이션 컨테이너만)2/2 Ready (애플리케이션 + 사이드카 컨테이너)# ambient-demo 네임스페이스에 Ambient 모드 활성화
kubectl label namespace ambient-demo istio.io/dataplane-mode=ambient
# 라벨 확인
kubectl get namespace ambient-demo --show-labels
# 워크로드가 Ambient 모드로 등록되었는지 확인
kubectl get pods -n ambient-demo -o yaml | grep -A5 -B5 "istio.io/dataplane-mode"
# ztunnel 로그 확인
kubectl logs -n istio-system -l app=ztunnel -f --tail=50
# 워크로드 등록 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/config_dump | jq '.configs[] | select(.["@type"] | contains("WorkloadManager"))'
# ztunnel 상태 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/stats | grep -E "(workload|ambient)"
# Ingress Gateway 설정
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n ambient-demo
# Gateway 서비스를 NodePort로 설정
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 8080, "nodePort": 30000, "name": "http2"}]}}'
# 트래픽 테스트
curl -s http://localhost:30000/productpage | grep -o "<title>.*</title>"
# 내부 서비스 간 통신 테스트
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
curl -s reviews:9080/reviews/1 | jq '.'
# 응답 확인 (정상 동작)
{
"id": "1",
"reviews": [{
"reviewer": "Reviewer1",
"text": "An extremely entertaining play by Shakespeare..."
}]
}
# ztunnel에서 mTLS 통계 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/stats | grep ssl
# 출력 예시:
# cluster.outbound|9080||reviews.ambient-demo.svc.cluster.local.ssl.handshake: 5
# listener.0.0.0.0_15006.ssl.connection_error: 0
# 인증서 정보 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/certs | jq '.certificates[] | {uri, valid_from, valid_to}'
# SPIFFE ID 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/certs | jq '.certificates[].uri'
# 출력 예시:
# "spiffe://cluster.local/ns/ambient-demo/sa/bookinfo-productpage"
# "spiffe://cluster.local/ns/ambient-demo/sa/bookinfo-reviews"
# 네트워크 패킷 캡처로 암호화 확인 (별도 터미널에서 실행)
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
tcpdump -i any -c 10 port 9080 &
# 트래픽 생성
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
curl -s reviews:9080/reviews/1
# mTLS 트래픽 확인 (암호화된 패킷)
# 출력에서 TLS handshake 및 암호화된 데이터 확인 가능
# L4 네트워크 정책 생성
cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: ambient-demo
spec:
action: DENY
rules:
- {}
EOF
# 정책 적용 후 트래픽 테스트 (실패해야 함)
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
curl -s reviews:9080/reviews/1 || echo "Connection denied by L4 policy"
# 특정 서비스만 허용하는 정책으로 변경
cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-productpage
namespace: ambient-demo
spec:
selector:
matchLabels:
app: reviews
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/ambient-demo/sa/bookinfo-productpage"]
EOF
# 정책 적용 후 트래픽 테스트 (성공해야 함)
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
curl -s reviews:9080/reviews/1 | jq '.id'
# 정책 정리
kubectl delete authorizationpolicy -n ambient-demo --all
# reviews 서비스용 Waypoint Proxy 생성
istioctl x waypoint generate --for service/reviews -n ambient-demo | \
kubectl apply -f -
# Waypoint Proxy 확인
kubectl get gateway -n ambient-demo
kubectl get pods -n ambient-demo -l gateway.istio.io/managed=istio.io-mesh-controller
# Waypoint Proxy 상태 확인
kubectl describe gateway -n ambient-demo reviews-istio-waypoint
# VirtualService로 트래픽 분할 설정
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
namespace: ambient-demo
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
weight: 80
- destination:
host: reviews
subset: v3
weight: 20
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
namespace: ambient-demo
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
EOF
# 일반 사용자 요청 (v1: 80%, v3: 20% 분할)
echo "=== 일반 사용자 요청 테스트 ==="
for i in {1..10}; do
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
curl -s reviews:9080/reviews/1 | jq -r '.reviews[0].rating // "no-rating"'
done
# jason 사용자 요청 (v2로 라우팅)
echo "=== jason 사용자 요청 테스트 ==="
for i in {1..5}; do
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
curl -s -H "end-user: jason" reviews:9080/reviews/1 | \
jq -r '.reviews[0].rating // "no-rating"'
done
# Waypoint Proxy 메트릭 확인
kubectl exec -n ambient-demo deployment/reviews-istio-waypoint -- \
curl -s localhost:15000/stats | grep -E "(upstream_rq_|version)"
# 재시도 정책 설정
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews-retry
namespace: ambient-demo
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
retries:
attempts: 3
perTryTimeout: 2s
retryOn: 5xx,reset,connect-failure,refused-stream
EOF
# 서킷 브레이커 설정
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews-circuit-breaker
namespace: ambient-demo
spec:
host: reviews
trafficPolicy:
outlierDetection:
consecutiveErrors: 3
interval: 30s
baseEjectionTime: 30s
maxEjectionPercent: 50
connectionPool:
tcp:
maxConnections: 10
http:
http1MaxPendingRequests: 10
maxRequestsPerConnection: 2
EOF
# 정책 적용 확인
kubectl exec -n ambient-demo deployment/productpage-v1 -- \
curl -s reviews:9080/reviews/1 | jq '.id'
# Ambient 모드 리소스 사용량
echo "=== Ambient Mesh 리소스 사용량 ==="
kubectl top pods -n istio-system
kubectl top pods -n ambient-demo
# 사이드카 모드 리소스 사용량
echo "=== 사이드카 모드 리소스 사용량 ==="
kubectl top pods -n sidecar-demo
# 메모리 사용량 상세 비교
echo "=== ztunnel 메모리 사용량 ==="
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/memory | jq '.allocated'
echo "=== Waypoint Proxy 메모리 사용량 ==="
kubectl exec -n ambient-demo deployment/reviews-istio-waypoint -- \
curl -s localhost:15000/memory | jq '.allocated'
# 사이드카 프록시 메모리 사용량
echo "=== 사이드카 프록시 메모리 사용량 ==="
kubectl exec -n sidecar-demo deployment/productpage-v1 -c istio-proxy -- \
curl -s localhost:15000/memory | jq '.allocated'
# 성능 테스트를 위한 부하 생성 도구 설치
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: fortio
namespace: ambient-demo
spec:
replicas: 1
selector:
matchLabels:
app: fortio
template:
metadata:
labels:
app: fortio
spec:
containers:
- name: fortio
image: fortio/fortio:latest
ports:
- containerPort: 8080
name: http
EOF
# Ambient Mesh 성능 테스트
echo "=== Ambient Mesh 성능 테스트 ==="
kubectl exec -n ambient-demo deployment/fortio -- \
fortio load -c 10 -t 30s -qps 100 http://reviews:9080/reviews/1
# 사이드카 모드 성능 테스트 (비교용)
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: fortio
namespace: sidecar-demo
spec:
replicas: 1
selector:
matchLabels:
app: fortio
template:
metadata:
labels:
app: fortio
spec:
containers:
- name: fortio
image: fortio/fortio:latest
ports:
- containerPort: 8080
name: http
EOF
echo "=== 사이드카 모드 성능 테스트 ==="
kubectl exec -n sidecar-demo deployment/fortio -- \
fortio load -c 10 -t 30s -qps 100 http://reviews:9080/reviews/1
# Ambient 모드 Pod 시작 시간 측정
echo "=== Ambient 모드 Pod 시작 시간 ==="
kubectl delete pod -n ambient-demo -l app=productpage
time kubectl wait --for=condition=ready pod -n ambient-demo -l app=productpage --timeout=60s
# 사이드카 모드 Pod 시작 시간 측정
echo "=== 사이드카 모드 Pod 시작 시간 ==="
kubectl delete pod -n sidecar-demo -l app=productpage
time kubectl wait --for=condition=ready pod -n sidecar-demo -l app=productpage --timeout=60s
# Prometheus 설치
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
cat <<EOF > prom-values.yaml
prometheusOperator:
tls:
enabled: false
admissionWebhooks:
patch:
enabled: false
prometheus:
service:
type: NodePort
nodePort: 30001
grafana:
service:
type: NodePort
nodePort: 30002
EOF
kubectl create ns prometheus
helm install prom prometheus-community/kube-prometheus-stack --version 45.7.1 \
-n prometheus -f prom-values.yaml
# Istio 메트릭 수집 설정
cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: istio-component-monitor
namespace: prometheus
labels:
monitoring: istio-components
release: prom
spec:
jobLabel: istio
targetLabels: [app]
selector:
matchExpressions:
- {key: istio, operator: In, values: [pilot]}
namespaceSelector:
any: true
endpoints:
- port: http-monitoring
interval: 15s
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: envoy-stats-monitor
namespace: prometheus
labels:
monitoring: istio-proxies
release: prom
spec:
selector:
matchExpressions:
- {key: istio-prometheus-ignore, operator: DoesNotExist}
namespaceSelector:
any: true
jobLabel: envoy-stats
podMetricsEndpoints:
- path: /stats/prometheus
interval: 15s
relabelings:
- action: keep
sourceLabels: [__meta_kubernetes_pod_container_name]
regex: "istio-proxy"
- action: keep
sourceLabels: [__meta_kubernetes_pod_annotationpresent_prometheus_io_scrape]
- sourceLabels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
targetLabel: __address__
- action: labeldrop
regex: "__meta_kubernetes_pod_label_(.+)"
- sourceLabels: [__meta_kubernetes_namespace]
action: replace
targetLabel: namespace
- sourceLabels: [__meta_kubernetes_pod_name]
action: replace
targetLabel: pod_name
EOF
# ztunnel 메트릭 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/stats/prometheus | grep istio
# 주요 메트릭:
# - istio_tcp_connections_opened_total
# - istio_tcp_connections_closed_total
# - istio_request_total
# - istio_request_duration_milliseconds
# ztunnel 전용 ServiceMonitor 생성
cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: ztunnel-monitor
namespace: prometheus
labels:
monitoring: ztunnel
release: prom
spec:
selector:
matchLabels:
app: ztunnel
namespaceSelector:
matchNames:
- istio-system
endpoints:
- port: http-monitoring
interval: 15s
path: /stats/prometheus
EOF
# Waypoint Proxy 메트릭 확인
kubectl exec -n ambient-demo deployment/reviews-istio-waypoint -- \
curl -s localhost:15000/stats/prometheus | grep istio
# L7 특화 메트릭:
# - istio_requests_total
# - istio_request_duration_milliseconds
# - istio_request_bytes
# - istio_response_bytes
# Waypoint 전용 ServiceMonitor 생성
cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: waypoint-monitor
namespace: prometheus
labels:
monitoring: waypoint
release: prom
spec:
selector:
matchLabels:
gateway.istio.io/managed: istio.io-mesh-controller
namespaceSelector:
any: true
endpoints:
- port: http-monitoring
interval: 15s
path: /stats/prometheus
EOF
Ambient Mesh의 L4 계층에서는 ztunnel이 모든 트래픽을 처리합니다. 이는 기존 사이드카 모델과 근본적으로 다른 접근 방식으로, 노드별 공유 프록시를 통해 효율성을 극대화합니다.

L4 트래픽 흐름의 핵심 특징:
🔸 투명한 인터셉션
🔸 SPIFFE 기반 인증
🔸 HBONE 프로토콜
🔸 성능 최적화
L7 기능이 필요한 경우 Waypoint Proxy를 경유하는 트래픽 흐름입니다. 이는 목적지 지향 정책 적용의 핵심 개념을 보여주며, 기존 사이드카 모델의 N² 확장 문제를 해결하는 혁신적인 접근 방식입니다.

L7 트래픽 흐름의 핵심 특징:
🔸 목적지 지향 정책 (Destination-Oriented Policy)
🔸 선택적 L7 처리
🔸 고급 L7 기능
🔸 성능 최적화
기존 사이드카 모델과 Ambient Mesh의 트래픽 흐름을 비교해보겠습니다:


주요 차이점:
| 측면 | 사이드카 모델 | Ambient Mesh |
|---|---|---|
| 프록시 배치 | Pod별 개별 사이드카 | 노드별 공유 ztunnel |
| L7 처리 | 모든 사이드카에서 처리 | 필요시에만 Waypoint에서 처리 |
| 리소스 사용 | Pod 수에 비례 증가 | 노드 수에 비례 (훨씬 적음) |
| 정책 적용 | 소스 지향 (N² 문제) | 목적지 지향 (선형 확장) |
| 업그레이드 | 모든 Pod 재시작 | 독립적 컴포넌트 업그레이드 |
L4 보안 (ztunnel):
- SPIFFE 기반 워크로드 인증
- 자동 mTLS 적용
- 네트워크 정책 시행
- 기본 접근 제어
L7 보안 (Waypoint):
- JWT 토큰 검증
- HTTP 헤더 기반 인가
- 세밀한 경로별 정책
- 고급 인증 통합
원칙:
- 기본적으로 모든 트래픽 암호화
- 워크로드 신원 기반 인증
- 최소 권한 원칙 적용
- 지속적인 검증
구현:
- SPIFFE/SPIRE 통합
- 자동 인증서 순환
- 정책 기반 접근 제어
- 실시간 위협 탐지
메모리 최적화:
- Rust의 메모리 안전성 활용
- 제로 카피 네트워킹
- 효율적인 연결 풀링
CPU 최적화:
- L7 처리 제거
- 비동기 I/O 활용
- 최적화된 패킷 처리
동적 스케일링:
- 트래픽 기반 자동 확장
- 리소스 사용량 모니터링
- 예측적 스케일링
로드 밸런싱:
- 지능형 트래픽 분산
- 헬스 체크 통합
- 장애 감지 및 복구
# 1단계: 개발 환경에서 테스트
kubectl label namespace dev-app istio.io/dataplane-mode=ambient
# 2단계: 스테이징 환경 적용
kubectl label namespace staging-app istio.io/dataplane-mode=ambient
# 3단계: 프로덕션 카나리 배포
kubectl label namespace prod-app-canary istio.io/dataplane-mode=ambient
# 4단계: 전체 프로덕션 적용
kubectl label namespace prod-app istio.io/dataplane-mode=ambient
확인 사항:
- Kubernetes 버전 (1.27+)
- Istio 버전 (1.24+)
- CNI 플러그인 호환성
- 기존 정책 마이그레이션
테스트 항목:
- 기본 연결성
- mTLS 동작
- 정책 적용
- 성능 벤치마크
# ztunnel 상태 확인
kubectl get pods -n istio-system -l app=ztunnel
# 워크로드 등록 확인
kubectl get pods -n ambient-demo -o yaml | grep istio.io/dataplane-mode
# 네트워크 정책 확인
kubectl describe networkpolicy -n ambient-demo
# ztunnel 로그 분석
kubectl logs -n istio-system -l app=ztunnel | grep ERROR
# 인증서 상태 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/certs | jq '.certificates[] | {uri, valid_from, valid_to}'
# 클러스터 상태 확인
kubectl exec -n istio-system daemonset/ztunnel -- \
curl -s localhost:15000/clusters | grep HEALTHY
Ambient Mesh는 서비스 메시 기술의 새로운 전환점을 제시합니다:
적용 시나리오:
권장:
- 새로운 마이크로서비스 환경
- 리소스 제약이 있는 환경
- 운영 복잡성 감소가 필요한 경우
- 점진적 서비스 메시 도입
신중 검토:
- 복잡한 L7 정책이 많은 환경
- 커스텀 Envoy 필터 사용
- 레거시 애플리케이션 통합
Ambient Mesh를 성공적으로 도입하기 위한 모범 사례:
Ambient Mesh는 서비스 메시의 미래를 제시하는 혁신적인 기술입니다. 기존 사이드카 모델의 한계를 극복하면서도 서비스 메시의 핵심 가치를 유지하는 이 기술은, 클라우드 네이티브 애플리케이션의 운영 복잡성을 크게 줄이고 리소스 효율성을 향상시킬 것입니다.