Advanced 퀴즈
지원 버전: Istio 1.28.0 EKS 버전: 1.34 (Kubernetes 1.28+) 마지막 업데이트: 2026년 2월 19일
이 퀴즈는 Istio의 고급 기능에 대한 이해도를 테스트합니다.
객관식 문제 (1-5번)
문제 1: Ambient Mode vs Sidecar Mode
Istio Ambient Mode의 가장 큰 장점은?
A. 더 많은 기능 제공
B. 리소스 사용량 대폭 감소
C. 더 빠른 설치 속도
D. 더 나은 보안
정답 및 해설
정답: B
Ambient Mode의 가장 큰 장점은 리소스 사용량이 98% 이상 감소한다는 것입니다.
해설:
Sidecar Mode vs Ambient Mode 비교:
| 항목 | Sidecar Mode | Ambient Mode | 개선 |
|---|---|---|---|
| 메모리 | 50MB × Pod 수 | ztunnel + waypoint만 | 98%+ 감소 |
| CPU | 0.1 vCPU × Pod 수 | ztunnel + waypoint만 | 98%+ 감소 |
| Pod 재시작 | 필요 | 불필요 | 운영 간소화 |
| 배포 속도 | 느림 (Sidecar 주입) | 빠름 | 5-10배 향상 |
1000개 Pod 규모에서 리소스 비교:
Sidecar Mode:
- 메모리: 1000 × 50MB = 50GB
- CPU: 1000 × 0.1 vCPU = 100 vCPU
Ambient Mode (10개 노드):
- 메모리: (10 × 50MB) + 200MB = 700MB
- CPU: (10 × 0.1 vCPU) + 0.5 vCPU = 1.5 vCPU
절감률: 98.6% (메모리), 98.5% (CPU)Ambient Mode 아키텍처:
Ambient Mode 활성화:
# Ambient Mode로 Istio 설치
istioctl install --set profile=ambient -y
# Namespace를 Ambient Mode에 추가
kubectl label namespace default istio.io/dataplane-mode=ambient
# 확인
kubectl get pods -n istio-system | grep ztunnel각 옵션 분석:
- A (X): 기능은 Sidecar와 동일 (일부 고급 기능은 waypoint 필요)
- B (O): 리소스 사용량이 98% 이상 감소
- C (X): 설치 속도는 부차적 이점
- D (X): 보안 수준은 동일 (mTLS, AuthorizationPolicy 모두 지원)
참고 자료:
문제 2: Multi-cluster Mesh
Istio Multi-cluster Mesh에서 클러스터 간 서비스 검색을 담당하는 것은?
A. Istiod
B. CoreDNS
C. East-West Gateway
D. Service Entry
정답 및 해설
정답: A
Istiod는 멀티 클러스터 환경에서 모든 클러스터의 서비스 정보를 수집하고 배포합니다.
해설:
Multi-cluster Mesh 아키텍처:
Istiod의 역할:
- 서비스 검색 (Service Discovery):
- 모든 클러스터의 Kubernetes Service 수집
- 통합된 서비스 레지스트리 유지
- Envoy에 엔드포인트 정보 배포
- 구성 배포:
- VirtualService, DestinationRule을 모든 클러스터에 배포
- Cross-cluster 라우팅 규칙 관리
- 인증서 관리:
- 모든 클러스터의 mTLS 인증서 발급
- Root CA를 공유하여 신뢰 체인 구축
Multi-cluster 설정 예시:
# Primary 클러스터 설정
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
meshID: mesh1
multiCluster:
clusterName: cluster1
network: network1
---
# Remote 클러스터에서 Primary 접근
apiVersion: v1
kind: Secret
metadata:
name: istio-remote-secret-cluster2
namespace: istio-system
annotations:
networking.istio.io/cluster: cluster2
type: Opaque
data:
kubeconfig: <base64-encoded-kubeconfig>각 옵션 분석:
- A (O): Istiod가 모든 클러스터의 서비스 정보를 수집하고 배포
- B (X): CoreDNS는 클러스터 내부 DNS만 담당
- C (X): East-West Gateway는 트래픽 라우팅만 담당 (서비스 검색 아님)
- D (X): ServiceEntry는 외부 서비스를 수동으로 등록하는 리소스
참고 자료:
문제 3: EnvoyFilter 사용 목적
EnvoyFilter를 사용하는 주요 목적은?
A. Kubernetes Service 생성
B. VirtualService 자동 생성
C. Envoy 프록시 동작 커스터마이징
D. Istiod 구성 변경
정답 및 해설
정답: C
EnvoyFilter는 Envoy 프록시의 동작을 세밀하게 커스터마이징하기 위한 고급 리소스입니다.
해설:
EnvoyFilter 사용 사례:
- 커스텀 헤더 추가:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: add-custom-header
namespace: default
spec:
workloadSelector:
labels:
app: reviews
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_OUTBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
function envoy_on_request(request_handle)
request_handle:headers():add("x-custom-header", "my-value")
end- Wasm 확장 통합:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: wasm-filter
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
config:
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/istio/extensions/auth_filter.wasm"- Rate Limiting 통합:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: rate-limit-filter
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
domain: productpage-ratelimit
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: rate_limit_clusterEnvoyFilter 적용 범위:
spec:
# 전체 메시에 적용
workloadSelector: {}
# 특정 워크로드에만 적용
workloadSelector:
labels:
app: reviews
version: v2
# 특정 네임스페이스에만 적용
# (metadata.namespace로 제어)주의사항:
⚠️ EnvoyFilter는 매우 강력하지만 위험합니다:
- Envoy 내부 구조에 대한 깊은 이해 필요
- Istio 버전 업그레이드 시 호환성 문제 가능
- 잘못된 구성으로 전체 메시 장애 가능
모범 사례:
- 가능하면 VirtualService, DestinationRule 사용
- EnvoyFilter는 최후의 수단으로만 사용
- 테스트 환경에서 충분히 검증
- workloadSelector로 범위 제한
각 옵션 분석:
- A (X): Kubernetes Service 생성은 kubectl로 수행
- B (X): VirtualService는 수동으로 생성
- C (O): Envoy 프록시의 동작을 세밀하게 커스터마이징
- D (X): Istiod 구성은 IstioOperator로 변경
참고 자료:
문제 4: Sidecar Injection
Istio에서 자동 Sidecar 주입을 비활성화하는 방법은?
A. Namespace에서 istio-injection=enabled 레이블 제거
B. Pod에 sidecar.istio.io/inject="false" annotation 추가
C. Istiod 재시작
D. A와 B 모두 가능
정답 및 해설
정답: D
Namespace 레벨과 Pod 레벨 모두에서 Sidecar 주입을 제어할 수 있습니다.
해설:
Sidecar 주입 제어 방법:
1. Namespace 레벨 (A - O):
# Sidecar 주입 활성화
kubectl label namespace default istio-injection=enabled
# Sidecar 주입 비활성화
kubectl label namespace default istio-injection-
# 또는 레이블 변경
kubectl label namespace default istio-injection=disabled --overwrite2. Pod 레벨 (B - O):
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: "false" # Sidecar 주입 비활성화
spec:
containers:
- name: myapp
image: myapp:latestSidecar 주입 우선순위:
Pod annotation > Namespace label > 기본값
예시:
1. Namespace: istio-injection=enabled
Pod: sidecar.istio.io/inject="false"
결과: Sidecar 주입 안됨 (Pod annotation 우선)
2. Namespace: istio-injection=disabled
Pod: sidecar.istio.io/inject="true"
결과: Sidecar 주입됨 (Pod annotation 우선)
3. Namespace: 레이블 없음
Pod: annotation 없음
결과: Sidecar 주입 안됨 (기본값)Sidecar 주입 검증:
# Pod에 Sidecar가 주입되었는지 확인
kubectl get pods <pod-name> -o jsonpath='{.spec.containers[*].name}'
# 출력 예시: myapp istio-proxy (2개 = Sidecar 있음)
# Sidecar 주입 로그 확인
kubectl logs -n istio-system -l app=istiod --tail=100 | grep injection
# Namespace 설정 확인
kubectl get namespace -L istio-injection혼합 환경 예시:
# Namespace 전체에 Sidecar 주입
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
istio-injection: enabled
---
# 특정 Pod만 제외 (예: 레거시 시스템)
apiVersion: apps/v1
kind: Deployment
metadata:
name: legacy-app
namespace: production
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
spec:
containers:
- name: legacy
image: legacy:v1
---
# 대부분의 Pod는 자동으로 Sidecar 주입됨
apiVersion: apps/v1
kind: Deployment
metadata:
name: modern-app
namespace: production
spec:
template:
spec:
containers:
- name: modern
image: modern:v2각 옵션 분석:
- A (O): Namespace 레벨에서 Sidecar 주입 제어 가능
- B (O): Pod 레벨에서 Sidecar 주입 제어 가능
- C (X): Istiod 재시작은 불필요
- D (O): A와 B 모두 유효한 방법
참고 자료:
문제 5: Argo Rollouts 통합
Argo Rollouts와 Istio를 함께 사용할 때 트래픽 분할을 담당하는 것은?
A. Argo Rollouts Controller B. Istio VirtualService C. Kubernetes Service D. Istio Gateway
정답 및 해설
정답: B
Istio VirtualService가 실제 트래픽 분할을 수행하고, Argo Rollouts는 VirtualService의 weight 값을 자동으로 업데이트합니다.
해설:
Argo Rollouts + Istio 통합 아키텍처:
VirtualService 역할:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- name: primary # Argo Rollouts가 참조하는 route 이름
route:
- destination:
host: reviews
subset: stable
weight: 100 # Argo Rollouts가 자동으로 변경
- destination:
host: reviews
subset: canary
weight: 0 # Argo Rollouts가 자동으로 변경Argo Rollouts 설정:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: reviews
spec:
strategy:
canary:
# Istio 통합 설정
trafficRouting:
istio:
virtualService:
name: reviews # VirtualService 이름
routes:
- primary # route 이름
destinationRule:
name: reviews # DestinationRule 이름
canarySubsetName: canary
stableSubsetName: stable
# Canary 단계
steps:
- setWeight: 10 # VirtualService weight를 10으로 변경
- pause: {duration: 2m}
- setWeight: 25 # VirtualService weight를 25로 변경
- pause: {duration: 2m}
- setWeight: 50
- pause: {duration: 2m}배포 프로세스:
1. Argo Rollouts가 새 버전 (v2) Pod 생성
↓
2. Argo Rollouts가 VirtualService의 canary weight를 10으로 설정
↓
3. Istio Envoy가 실제 10% 트래픽을 v2로 라우팅
↓
4. AnalysisTemplate이 메트릭 확인 (에러율, 지연시간)
↓
5. 성공 시 Argo Rollouts가 weight를 25로 증가
↓
6. 반복...
↓
7. 최종적으로 weight 100 (완전 전환)책임 분담:
| 컴포넌트 | 역할 |
|---|---|
| Argo Rollouts | - Pod 생성/삭제 |
| Istio VirtualService | - 실제 트래픽 분할 |
| Envoy Proxy | - 트래픽 라우팅 실행 |
| Prometheus | - 메트릭 저장 |
실제 트래픽 흐름:
# 사용자 요청 100개
100개 요청 → Istio Gateway
↓
VirtualService
(weight: stable=90, canary=10)
↓
┌────┴────┐
↓ ↓
90개 10개
Stable v1 Canary v2각 옵션 분석:
- A (X): Argo Rollouts는 VirtualService를 업데이트만 함 (직접 트래픽 분할 안함)
- B (O): VirtualService가 실제 트래픽 분할 수행
- C (X): Kubernetes Service는 로드 밸런싱만 담당 (트래픽 분할 안함)
- D (X): Gateway는 외부 트래픽 진입점 (트래픽 분할 안함)
참고 자료:
주관식 문제 (6-10번)
문제 6: Ambient Mode 비용 절감 분석
AWS EKS 클러스터에서 Sidecar Mode에서 Ambient Mode로 전환할 때의 비용 절감 효과를 계산하세요. (가정: 500개 Pod, 5개 노드, r5.xlarge 인스턴스, 월 730시간 운영)
예시 답안
답변:
비용 절감 분석:
1. 가정 조건
클러스터 규모:
- Pod 수: 500개
- 노드 수: 5개
- 인스턴스 타입: r5.xlarge (4 vCPU, 32GB RAM)
- 인스턴스 비용: $0.252/시간
- 운영 시간: 월 730시간
리소스 사용량:
- Sidecar 메모리: 50MB/Pod
- Sidecar CPU: 0.1 vCPU/Pod
- ztunnel 메모리: 50MB/Node
- ztunnel CPU: 0.1 vCPU/Node
- waypoint 메모리: 200MB
- waypoint CPU: 0.5 vCPU2. Sidecar Mode 리소스 계산
메모리 사용량:
= 500 Pod × 50MB
= 25,000MB
= 25GB
CPU 사용량:
= 500 Pod × 0.1 vCPU
= 50 vCPU필요 인스턴스 수 (r5.xlarge: 4 vCPU, 32GB RAM):
CPU 기준:
= 50 vCPU ÷ 4 vCPU/인스턴스
= 12.5 인스턴스
≈ 13 인스턴스 필요
메모리 기준:
= 25GB ÷ 32GB/인스턴스
= 0.78 인스턴스
≈ 1 인스턴스 필요
실제 필요: max(13, 1) = 13 인스턴스Sidecar Mode 월간 비용:
= 13 인스턴스 × $0.252/시간 × 730시간
= $2,395.56/월3. Ambient Mode 리소스 계산
메모리 사용량:
= (5 노드 × 50MB) + 200MB
= 250MB + 200MB
= 450MB
CPU 사용량:
= (5 노드 × 0.1 vCPU) + 0.5 vCPU
= 0.5 vCPU + 0.5 vCPU
= 1.0 vCPU필요 인스턴스 수:
CPU 기준:
= 1.0 vCPU ÷ 4 vCPU/인스턴스
= 0.25 인스턴스
≈ 1 인스턴스 필요
메모리 기준:
= 0.45GB ÷ 32GB/인스턴스
= 0.01 인스턴스
≈ 1 인스턴스 필요
실제 필요: max(1, 1) = 1 인스턴스Ambient Mode 월간 비용:
= 1 인스턴스 × $0.252/시간 × 730시간
= $183.96/월4. 비용 절감 효과
월간 절감액:
= $2,395.56 - $183.96
= $2,211.60/월
절감률:
= ($2,211.60 ÷ $2,395.56) × 100
= 92.3%
연간 절감액:
= $2,211.60 × 12
= $26,539.20/년5. 리소스 절감 요약
| 항목 | Sidecar Mode | Ambient Mode | 절감 |
|---|---|---|---|
| 메모리 | 25GB | 0.45GB | 24.55GB (98.2%) |
| CPU | 50 vCPU | 1.0 vCPU | 49 vCPU (98.0%) |
| 인스턴스 | 13대 | 1대 | 12대 (92.3%) |
| 월간 비용 | $2,395.56 | $183.96 | $2,211.60 (92.3%) |
| 연간 비용 | $28,746.72 | $2,207.52 | $26,539.20 (92.3%) |
6. 추가 비용 절감 요인
네트워크 비용:
- Sidecar Mode: localhost 통신 없음 (모든 트래픽이 네트워크 통과)
- Ambient Mode: ztunnel 간 직접 통신으로 효율 향상
운영 비용:
- Pod 재시작 불필요 (배포 시간 단축)
- Sidecar 주입 오류 없음
- 관리 복잡도 감소
성능 향상:
- 메모리 압박 감소로 Pod 성능 향상
- OOMKilled 빈도 감소
- 노드 자원 여유 확보
7. ROI (Return on Investment)
Ambient Mode 전환 비용 (1회):
- 학습 시간: 40시간 × $100/시간 = $4,000
- 테스트 및 검증: 20시간 × $100/시간 = $2,000
- 총 전환 비용: $6,000
투자 회수 기간:
= $6,000 ÷ $2,211.60/월
= 2.7개월
3년 총 절감액:
= ($26,539.20 × 3) - $6,000
= $73,617.608. 실전 고려사항
장점:
- ✅ 92% 이상 비용 절감
- ✅ 운영 간소화
- ✅ 배포 속도 향상
- ✅ 리소스 효율 극대화
주의사항:
- ⚠️ Istio 1.28+ 베타 기능
- ⚠️ L7 기능 필요 시 waypoint 추가 배포
- ⚠️ 일부 고급 기능은 Sidecar 모드 필요
- ⚠️ 충분한 테스트 필요
참고 자료:
문제 7: Multi-cluster Service Mesh 구성
2개의 EKS 클러스터(us-east-1, us-west-2)를 하나의 Istio Mesh로 통합하는 방법을 설명하세요. Primary-Remote 모델을 사용하고, 클러스터 간 서비스 호출 예시를 포함해야 합니다.
예시 답안
답변:
Multi-cluster Istio Mesh 구성:
1. 아키텍처 개요
2. 사전 준비
# 두 클러스터에 접근 가능한 kubeconfig 설정
export CTX_CLUSTER1=eks-us-east-1
export CTX_CLUSTER2=eks-us-west-2
# 컨텍스트 확인
kubectl config get-contexts
# CA 인증서 생성 (공유 Root CA)
mkdir -p certs
cd certs
# Root CA 생성
make -f ../istio-1.28.0/tools/certs/Makefile.selfsigned.mk root-ca
# 각 클러스터용 중간 인증서 생성
make -f ../istio-1.28.0/tools/certs/Makefile.selfsigned.mk cluster1-cacerts
make -f ../istio-1.28.0/tools/certs/Makefile.selfsigned.mk cluster2-cacerts3. 클러스터 1 (Primary) 설정
# CA 인증서 Secret 생성
kubectl create namespace istio-system --context="${CTX_CLUSTER1}"
kubectl create secret generic cacerts -n istio-system \
--from-file=cluster1/ca-cert.pem \
--from-file=cluster1/ca-key.pem \
--from-file=cluster1/root-cert.pem \
--from-file=cluster1/cert-chain.pem \
--context="${CTX_CLUSTER1}"
# Primary Istio 설치
istioctl install --context="${CTX_CLUSTER1}" -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
meshID: mesh1
multiCluster:
clusterName: cluster1
network: network1
components:
ingressGateways:
- name: istio-eastwestgateway
label:
istio: eastwestgateway
app: istio-eastwestgateway
topology.istio.io/network: network1
enabled: true
k8s:
env:
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
value: network1
service:
type: LoadBalancer
ports:
- name: status-port
port: 15021
targetPort: 15021
- name: tls
port: 15443
targetPort: 15443
- name: tls-istiod
port: 15012
targetPort: 15012
- name: tls-webhook
port: 15017
targetPort: 15017
EOF
# East-West Gateway 노출
kubectl apply --context="${CTX_CLUSTER1}" -n istio-system -f \
samples/multicluster/expose-services.yaml4. 클러스터 2 (Remote) 설정
# CA 인증서 Secret 생성
kubectl create namespace istio-system --context="${CTX_CLUSTER2}"
kubectl create secret generic cacerts -n istio-system \
--from-file=cluster2/ca-cert.pem \
--from-file=cluster2/ca-key.pem \
--from-file=cluster2/root-cert.pem \
--from-file=cluster2/cert-chain.pem \
--context="${CTX_CLUSTER2}"
# Remote Secret 생성 (cluster1에서 cluster2 접근)
istioctl create-remote-secret \
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
# Remote Istio 설치
istioctl install --context="${CTX_CLUSTER2}" -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
meshID: mesh1
multiCluster:
clusterName: cluster2
network: network2
remotePilotAddress: <CLUSTER1_EAST_WEST_GATEWAY_IP>
components:
ingressGateways:
- name: istio-eastwestgateway
label:
istio: eastwestgateway
app: istio-eastwestgateway
topology.istio.io/network: network2
enabled: true
k8s:
env:
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
value: network2
service:
type: LoadBalancer
ports:
- name: status-port
port: 15021
- name: tls
port: 15443
- name: tls-istiod
port: 15012
- name: tls-webhook
port: 15017
EOF5. 서비스 배포 및 검증
클러스터 1에 Service A 배포:
# cluster1: service-a.yaml
apiVersion: v1
kind: Service
metadata:
name: service-a
labels:
app: service-a
spec:
ports:
- port: 8080
name: http
selector:
app: service-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-a
spec:
replicas: 2
selector:
matchLabels:
app: service-a
template:
metadata:
labels:
app: service-a
spec:
containers:
- name: service-a
image: nginx:latest
ports:
- containerPort: 8080kubectl apply --context="${CTX_CLUSTER1}" -f service-a.yaml클러스터 2에 Service B 배포:
# cluster2: service-b.yaml
apiVersion: v1
kind: Service
metadata:
name: service-b
labels:
app: service-b
spec:
ports:
- port: 8080
name: http
selector:
app: service-b
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-b
spec:
replicas: 2
selector:
matchLabels:
app: service-b
template:
metadata:
labels:
app: service-b
spec:
containers:
- name: service-b
image: nginx:latest
ports:
- containerPort: 8080kubectl apply --context="${CTX_CLUSTER2}" -f service-b.yaml6. Cross-cluster 서비스 호출 테스트
# 클러스터 1에서 클러스터 2의 서비스 호출
kubectl exec --context="${CTX_CLUSTER1}" -it \
$(kubectl get pod --context="${CTX_CLUSTER1}" -l app=service-a -o jsonpath='{.items[0].metadata.name}') \
-- curl http://service-b.default.svc.cluster.local:8080
# 클러스터 2에서 클러스터 1의 서비스 호출
kubectl exec --context="${CTX_CLUSTER2}" -it \
$(kubectl get pod --context="${CTX_CLUSTER2}" -l app=service-b -o jsonpath='{.items[0].metadata.name}') \
-- curl http://service-a.default.svc.cluster.local:80807. 서비스 검색 확인
# 클러스터 1에서 Envoy 구성 확인
istioctl --context="${CTX_CLUSTER1}" proxy-config endpoints \
$(kubectl get pod --context="${CTX_CLUSTER1}" -l app=service-a -o jsonpath='{.items[0].metadata.name}') | \
grep service-b
# 출력 예시:
# service-b.default.svc.cluster.local:8080 HEALTHY <cluster2-pod-ip>:80808. 트래픽 정책 적용
# Cross-cluster 트래픽 라우팅
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: service-b
spec:
hosts:
- service-b.default.svc.cluster.local
http:
- match:
- sourceLabels:
app: service-a
route:
- destination:
host: service-b.default.svc.cluster.local
port:
number: 8080
weight: 80 # 80%는 로컬 클러스터
- destination:
host: service-b.default.svc.cluster.local
port:
number: 8080
weight: 20 # 20%는 원격 클러스터
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: service-b
spec:
host: service-b.default.svc.cluster.local
trafficPolicy:
loadBalancer:
localityLbSetting:
enabled: true # Locality-aware 라우팅9. 모니터링 및 검증
# Prometheus에서 Cross-cluster 트래픽 확인
kubectl port-forward --context="${CTX_CLUSTER1}" -n istio-system \
svc/prometheus 9090:9090
# Prometheus 쿼리:
# sum(rate(istio_requests_total{source_cluster="cluster1", destination_cluster="cluster2"}[5m]))
# Kiali로 시각화
istioctl dashboard kiali --context="${CTX_CLUSTER1}"10. 주의사항 및 모범 사례
주의사항:
- ⚠️ 공유 Root CA 필수
- ⚠️ 네트워크 레이턴시 고려
- ⚠️ East-West Gateway 보안 강화
- ⚠️ DNS 해석 올바르게 설정
모범 사례:
- ✅ Locality-aware 라우팅 활성화
- ✅ Circuit Breaker 설정
- ✅ 클러스터별 replica 유지
- ✅ Cross-cluster 트래픽 모니터링
참고 자료:
문제 8: EnvoyFilter로 커스텀 Rate Limiting
EnvoyFilter를 사용하여 특정 경로(/api/premium/*)에만 사용자별 Rate Limiting(분당 100 요청)을 적용하는 방법을 구현하세요.
예시 답안
답변:
EnvoyFilter 기반 Rate Limiting 구현:
1. 아키텍처 개요
2. Redis Rate Limit 서버 배포
# redis-ratelimit.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-ratelimit
namespace: istio-system
spec:
ports:
- port: 6379
name: redis
selector:
app: redis-ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-ratelimit
namespace: istio-system
spec:
replicas: 1
selector:
matchLabels:
app: redis-ratelimit
template:
metadata:
labels:
app: redis-ratelimit
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
---
# Envoy Rate Limit 서비스
apiVersion: v1
kind: ConfigMap
metadata:
name: ratelimit-config
namespace: istio-system
data:
config.yaml: |
domain: premium-ratelimit
descriptors:
# 사용자별 Rate Limit: 분당 100 요청
- key: user_id
rate_limit:
unit: minute
requests_per_unit: 100
---
apiVersion: v1
kind: Service
metadata:
name: ratelimit
namespace: istio-system
spec:
ports:
- port: 8081
name: http
- port: 9091
name: grpc
selector:
app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratelimit
namespace: istio-system
spec:
replicas: 2
selector:
matchLabels:
app: ratelimit
template:
metadata:
labels:
app: ratelimit
spec:
containers:
- name: ratelimit
image: envoyproxy/ratelimit:master
ports:
- containerPort: 8081
- containerPort: 9091
env:
- name: REDIS_URL
value: redis-ratelimit.istio-system.svc.cluster.local:6379
- name: USE_STATSD
value: "false"
- name: LOG_LEVEL
value: debug
- name: RUNTIME_ROOT
value: /data
- name: RUNTIME_SUBDIRECTORY
value: ratelimit
volumeMounts:
- name: config-volume
mountPath: /data/ratelimit/config
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: config-volume
configMap:
name: ratelimit-configkubectl apply -f redis-ratelimit.yaml3. EnvoyFilter 구성
# envoyfilter-ratelimit.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: premium-ratelimit
namespace: istio-system
spec:
workloadSelector:
labels:
app: api-gateway
configPatches:
# HTTP 필터 체인에 Rate Limit 필터 추가
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
domain: premium-ratelimit
failure_mode_deny: true # Rate Limit 서버 장애 시 거부
enable_x_ratelimit_headers: DRAFT_VERSION_03
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: rate_limit_cluster
transport_api_version: V3
# Rate Limit 클러스터 정의
- applyTo: CLUSTER
patch:
operation: ADD
value:
name: rate_limit_cluster
type: STRICT_DNS
connect_timeout: 1s
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
cluster_name: rate_limit_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: ratelimit.istio-system.svc.cluster.local
port_value: 9091
# HTTP 라우트에 Rate Limit 액션 추가
- applyTo: HTTP_ROUTE
match:
context: SIDECAR_INBOUND
routeConfiguration:
vhost:
route:
action: ANY
patch:
operation: MERGE
value:
route:
rate_limits:
# /api/premium/* 경로만 Rate Limit 적용
- actions:
- header_value_match:
descriptor_value: "premium"
headers:
- name: ":path"
prefix_match: "/api/premium/"
- request_headers:
header_name: "x-user-id"
descriptor_key: "user_id"kubectl apply -f envoyfilter-ratelimit.yaml4. VirtualService 구성
# virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: api-service
spec:
hosts:
- api.example.com
gateways:
- api-gateway
http:
# Premium API 경로
- match:
- uri:
prefix: /api/premium/
route:
- destination:
host: premium-backend
port:
number: 8080
# 일반 API 경로 (Rate Limit 없음)
- match:
- uri:
prefix: /api/
route:
- destination:
host: backend
port:
number: 80805. 테스트 애플리케이션
# backend.yaml
apiVersion: v1
kind: Service
metadata:
name: premium-backend
spec:
ports:
- port: 8080
name: http
selector:
app: premium-backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: premium-backend
spec:
replicas: 2
selector:
matchLabels:
app: premium-backend
template:
metadata:
labels:
app: premium-backend
app: api-gateway # EnvoyFilter 적용 대상
spec:
containers:
- name: backend
image: nginx:latest
ports:
- containerPort: 8080kubectl apply -f backend.yaml6. 테스트
# 정상 요청 (사용자별 100 요청/분 이하)
for i in {1..50}; do
curl -H "x-user-id: user123" \
-H "Host: api.example.com" \
http://<INGRESS_GATEWAY>/api/premium/data
sleep 0.1
done
# 출력: 200 OK (모두 성공)
# Rate Limit 초과 (100 요청/분 초과)
for i in {1..150}; do
curl -H "x-user-id: user123" \
-H "Host: api.example.com" \
http://<INGRESS_GATEWAY>/api/premium/data
done
# 출력:
# 1-100번: 200 OK
# 101-150번: 429 Too Many Requests
# 다른 사용자는 영향 없음
curl -H "x-user-id: user456" \
-H "Host: api.example.com" \
http://<INGRESS_GATEWAY>/api/premium/data
# 출력: 200 OK7. Rate Limit 헤더 확인
curl -I -H "x-user-id: user123" \
-H "Host: api.example.com" \
http://<INGRESS_GATEWAY>/api/premium/data
# 출력:
# X-RateLimit-Limit: 100
# X-RateLimit-Remaining: 73
# X-RateLimit-Reset: 17356896008. Redis 모니터링
# Redis에 저장된 Rate Limit 데이터 확인
kubectl exec -it -n istio-system \
$(kubectl get pod -n istio-system -l app=redis-ratelimit -o jsonpath='{.items[0].metadata.name}') \
-- redis-cli
# Redis CLI에서:
KEYS *
# 출력: "premium-ratelimit_user123_..."
GET "premium-ratelimit_user123_..."
# 출력: "27" (남은 요청 수)
TTL "premium-ratelimit_user123_..."
# 출력: "42" (초 단위 TTL)9. Prometheus 메트릭
# Rate Limit 거부된 요청 수
sum(rate(envoy_http_ratelimit_rejected_total[5m])) by (pod)
# Rate Limit 허용된 요청 수
sum(rate(envoy_http_ratelimit_ok_total[5m])) by (pod)
# Rate Limit 서버 오류
sum(rate(envoy_http_ratelimit_error_total[5m])) by (pod)10. 주의사항 및 모범 사례
주의사항:
- ⚠️ Redis 고가용성 구성 필요 (프로덕션)
- ⚠️ Rate Limit 서버 장애 시 동작 정의 (
failure_mode_deny) - ⚠️ 사용자 식별 헤더 (
x-user-id) 신뢰성 확보 - ⚠️ EnvoyFilter는 Istio 버전 업그레이드 시 호환성 확인 필요
모범 사례:
- ✅ Redis Sentinel 또는 Cluster 사용
- ✅ Rate Limit 서버 replica ≥ 2
- ✅ 적절한 모니터링 및 알림
- ✅ 사용자별 예외 처리 (VIP 사용자 등)
참고 자료:
문제 9: Argo Rollouts Blue/Green 배포
Argo Rollouts와 Istio를 사용하여 Blue/Green 배포를 구현하세요. 자동 분석(AnalysisTemplate)을 포함하고, 실패 시 자동 롤백되도록 구성해야 합니다.
예시 답안
답변:
Argo Rollouts Blue/Green 배포 구현:
1. Blue/Green 배포 개념
2. Kubernetes Service 생성
# services.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-active
spec:
ports:
- port: 8080
name: http
selector:
app: myapp
# Argo Rollouts가 자동으로 selector 관리
---
apiVersion: v1
kind: Service
metadata:
name: myapp-preview
spec:
ports:
- port: 8080
name: http
selector:
app: myapp
# Argo Rollouts가 자동으로 selector 관리kubectl apply -f services.yaml3. Istio Gateway 및 VirtualService
# gateway.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: myapp-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- myapp.example.com
---
# virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.example.com
gateways:
- myapp-gateway
http:
# 프로덕션 트래픽 (Active)
- match:
- uri:
prefix: /
route:
- destination:
host: myapp-active
port:
number: 8080
---
# preview-virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-preview
spec:
hosts:
- myapp-preview.example.com
gateways:
- myapp-gateway
http:
# 미리보기 트래픽 (Preview)
- match:
- uri:
prefix: /
route:
- destination:
host: myapp-preview
port:
number: 8080kubectl apply -f gateway.yaml4. AnalysisTemplate 정의
# analysis-template.yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
# 메트릭 1: 성공률 (95% 이상)
- name: success-rate
interval: 30s
count: 5
successCondition: result >= 0.95
failureLimit: 2
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}",
response_code!~"5.*"
}[2m]
))
/
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}"
}[2m]
))
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: latency
spec:
args:
- name: service-name
metrics:
# 메트릭 2: P95 지연시간 (500ms 이하)
- name: latency-p95
interval: 30s
count: 5
successCondition: result <= 500
failureLimit: 2
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
histogram_quantile(0.95,
sum(rate(
istio_request_duration_milliseconds_bucket{
destination_service_name="{{args.service-name}}"
}[2m]
)) by (le)
)
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: error-rate
spec:
args:
- name: service-name
metrics:
# 메트릭 3: 에러율 (1% 이하)
- name: error-rate
interval: 30s
count: 5
successCondition: result <= 0.01
failureLimit: 2
provider:
prometheus:
address: http://prometheus.istio-system:9090
query: |
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}",
response_code=~"5.*"
}[2m]
))
/
sum(rate(
istio_requests_total{
destination_service_name="{{args.service-name}}"
}[2m]
))kubectl apply -f analysis-template.yaml5. Rollout 리소스 정의
# rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
spec:
replicas: 5
revisionHistoryLimit: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
# Blue/Green 배포 전략
strategy:
blueGreen:
# Active Service (프로덕션)
activeService: myapp-active
# Preview Service (테스트)
previewService: myapp-preview
# 자동 승격 비활성화 (수동 승격 또는 Analysis 기반)
autoPromotionEnabled: false
# Green 배포 후 대기 시간
scaleDownDelaySeconds: 30
# 배포 전 분석 (Green 환경 검증)
prePromotionAnalysis:
templates:
- templateName: success-rate
- templateName: latency
- templateName: error-rate
args:
- name: service-name
value: myapp-preview
# 승격 후 분석 (Active 전환 후 검증)
postPromotionAnalysis:
templates:
- templateName: success-rate
- templateName: latency
- templateName: error-rate
args:
- name: service-name
value: myapp-activekubectl apply -f rollout.yaml6. 새 버전 배포
# 새 버전 이미지로 업데이트
kubectl argo rollouts set image myapp \
myapp=myapp:v2
# 배포 상태 모니터링
kubectl argo rollouts get rollout myapp --watch
# 출력:
# Name: myapp
# Namespace: default
# Status: ॥ Paused
# Strategy: BlueGreen
# Images: myapp:v1 (stable, active)
# myapp:v2 (preview)
# Replicas:
# Desired: 5
# Current: 10
# Updated: 5
# Ready: 5
# Available: 5
# Analysis: Running7. 배포 프로세스
1. 새 버전 (Green) Pod 5개 생성
↓
2. Preview Service가 Green을 가리킴
↓
3. prePromotionAnalysis 시작 (2.5분)
- success-rate 측정 (5회 × 30초)
- latency-p95 측정 (5회 × 30초)
- error-rate 측정 (5회 × 30초)
↓
4. 분석 결과 확인
├─ 성공 → 5단계 진행
└─ 실패 → 자동 롤백 (Green Pod 삭제)
↓
5. 수동 승격 또는 자동 승격
kubectl argo rollouts promote myapp
↓
6. Active Service가 Green을 가리킴
Preview Service가 Blue를 가리킴
↓
7. postPromotionAnalysis 시작 (2.5분)
- 프로덕션 트래픽으로 Green 검증
↓
8. 분석 결과 확인
├─ 성공 → Blue Pod 삭제 (30초 후)
└─ 실패 → 즉시 롤백 (Active를 Blue로 복구)8. 수동 승격
# Green 환경 미리보기 (Preview Service)
curl http://myapp-preview.example.com
# 문제 없으면 승격
kubectl argo rollouts promote myapp
# 승격 후 Active Service로 트래픽 전환됨
curl http://myapp.example.com9. 자동 롤백 시나리오
시나리오 1: prePromotionAnalysis 실패
# Green 환경에서 에러율이 1% 초과
# Analysis 로그:
# error-rate: FAILED (0.03 > 0.01)
# failureLimit: 2/2
# 자동 롤백 실행
# Green Pod 삭제
# Blue가 계속 Active 유지
kubectl argo rollouts get rollout myapp
# Status: Degraded
# Message: PrePromotionAnalysis Failed시나리오 2: postPromotionAnalysis 실패
# Active 전환 후 성공률이 95% 미만
# Analysis 로그:
# success-rate: FAILED (0.92 < 0.95)
# failureLimit: 2/2
# 자동 롤백 실행
# Active Service를 즉시 Blue로 복구
# Green은 Preview로 이동
kubectl argo rollouts get rollout myapp
# Status: Degraded
# Message: PostPromotionAnalysis Failed10. 모니터링 및 대시보드
# Argo Rollouts 대시보드
kubectl argo rollouts dashboard
# Kiali에서 트래픽 시각화
istioctl dashboard kiali
# Grafana에서 메트릭 확인
kubectl port-forward -n istio-system svc/grafana 3000:3000Prometheus 쿼리:
# 배포 진행 상태
argo_rollouts_info{name="myapp"}
# Analysis 결과
argo_rollouts_analysis_run_metric_phase{name="myapp", metric="success-rate"}
# 활성 버전별 트래픽
sum(rate(istio_requests_total{destination_service_name="myapp"}[5m])) by (destination_version)11. 모범 사례
장점:
- ✅ 즉시 롤백 가능 (스위치 전환)
- ✅ 프로덕션 영향 최소화
- ✅ 충분한 테스트 시간 확보
- ✅ 자동 분석 및 롤백
주의사항:
- ⚠️ 2배 리소스 필요 (Blue + Green)
- ⚠️ 데이터베이스 스키마 호환성 확인
- ⚠️ 세션 관리 (Sticky Session 필요 시)
참고 자료:
문제 10: DNS Caching 성능 최적화
Istio에서 DNS Caching을 활성화하여 외부 서비스 호출 성능을 개선하는 방법을 설명하세요. 벤치마크 결과를 포함해야 합니다.
예시 답안
답변:
Istio DNS Caching 구현 및 성능 측정:
1. DNS Caching 필요성
문제: DNS 조회 오버헤드
외부 API 호출 시마다 DNS 조회 발생:
1. 애플리케이션 → Envoy: HTTP 요청
2. Envoy → CoreDNS: DNS 조회 (50-100ms)
3. CoreDNS → 응답: IP 주소
4. Envoy → 외부 API: HTTP 요청 (100-200ms)
총 지연시간: 150-300ms해결: DNS Caching 활성화
DNS Caching 후:
1. 애플리케이션 → Envoy: HTTP 요청
2. Envoy: 캐시된 IP 사용 (0ms)
3. Envoy → 외부 API: HTTP 요청 (100-200ms)
총 지연시간: 100-200ms (33-50% 개선)2. ServiceEntry로 외부 서비스 등록
# external-api-serviceentry.yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-api
spec:
hosts:
- api.github.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS # DNS 해석 사용kubectl apply -f external-api-serviceentry.yaml3. DestinationRule로 DNS Caching 활성화
# destinationrule-dns-cache.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: external-api
spec:
host: api.github.com
trafficPolicy:
# DNS 리프레시 간격: 5분
# (TTL이 0이어도 5분마다 DNS 재조회)
dnsRefreshRate: 5m
# Connection Pool 설정
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
http2MaxRequests: 100
maxRequestsPerConnection: 10
# Outlier Detection
outlierDetection:
consecutiveErrors: 5
interval: 30s
baseEjectionTime: 30skubectl apply -f destinationrule-dns-cache.yaml4. EnvoyFilter로 고급 DNS 설정
# envoyfilter-dns-cache.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: dns-cache-filter
namespace: istio-system
spec:
configPatches:
# DNS 캐시 필터 추가
- applyTo: NETWORK_FILTER
match:
context: SIDECAR_OUTBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.tcp_proxy"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.network.dns_cache
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.dns_cache.v3.DnsCacheConfig
dns_cache_config:
name: dynamic_forward_proxy_cache_config
dns_lookup_family: V4_ONLY
# DNS 캐시 TTL: 5분
dns_cache_ttl: 300s
# 최대 캐시 항목 수
max_hosts: 1024
# DNS 조회 타임아웃
dns_query_timeout: 5s
# Cluster에 DNS 캐시 적용
- applyTo: CLUSTER
match:
context: SIDECAR_OUTBOUND
cluster:
service: "*.external"
patch:
operation: MERGE
value:
dns_lookup_family: V4_ONLY
# Strict DNS 사용 (DNS 캐싱 활성화)
type: STRICT_DNS
# DNS 리프레시 간격
dns_refresh_rate: 300s
# 연결 재사용
upstream_connection_options:
tcp_keepalive:
keepalive_time: 60kubectl apply -f envoyfilter-dns-cache.yaml5. 테스트 애플리케이션 배포
# test-app.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-app
labels:
app: test-app
spec:
containers:
- name: test
image: curlimages/curl:latest
command: ["/bin/sh"]
args: ["-c", "sleep 3600"]kubectl apply -f test-app.yaml6. 성능 벤치마크
DNS Caching 비활성화 (Before):
# 100회 연속 호출 테스트
kubectl exec -it test-app -- sh -c '
for i in $(seq 1 100); do
time curl -s -o /dev/null -w "%{time_total}\n" https://api.github.com/users/octocat
done' | awk '{sum+=$1; count++} END {print "평균 응답 시간:", sum/count, "초"}'
# 출력:
# 평균 응답 시간: 0.287 초DNS Caching 활성화 (After):
# DestinationRule 적용 후 동일 테스트
kubectl exec -it test-app -- sh -c '
for i in $(seq 1 100); do
time curl -s -o /dev/null -w "%{time_total}\n" https://api.github.com/users/octocat
done' | awk '{sum+=$1; count++} END {print "평균 응답 시간:", sum/count, "초"}'
# 출력:
# 평균 응답 시간: 0.152 초성능 개선:
개선 전: 287ms
개선 후: 152ms
개선율: (287 - 152) / 287 = 47%
DNS 조회 시간: ~135ms 절감7. Envoy 통계 확인
# Envoy DNS 캐시 통계
kubectl exec -it test-app -c istio-proxy -- \
curl localhost:15000/stats | grep dns_cache
# 출력:
# cluster.outbound|443||api.github.com.dns_cache_hits: 99
# cluster.outbound|443||api.github.com.dns_cache_misses: 1
# cluster.outbound|443||api.github.com.dns_refresh: 0
# 캐시 히트율: 99 / (99 + 1) = 99%8. 상세 벤치마크 결과
테스트 환경:
- 클러스터: AWS EKS 1.34
- Istio: 1.28.0
- 노드: r5.xlarge
- 위치: us-east-1
- 외부 API: api.github.com
벤치마크 도구: Apache Bench
# DNS Caching 비활성화
kubectl exec -it test-app -- ab -n 1000 -c 10 \
https://api.github.com/users/octocat
# 결과:
# Requests per second: 12.34 [#/sec]
# Time per request: 81.07 [ms] (mean)
# Time per request: 810.70 [ms] (mean, across all concurrent requests)
# DNS Caching 활성화
kubectl exec -it test-app -- ab -n 1000 -c 10 \
https://api.github.com/users/octocat
# 결과:
# Requests per second: 23.15 [#/sec]
# Time per request: 43.19 [ms] (mean)
# Time per request: 431.90 [ms] (mean, across all concurrent requests)
# 처리량 개선: 23.15 / 12.34 = 1.88배 (88% 향상)9. 비교표
| 항목 | DNS Caching 비활성화 | DNS Caching 활성화 | 개선 |
|---|---|---|---|
| 평균 응답 시간 | 287ms | 152ms | 47% ↓ |
| P95 응답 시간 | 350ms | 180ms | 49% ↓ |
| P99 응답 시간 | 420ms | 210ms | 50% ↓ |
| 처리량 (RPS) | 12.34 | 23.15 | 88% ↑ |
| DNS 캐시 히트율 | 0% | 99% | - |
| 연결 재사용률 | 0% | 95% | - |
10. Prometheus 모니터링
# DNS 캐시 히트율
sum(rate(envoy_dns_cache_dns_query_success[5m]))
/
(
sum(rate(envoy_dns_cache_dns_query_success[5m])) +
sum(rate(envoy_dns_cache_dns_query_failure[5m]))
)
# 외부 API 지연시간 (P95)
histogram_quantile(0.95,
sum(rate(
istio_request_duration_milliseconds_bucket{
destination_service_name="api.github.com"
}[5m]
)) by (le)
)
# 연결 재사용률
rate(envoy_cluster_upstream_cx_active[5m])
/
rate(envoy_cluster_upstream_cx_total[5m])11. 모범 사례
권장 설정:
- ✅ DNS 리프레시 간격: 5-15분 (외부 서비스 TTL 고려)
- ✅ Connection Pool 활성화 (연결 재사용)
- ✅ HTTP/2 사용 (멀티플렉싱)
- ✅ Keep-Alive 활성화
주의사항:
- ⚠️ TTL이 짧은 서비스는 리프레시 간격 줄이기
- ⚠️ DNS 변경 시 캐시 무효화 시간 고려
- ⚠️ 장애 조치 시나리오 테스트
참고 자료:
점수 계산
- 객관식 1-5번: 각 10점 (총 50점)
- 주관식 6-10번: 각 10점 (총 50점)
- 총점: 100점
평가 기준:
- 90-100점: 우수 (Istio 고급 기능 전문가)
- 80-89점: 양호 (고급 기능 활용 가능)
- 70-79점: 보통 (추가 학습 권장)
- 60-69점: 미흡 (기본 개념 복습 필요)
- 0-59점: 재학습 필요