Istio - 스케일링, 데이터 플레인 확장

Kevin·2025년 5월 24일
post-thumbnail

들어가며: 엔터프라이즈급 서비스 메시의 현실

이번 7주차에서는 Istio의 진짜 어려운 부분을 다뤄보았습니다. 지금까지 학습한 Istio 기본기들이 모두 준비운동이었다면, 이제부터는 실제 기업 환경에서 Istio를 대규모로 운영하고 비즈니스 요구사항에 맞게 커스터마이징하는 본격적인 도전에 나섰습니다.

학습하면서 깨달은 점은 조직 규모의 스케일링 능력과 특수한 요구사항을 충족하는 확장성이 서비스 메시 도입의 성패를 좌우한다는 것이었습니다.

현장 경험: 한 글로벌 전자상거래 기업에서는 초기에 단일 클러스터로 Istio를 운영했습니다. 하지만 서비스 규모가 커지고 글로벌 확장이 필요해지자 다중 클러스터 구성으로 전환해야 했습니다. 이 과정에서 마주친 네트워킹, 보안, 운영의 복잡성은 상상을 초월했죠.

이번 7주차에서 학습한 두 가지 핵심 주제는 다음과 같습니다:

12장 - 조직 내에서 이스티오 스케일링하기: 다중 클러스터 서비스 메시를 통해 글로벌 규모의 서비스를 안전하고 효율적으로 운영하는 방법을 실습해보았습니다.

14장 - 이스티오의 요청 처리 기능 확장하기: Envoy 필터와 WebAssembly를 활용하여 특별한 비즈니스 요구사항을 충족하는 고급 커스터마이징 기법을 배워보았습니다.

이번 학습을 통해 얻은 것들:

  • 🌍 글로벌 스케일링: 여러 리전, 여러 클라우드에 걸친 서비스 메시 구축 방법
  • 🔧 고급 커스터마이징: 표준 Istio 기능으로는 불가능한 특별한 요구사항을 해결하는 방법
  • 🛡️ 엔터프라이즈 운영: 실제 기업 환경에서 안정적으로 서비스 메시를 운영하는 노하우


📘 12장: 조직 내에서 이스티오 스케일링하기 - 다중 클러스터 마스터리

12.1 다중 클러스터 서비스 메시의 비즈니스 가치와 전략적 이점

학습하면서 가장 궁금했던 점은 "왜 수많은 기업들이 단일 클러스터의 편안함을 포기하고 복잡한 다중 클러스터 구조로 이전하는가?"였습니다. 이에 대한 답은 현대 비즈니스의 현실적 요구사항에 있었습니다.

현장 이야기: ACME라는 가상의 회사를 통해 살펴보겠습니다. ACME는 클라우드 마이그레이션 초기에 클러스터 규모를 어떻게 조정할지 고민에 빠졌습니다. 단일 클러스터로 시작했지만, 비즈니스가 성장하면서 신속하게 다중 클러스터 전략으로 전환했습니다. 왜였을까요?

🔒 격리성 강화 (Improved Isolation): 팀 간 충돌 방지

실제 기업 환경에서는 여러 팀이 동시에 개발하고 배포합니다. 단일 클러스터에서는:

# 문제 상황 예시: 개발팀 A의 잘못된 배포가 전체 클러스터에 영향
kubectl apply -f bad-config.yaml  # 전체 클러스터의 네트워크 정책 손상
# 결과: 모든 팀의 서비스가 영향을 받음

다중 클러스터 환경에서는:

  • 팀별 클러스터 분리: 개발팀 A는 dev-cluster-a, 개발팀 B는 dev-cluster-b 사용
  • 폭발 반경 제한: 한 팀의 실수가 다른 팀에게 영향을 주지 않음
  • 독립적인 업데이트: 각 팀이 자신의 속도로 Kubernetes 버전, Istio 버전 업그레이드 가능

💡 현실적 조언: 100명 이상의 개발자가 있는 조직이라면 반드시 클러스터 분리를 고려해야 합니다. 혼재된 환경에서는 예기치 못한 장애가 연쇄적으로 발생할 확률이 기하급수적으로 증가합니다.

🛡️ 장애 경계 (Failure Boundary): 비즈니스 연속성 보장

실제 금융 서비스 회사에서 겪은 사례입니다:

# 단일 클러스터에서의 위험한 설정 변경
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: global-policy
  namespace: istio-system  # 전체 메시에 영향!
spec:
  rules:
  - to:
    - operation:
        methods: ["GET"]  # POST 요청 차단 -> 전체 서비스 마비!

다중 클러스터 설계에서는:

  • 클러스터별 정책 범위 제한: 한 클러스터의 설정 오류가 다른 클러스터에 전파되지 않음
  • 점진적 롤아웃: 새로운 정책을 한 클러스터에서 먼저 테스트한 후 점진적으로 확산
  • 빠른 복구: 문제 발생 시 트래픽을 정상 클러스터로 즉시 라우팅

📋 규정 준수 (Regulatory and Compliance): 법적 요구사항 충족

GDPR, HIPAA, SOX 같은 규정들은 단순히 권고사항이 아닙니다. 실제 사례를 보겠습니다:

# EU 사용자 데이터는 반드시 EU 리전에서만 처리
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: eu-cluster-setup
  namespace: istio-system
spec:
  values:
    global:
      meshID: eu-mesh
      multiCluster:
        clusterName: eu-west-cluster
        network: eu-network
      # EU 규정 준수를 위한 특별 설정
      defaultConfig:
        proxyMetadata:
          GDPR_COMPLIANT: "true"
          DATA_RESIDENCY: "EU"
  • 지역별 데이터 격리: EU 고객 데이터는 EU 클러스터에서만 처리
  • 규정 감사 추적: 클러스터별로 독립적인 감사 로그 관리
  • 컴플라이언스 인증: 각 지역의 법적 요구사항에 맞는 별도 인증 획득

⚡ 가용성 및 성능 향상: 글로벌 서비스의 필수 요소

Netflix, Amazon과 같은 글로벌 서비스들이 사용하는 전략:

# 지역별 클러스터 구성 예시
# US-West 클러스터
apiVersion: v1
kind: Service
metadata:
  name: catalog-service
  annotations:
    service.istio.io/preferred-region: "us-west"
    service.istio.io/locality-weight: "80"  # 80% 로컬 트래픽
spec:
  # 서비스 정의

---
# EU-West 클러스터  
apiVersion: v1
kind: Service
metadata:
  name: catalog-service
  annotations:
    service.istio.io/preferred-region: "eu-west"
    service.istio.io/locality-weight: "80"

실제 성능 지표:

  • 레이턴시 개선: 글로벌 사용자 대비 평균 레이턴시 60% 감소
  • 가용성 향상: 99.9%에서 99.99%로 향상 (연간 다운타임 8.76시간 → 52.56분)
  • 사용자 경험: 지역별 최적화된 서비스 제공

☁️ 다중 및 하이브리드 클라우드: 벤더 락인 방지와 비용 최적화

실제 사례: 대형 소매업체의 하이브리드 클라우드 전략

# AWS 클러스터 (신규 서비스)
export CLUSTER_CONTEXT="aws-prod-cluster"
kubectl config use-context $CLUSTER_CONTEXT

# Azure 클러스터 (레거시 서비스)  
export CLUSTER_CONTEXT="azure-legacy-cluster"
kubectl config use-context $CLUSTER_CONTEXT

# 온프레미스 클러스터 (민감한 금융 데이터)
export CLUSTER_CONTEXT="onprem-secure-cluster"
kubectl config use-context $CLUSTER_CONTEXT

전략적 이점:

  • 비용 최적화: 워크로드별로 가장 비용 효율적인 클라우드 선택
  • 벤더 의존성 제거: 하나의 클라우드 프로바이더에 종속되지 않음
  • 재해 복구: 한 클라우드의 장애 시 다른 클라우드로 페일오버

💰 실제 비용 절감 사례: 한 글로벌 제조업체는 다중 클라우드 전략으로 연간 클라우드 비용을 35% 절감했습니다. 컴퓨팅 집약적인 작업은 가격이 저렴한 클라우드로, 네트워크 집약적인 작업은 지연시간이 낮은 클라우드로 배치했기 때문입니다.

12.2 다중 클러스터 서비스 메시 아키텍처 심화 이해

학습하면서 알게 된 것은 다중 클러스터 구성이 단순히 "여러 개의 클러스터를 연결하는" 것 이상의 복잡한 고려사항들이 있다는 점이었습니다. 어떤 배포 모델을 선택하느냐에 따라 운영 복잡성, 성능, 보안이 크게 달라진다는 것을 실습을 통해 체감할 수 있었습니다.

🏗️ Istio 다중 클러스터 배포 모델 비교 분석

1️⃣ 단일 컨트롤 플레인 (Primary-Remote)

# Primary 클러스터 (us-west)
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: control-plane-primary
spec:
  values:
    global:
      meshID: production-mesh
      multiCluster:
        clusterName: us-west-primary
        network: us-west-network
    pilot:
      env:
        EXTERNAL_ISTIOD: true  # 원격 클러스터 지원

---
# Remote 클러스터 (us-east)
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: remote-cluster
spec:
  values:
    global:
      meshID: production-mesh
      multiCluster:
        clusterName: us-east-remote
        network: us-east-network
      remotePilotAddress: ${PRIMARY_CLUSTER_PILOT_ADDRESS}
    istiodRemote:
      enabled: true

장점:

  • 중앙화된 관리: 모든 정책과 설정을 한 곳에서 관리
  • 일관성 보장: 단일 제어점으로 구성 불일치 최소화
  • 리소스 효율성: 컨트롤 플레인 중복 없음

단점:

  • 단일 장애점: Primary 클러스터 장애 시 전체 메시 영향
  • 네트워크 의존성: Remote 클러스터가 Primary에 지속적으로 연결되어야 함
  • 지연시간: 원격 클러스터의 설정 변경 지연

2️⃣ 복제된 컨트롤 플레인 (Primary-Primary)

# West 클러스터 설정
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: west-control-plane
spec:
  values:
    global:
      meshID: production-mesh
      multiCluster:
        clusterName: west-cluster
        network: west-network
      # 양방향 클러스터 검색 활성화
      enableCrossClusterWorkloadEntry: true

---
# East 클러스터 설정 
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: east-control-plane
spec:
  values:
    global:
      meshID: production-mesh  # 동일한 메시 ID!
      multiCluster:
        clusterName: east-cluster
        network: east-network
      enableCrossClusterWorkloadEntry: true

장점:

  • 고가용성: 한 클러스터 장애 시에도 다른 클러스터는 독립 운영
  • 지역 자율성: 각 클러스터가 독립적으로 운영되어 지연시간 최소화
  • 확장성: 새로운 클러스터 추가가 더 용이

단점:

  • 관리 복잡성: 여러 컨트롤 플레인의 일관성 유지 필요
  • 리소스 오버헤드: 각 클러스터마다 완전한 컨트롤 플레인 필요
  • 설정 동기화: 수동으로 설정을 동기화해야 하는 경우 발생

🔄 메시 연합 vs 다중 클러스터 메시: 실전 선택 기준

메시 연합 (Mesh Federation) 적합한 시나리오:

# 조직별로 독립적인 메시 운영
# 보안팀 메시
kubectl create namespace security-mesh-system
kubectl label namespace security-mesh-system istio.io/mesh-id=security-mesh

# 개발팀 메시  
kubectl create namespace dev-mesh-system
kubectl label namespace dev-mesh-system istio.io/mesh-id=dev-mesh

# 메시 간 선택적 통신만 허용
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: inter-mesh-policy
spec:
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/security-mesh-system/sa/gateway-service"]
    to:
    - operation:
        methods: ["GET", "POST"]
        paths: ["/api/validate"]

다중 클러스터 서비스 메시 적합한 시나리오:

# 전역적으로 통합된 서비스 디스커버리
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: global-catalog-service
spec:
  hosts:
  - catalog.production.svc.cluster.local
  http:
  - match:
    - headers:
        region:
          exact: "us-west"
    route:
    - destination:
        host: catalog.production.svc.cluster.local
        subset: us-west-cluster
  - route:  # 기본 라우팅
    - destination:
        host: catalog.production.svc.cluster.local
        subset: us-east-cluster

🌐 네트워크 토폴로지와 워크로드 디스커버리

다중 네트워크 시나리오에서는 클러스터 간 Pod가 직접 통신할 수 없기 때문에 East-West 게이트웨이가 필요합니다:

# 네트워크 연결성 테스트
kubectl exec -it test-pod -- ping 10.20.0.15  # 다른 클러스터 Pod IP
# 실패 -> East-West 게이트웨이 필요

# 단일 네트워크 시나리오 (네이티브 라우팅)
kubectl exec -it test-pod -- ping 10.20.0.15  # 다른 클러스터 Pod IP  
# 성공 -> 직접 통신 가능

워크로드 디스커버리 원리:

# 클러스터 간 서비스 엔드포인트 공유
apiVersion: v1
kind: Secret
metadata:
  name: istio-remote-secret-east-cluster
  namespace: istio-system
  labels:
    istio/cluster: east-cluster
type: Opaque
data:
  east-cluster: <base64-encoded-kubeconfig>  # East 클러스터 접근 정보

이 시크릿을 통해 West 클러스터의 istiod가 East 클러스터의 서비스를 발견하고 Envoy 설정에 포함시킵니다.

12.3 엔터프라이즈급 다중 클러스터 배포 실습

이번 실습에서는 실제 운영 환경과 유사한 다중 클러스터 서비스 메시를 직접 구축해보았습니다. 클러스터 간 안전한 통신, 서비스 디스커버리, 트래픽 라우팅을 직접 체험할 수 있었던 값진 경험이었습니다.

실습 시나리오로는 ACME 회사의 글로벌 전자상거래 플랫폼을 시뮬레이션했습니다:

  • West 클러스터: 미국 서부 (webapp 서비스 운영)
  • East 클러스터: 미국 동부 (catalog 서비스 운영)

🏗️ Step 1: 실습 환경 구성 - 지역 분산 아키텍처


# West 클러스터 생성 (US-West 리전 시뮬레이션)
cat << 'EOF' > west-cluster-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000 # istio-ingressgateway HTTP
    hostPort: 30000
  - containerPort: 30001 # Prometheus
    hostPort: 30001
  - containerPort: 30002 # Grafana
    hostPort: 30002
  - containerPort: 30003 # Kiali
    hostPort: 30003
  - containerPort: 30004 # Tracing
    hostPort: 30004
networking:
  podSubnet: 10.10.0.0/16      # West 클러스터 전용 Pod 대역
  serviceSubnet: 10.100.0.0/24  # West 클러스터 서비스 대역
EOF

kind create cluster --name west --image kindest/node:v1.23.17 \
  --kubeconfig ./west-kubeconfig --config west-cluster-config.yaml

# East 클러스터 생성 (US-East 리전 시뮬레이션)
cat << 'EOF' > east-cluster-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 31000 # istio-ingressgateway HTTP
    hostPort: 31000
  - containerPort: 31001 # Prometheus
    hostPort: 31001
  - containerPort: 31002 # Grafana
    hostPort: 31002
  - containerPort: 31003 # Kiali
    hostPort: 31003
  - containerPort: 31004 # Tracing
    hostPort: 31004
networking:
  podSubnet: 10.20.0.0/16      # East 클러스터 전용 Pod 대역
  serviceSubnet: 10.200.0.0/24  # East 클러스터 서비스 대역
EOF

kind create cluster --name east --image kindest/node:v1.23.17 \
  --kubeconfig ./east-kubeconfig --config east-cluster-config.yaml

환경 확인 및 네트워크 테스트:

# 클러스터 생성 확인
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep -E "(west|east)"

# kubectl 컨텍스트 설정
kubectl config set-context west-context --cluster=kind-west --user=kind-west
kubectl config set-context east-context --cluster=kind-east --user=kind-east

# 각 클러스터의 네트워크 확인
echo "=== West 클러스터 네트워크 정보 ==="
kubectl --kubeconfig=./west-kubeconfig get nodes -o wide
kubectl --kubeconfig=./west-kubeconfig get pods -n kube-system -o wide | head -3

echo "=== East 클러스터 네트워크 정보 ==="
kubectl --kubeconfig=./east-kubeconfig get nodes -o wide
kubectl --kubeconfig=./east-kubeconfig get pods -n kube-system -o wide | head -3

# 클러스터 간 네트워크 분리 확인 (예상: 실패)
docker exec west-control-plane ping -c 1 east-control-plane 2>/dev/null || echo "✅ 클러스터 간 네트워크 분리 확인됨"

💡 운영 팁: 실제 환경에서는 각 클러스터가 서로 다른 VPC나 네트워크에 위치하여 자연스럽게 분리됩니다. 이는 보안과 장애 격리에 중요한 역할을 합니다.

🔧 Step 2: 공통 신뢰 기반 구축 - 인증서 관리

다중 클러스터 서비스 메시에서 공통 신뢰(Common Trust)는 필수적입니다. 클러스터 간 상호 인증을 위해 동일한 루트 CA를 사용해야 합니다.

# 편의를 위한 alias 설정
alias kwest='kubectl --kubeconfig=./west-kubeconfig'
alias keast='kubectl --kubeconfig=./east-kubeconfig'

# 공통 CA 인증서 생성 (프로덕션에서는 실제 CA 사용)
mkdir -p certs
cd certs

# 루트 CA 생성
openssl req -x509 -newkey rsa:4096 -keyout root-ca-key.pem -out root-ca-cert.pem \
  -days 365 -nodes -subj "/C=US/ST=CA/L=SanFrancisco/O=ACME/CN=ACME Root CA"

# 중간 CA 생성 (각 클러스터용)
# West 클러스터용 중간 CA
openssl req -newkey rsa:4096 -keyout west-ca-key.pem -out west-ca-csr.pem \
  -nodes -subj "/C=US/ST=CA/L=SanFrancisco/O=ACME/CN=ACME West Intermediate CA"
openssl x509 -req -in west-ca-csr.pem -CA root-ca-cert.pem -CAkey root-ca-key.pem \
  -CAcreateserial -out west-ca-cert.pem -days 365

# East 클러스터용 중간 CA
openssl req -newkey rsa:4096 -keyout east-ca-key.pem -out east-ca-csr.pem \
  -nodes -subj "/C=US/ST=NY/L=NewYork/O=ACME/CN=ACME East Intermediate CA"
openssl x509 -req -in east-ca-csr.pem -CA root-ca-cert.pem -CAkey root-ca-key.pem \
  -CAcreateserial -out east-ca-cert.pem -days 365

# 인증서 체인 생성
cat west-ca-cert.pem root-ca-cert.pem > west-cert-chain.pem
cat east-ca-cert.pem root-ca-cert.pem > east-cert-chain.pem

cd ..

Step 3: Istio 컨트롤 플레인 설치 - 복제된 컨트롤 플레인 모델

# istioctl 다운로드 (각 클러스터 컨테이너에)
export ISTIO_VERSION=1.17.8
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIO_VERSION sh -
sudo cp istio-$ISTIO_VERSION/bin/istioctl /usr/local/bin/

# West 클러스터 설정
cat << 'EOF' > west-istio-config.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: west-controlplane
  namespace: istio-system
spec:
  profile: demo
  components:
    egressGateways:
    - name: istio-egressgateway
      enabled: false  # 실습에서는 비활성화
  values:
    global:
      meshID: acme-production-mesh  # 글로벌 메시 ID
      multiCluster:
        clusterName: west-cluster   # 클러스터 고유 식별자
        network: west-network       # 네트워크 식별자
      # 메시 네트워크 토폴로지 정의
      meshNetworks:
        west-network:
          endpoints:
          - fromRegistry: west-cluster
          gateways:
          - address: 172.18.255.200  # East-West 게이트웨이 주소 (나중에 설정)
            port: 15443
        east-network:
          endpoints:
          - fromRegistry: east-cluster
          gateways:
          - address: 172.18.255.201
            port: 15443
EOF

# East 클러스터 설정
cat << 'EOF' > east-istio-config.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: east-controlplane
  namespace: istio-system
spec:
  profile: demo
  components:
    egressGateways:
    - name: istio-egressgateway
      enabled: false
  values:
    global:
      meshID: acme-production-mesh  # 동일한 메시 ID
      multiCluster:
        clusterName: east-cluster
        network: east-network
      meshNetworks:
        west-network:
          endpoints:
          - fromRegistry: west-cluster
          gateways:
          - address: 172.18.255.200
            port: 15443
        east-network:
          endpoints:
          - fromRegistry: east-cluster
          gateways:
          - address: 172.18.255.201
            port: 15443
EOF

실제 설치 실행:

# 네임스페이스 생성 및 CA 인증서 배포
kwest create namespace istio-system
keast create namespace istio-system

# 공통 CA 인증서 배포
kwest create secret generic cacerts -n istio-system \
  --from-file=certs/root-ca-cert.pem \
  --from-file=certs/west-cert-chain.pem \
  --from-file=certs/west-ca-cert.pem \
  --from-file=certs/west-ca-key.pem

keast create secret generic cacerts -n istio-system \
  --from-file=certs/root-ca-cert.pem \
  --from-file=certs/east-cert-chain.pem \
  --from-file=certs/east-ca-cert.pem \
  --from-file=certs/east-ca-key.pem

# Istio 설치
istioctl install --kubeconfig=./west-kubeconfig -f west-istio-config.yaml -y
istioctl install --kubeconfig=./east-kubeconfig -f east-istio-config.yaml -y

# 부가 도구 설치
kwest apply -f istio-$ISTIO_VERSION/samples/addons/
keast apply -f istio-$ISTIO_VERSION/samples/addons/

설치 확인 및 상태 점검:

# 컨트롤 플레인 파드 상태 확인
echo "=== West 클러스터 Istio 구성 요소 ==="
kwest get pods -n istio-system
kwest get istiooperator -n istio-system

echo "=== East 클러스터 Istio 구성 요소 ==="
keast get pods -n istio-system  
keast get istiooperator -n istio-system

# 인증서 확인
echo "=== 인증서 체인 확인 ==="
kwest get secret cacerts -n istio-system -o jsonpath='{.data.cert-chain\.pem}' | base64 -d | openssl x509 -text -noout | grep "Issuer:"
keast get secret cacerts -n istio-system -o jsonpath='{.data.cert-chain\.pem}' | base64 -d | openssl x509 -text -noout | grep "Issuer:"

# istiod 버전 확인
kwest exec -n istio-system deploy/istiod -- pilot-discovery version
keast exec -n istio-system deploy/istiod -- pilot-discovery version

🔒 보안 모범 사례: 프로덕션 환경에서는 Hardware Security Module(HSM)이나 외부 PKI 시스템을 사용하여 CA 키를 보호해야 합니다. 또한 인증서 순환(rotation) 정책을 수립하고 자동화해야 합니다.

🔐 Step 4: 클러스터 간 워크로드 디스커버리 설정

각 클러스터가 상대방의 워크로드를 발견할 수 있도록 시크릿을 생성:

# East 클러스터의 시크릿을 West 클러스터에 생성
istioctl create-remote-secret \
  --context=east \
  --name=east-cluster | \
  kubectl apply -f - --context=west

# West 클러스터의 시크릿을 East 클러스터에 생성
istioctl create-remote-secret \
  --context=west \
  --name=west-cluster | \
  kubectl apply -f - --context=east

🌉 Step 5: East-West 게이트웨이 설정

클러스터 간 통신을 위한 East-West 게이트웨이 구성:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio-eastwestgateway
  namespace: istio-system
spec:
  profile: empty
  components:
    ingressGateways:
    - name: istio-eastwestgateway
      label:
        istio: eastwestgateway
        app: istio-eastwestgateway
      enabled: true
      k8s:
        env:
        - name: ISTIO_META_ROUTER_MODE
          value: "sni-dnat"  # SNI 클러스터 활성화
        - name: ISTIO_META_REQUESTED_NETWORK_VIEW
          value: east-network

📡 SNI 클러스터와 자동 통과

East-West 게이트웨이는 SNI(Server Name Indication) 클러스터를 사용하여:

  • 모든 엔보이 클러스터 정보를 SNI에 인코딩
  • 암호화된 트래픽을 적절한 클러스터로 라우팅
  • 상호 인증된 연결 유지

🧪 Step 6: 실습 결과 확인

# 클러스터 간 서비스 디스커버리 확인
kubectl get endpoints catalog -n istioinaction --context=west
kubectl get endpoints catalog -n istioinaction --context=east

# East-West 트래픽 테스트
curl -H "Host: webapp.istioinaction.io" http://west-cluster-ip/api/catalog


📘 14장: 이스티오의 요청 처리 기능 확장하기 - 고급 데이터 플레인 커스터마이징

14.1 엔보이의 확장 기능: 표준을 넘어선 요구사항 해결

데이터 플레인 확장이 필요한 이유

학습하면서 깨달은 것은 Istio의 표준 기능만으로는 모든 비즈니스 요구사항을 충족할 수 없다는 점이었습니다. 실제 사례를 통해 이를 확인할 수 있었습니다:

현장 사례: 한 금융서비스 회사에서는 모든 API 호출에 대해 특별한 암호화된 거래 ID를 헤더에 추가해야 했습니다. 이 ID는 복잡한 알고리즘으로 생성되며, 표준 Istio 기능으로는 구현할 수 없었습니다.

이런 특별한 요구사항들을 해결하기 위해 Envoy의 확장 가능한 아키텍처를 학습하고 활용해보았습니다.

🔗 Envoy 필터 체인 아키텍처 심화 이해

학습을 통해 알게 된 것은 Envoy가 계층적 필터 체인으로 구성되어 있으며, 각 계층에서 다양한 확장점을 제공한다는 점이었습니다:

     ┌─────────────────────────────────────────────┐
     │           Listener                          │
     │  (Port 8080에서 들어오는 요청 수신)           │
     └─────────────────────┬───────────────────────┘
                           │
     ┌─────────────────────▼───────────────────────┐
     │         Network Filter Chain               │
     │  ┌─────────────────────────────────────┐    │
     │  │    MongoDB Filter                  │    │
     │  ├─────────────────────────────────────┤    │
     │  │    Redis Filter                    │    │
     │  ├─────────────────────────────────────┤    │
     │  │    HTTP Connection Manager (HCM)   │ ←──┼── 가장 중요!
     │  └─────────────────────────────────────┘    │
     └─────────────────────┬───────────────────────┘
                           │
     ┌─────────────────────▼───────────────────────┐
     │         HTTP Filter Chain                  │
     │  ┌─────────────────────────────────────┐    │
     │  │    CORS Filter                     │    │
     │  ├─────────────────────────────────────┤    │
     │  │    JWT Authentication Filter       │    │
     │  ├─────────────────────────────────────┤    │
     │  │    Rate Limiting Filter            │    │
     │  ├─────────────────────────────────────┤    │
     │  │    Custom Business Logic Filter    │ ←──┼── 우리가 추가할 곳!
     │  ├─────────────────────────────────────┤    │
     │  │    Router Filter (Terminal)        │    │
     │  └─────────────────────────────────────┘    │
     └─────────────────────┬───────────────────────┘
                           │
     ┌─────────────────────▼───────────────────────┐
     │         Upstream Cluster                   │
     │      (실제 백엔드 서비스로 전달)             │
     └─────────────────────────────────────────────┘

각 계층의 역할과 확장 가능성:

  1. 리스너 (Listener):

    • 네트워크 인터페이스 바인딩
    • 확장 포인트: 사용자 정의 리스너 필터
  2. 네트워크 필터:

    • 바이트 스트림 처리
    • 확장 포인트: TCP/UDP 레벨 커스터마이징
  3. HTTP Connection Manager:

    • HTTP 프로토콜 파싱
    • 확장 포인트: HTTP 레벨 커스터마이징
  4. HTTP 필터:

    • 요청/응답 처리
    • 확장 포인트: 가장 많이 사용되는 확장 영역

📋 실전에서 자주 사용되는 HTTP 필터들

# 실제 프로덕션에서 사용되는 필터 체인 예시
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: production-filter-chain
  namespace: payment-service
spec:
  workloadSelector:
    labels:
      app: payment-api
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
    patch:
      operation: INSERT_BEFORE
      filterClass: AUTHZ  # 인증 전에 실행
      value:
        name: envoy.filters.http.cors
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
          allow_origin_string_match:
          - prefix: "https://secure-"
          allow_methods: "GET, POST, PUT"
          allow_headers: "authorization, content-type, x-transaction-id"

주요 필터 카테고리별 사용 사례:

  • 🔐 보안 필터:

    • envoy.filters.http.jwt_authn: JWT 토큰 검증
    • envoy.filters.http.rbac: 역할 기반 접근 제어
    • envoy.filters.http.ext_authz: 외부 인증 서비스 연동
  • 📊 관찰성 필터:

    • envoy.filters.http.wasm: WebAssembly 기반 메트릭 수집
    • envoy.filters.http.tap: 디버깅을 위한 트래픽 캡처
    • envoy.access_loggers.file: 상세 액세스 로그
  • 🚦 트래픽 제어 필터:

    • envoy.filters.http.local_ratelimit: 로컬 속도 제한
    • envoy.filters.http.fault: 결함 주입 테스트
    • envoy.filters.http.adaptive_concurrency: 적응적 동시성 제어
  • 🔧 데이터 변환 필터:

    • envoy.filters.http.grpc_json_transcoder: gRPC ↔ JSON 변환
    • envoy.filters.http.lua: Lua 스크립트 실행
    • envoy.filters.http.header_to_metadata: 헤더 → 메타데이터 변환

💡 설계 원칙: 각 필터는 단일 책임 원칙을 따르며, 체인을 통해 조합됩니다. 이는 마이크로서비스 아키텍처와 유사한 철학입니다.

14.2 EnvoyFilter 리소스로 엔보이 필터 설정하기: 실전 가이드

⚠️ 위험 요소와 모범 사례

EnvoyFilter는 강력하지만 위험한 도구입니다. 잘못 사용하면 전체 서비스 메시가 중단될 수 있습니다.

# 실제 장애 사례: 잘못된 EnvoyFilter로 인한 서비스 중단
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: dangerous-filter  # 위험한 설정 예시
  namespace: istio-system  # 😱 전체 메시에 적용!
spec:
  # workloadSelector 없음 = 모든 워크로드에 적용
  configPatches:
  - applyTo: HTTP_FILTER
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.http.nonexistent_filter  # 😱 존재하지 않는 필터!

안전한 EnvoyFilter 개발 워크플로우:

  1. 개발 환경에서 테스트
  2. 특정 워크로드로 범위 제한
  3. 카나리 배포 적용
  4. 모니터링 및 롤백 계획 수립

🔍 실습: 프로덕션급 Tap 필터 구현

Step 1: 안전한 실습 환경 구성

# 실습용 네임스페이스 생성
kubectl create namespace tap-debug-lab
kubectl label namespace tap-debug-lab istio-injection=enabled

# 테스트 애플리케이션 배포
cat << 'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: debug-webapp
  namespace: tap-debug-lab
spec:
  replicas: 1
  selector:
    matchLabels:
      app: debug-webapp
      version: v1
  template:
    metadata:
      labels:
        app: debug-webapp
        version: v1
    spec:
      containers:
      - name: webapp
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: debug-webapp
  namespace: tap-debug-lab
spec:
  selector:
    app: debug-webapp
  ports:
  - port: 80
    targetPort: 80
EOF

Step 2: 점진적 Tap 필터 배포

# 프로덕션급 Tap 필터 설정
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: safe-tap-filter
  namespace: tap-debug-lab
spec:
  workloadSelector:
    labels:
      app: debug-webapp  # 특정 앱에만 적용
      version: v1        # 특정 버전에만 적용
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        portNumber: 80
      filterChain:
        filter:
          name: "envoy.filters.network.http_connection_manager"
        subFilter:
          name: "envoy.filters.http.router"
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.http.tap
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.tap.v3.Tap"
          commonConfig:
            adminConfig:
              configId: debug_tap_config
            # 보안을 위한 제한 설정
            maxBufferedRxBytes: 1024    # 수신 버퍼 제한
            maxBufferedTxBytes: 1024    # 송신 버퍼 제한
            streaming: true             # 스트리밍 모드 활성화

Step 3: 실시간 디버깅 실행

# Tap 설정 JSON 파일 생성
cat << 'EOF' > debug-tap-config.json
{
  "config_id": "debug_tap_config",
  "tap_config": {
    "match_config": {
      "http_request_headers_match": {
        "headers": [
          {
            "name": "x-debug-session",
            "exact_match": "enabled"
          }
        ]
      }
    },
    "output_config": {
      "sinks": [
        {
          "streaming_admin": {}
        }
      ]
    }
  }
}
EOF

# 포트 포워딩 및 Tap 활성화
kubectl port-forward -n tap-debug-lab deploy/debug-webapp 15000:15000 &
curl -X POST -d @debug-tap-config.json \
  -H "Content-Type: application/json" \
  http://localhost:15000/tap

# 디버그 요청 전송 (별도 터미널)
kubectl port-forward -n tap-debug-lab svc/debug-webapp 8080:80 &
curl -H "x-debug-session: enabled" \
  -H "x-trace-id: 12345" \
  http://localhost:8080/

14.3 고급 확장 기법: Lua와 WebAssembly

💻 Lua 스크립트: 빠른 프로토타이핑

Lua는 빠른 개발과 유연성이 필요할 때 적합합니다:

-- 요청 헤더에 비즈니스 로직 추가
function envoy_on_request(request_handle)
  -- 사용자 지역 감지
  local user_ip = request_handle:headers():get("x-forwarded-for")
  local region = detect_region(user_ip)
  
  -- 지역별 라우팅 헤더 추가
  request_handle:headers():add("x-user-region", region)
  
  -- 비즈니스 시간 확인
  local current_hour = os.date("!%H")
  if tonumber(current_hour) < 9 or tonumber(current_hour) > 17 then
    request_handle:headers():add("x-business-hours", "false")
  else
    request_handle:headers():add("x-business-hours", "true")
  end
end

🦀 WebAssembly: 고성능 확장

WASM은 성능이 중요한 프로덕션 환경에서 사용합니다:

// Rust로 작성된 고성능 필터 예시
use proxy_wasm::traits::*;
use proxy_wasm::types::*;

#[no_mangle]
pub fn _start() {
    proxy_wasm::set_log_level(LogLevel::Trace);
    proxy_wasm::set_http_context(|_| -> Box<dyn HttpContext> {
        Box::new(CustomAuthFilter)
    });
}

struct CustomAuthFilter;

impl HttpContext for CustomAuthFilter {
    fn on_http_request_headers(&mut self, _num_headers: usize) -> Action {
        // 고성능 인증 로직
        let auth_header = self.get_http_request_header("authorization");
        
        match validate_token_fast(&auth_header) {
            Ok(user_info) => {
                self.add_http_request_header("x-user-id", &user_info.id);
                Action::Continue
            },
            Err(_) => {
                self.send_http_response(401, vec![], Some(b"Unauthorized"));
                Action::Pause
            }
        }
    }
}

Lua vs WASM 선택 기준:

기준LuaWebAssembly
개발 속도🟢 빠름🟡 보통
성능🟡 보통🟢 높음
메모리 사용량🟢 낮음🟡 보통
디버깅🟢 쉬움🔴 어려움
보안🟡 보통🟢 높음

💡 실무 권장사항:

  • 프로토타이핑과 간단한 로직: Lua 사용
  • 프로덕션 고성능 요구사항: WebAssembly 사용
  • 복잡한 비즈니스 로직: 별도 마이크로서비스로 분리 고려

🎯 핵심 포인트 정리

12장 - 다중 클러스터 스케일링

  1. 격리성과 가용성을 위한 다중 클러스터 구성
  2. East-West 게이트웨이를 통한 클러스터 간 안전한 통신
  3. SNI 클러스터로 세밀한 트래픽 라우팅
  4. 공통 신뢰를 통한 클러스터 간 상호 인증

14장 - 데이터 플레인 확장

  1. Envoy 필터 체인 이해와 활용
  2. EnvoyFilter 리소스로 고급 설정
  3. Lua와 WebAssembly를 통한 커스터마이징
  4. Tap 필터를 활용한 디버깅

💡 마무리: 엔터프라이즈급 Istio 여정의 시작

이번 7주차 학습을 통해 Istio의 진정한 기업급 활용법을 체험해볼 수 있었습니다. 물론 이는 시작에 불과하다는 생각이 듭니다.

🎯 실무 적용 로드맵

단계 1 (1-2개월): 기초 다중 클러스터 구성

  • 개발/스테이징 환경에서 2-클러스터 구성 실험
  • 기본적인 East-West 통신 구현
  • 모니터링 파이프라인 구축

단계 2 (3-6개월): 프로덕션 배포

  • 프로덕션 환경에 점진적 적용
  • 재해 복구 시나리오 테스트
  • 성능 최적화 및 튜닝

단계 3 (6-12개월): 고급 커스터마이징

  • 비즈니스 요구사항에 맞는 EnvoyFilter 개발
  • WebAssembly 기반 고성능 확장 구현
  • 조직 전체 플랫폼으로 확장

🌟 성공하는 조직의 공통점

학습하면서 조사해본 성공적으로 Istio를 확장한 조직들의 공통점은 다음과 같았습니다:

  1. 점진적 접근: 한 번에 모든 것을 바꾸려 하지 않음
  2. 강력한 모니터링: 문제를 미리 감지할 수 있는 시스템 구축
  3. 팀 간 협업: 개발, 운영, 보안팀 간의 긴밀한 협력
  4. 지속적 학습: Istio 커뮤니티와 지속적인 지식 교환

마지막 조언: 서비스 메시는 도구일 뿐입니다. 진짜 가치는 이를 통해 더 안정적이고 확장 가능한 시스템을 구축하여 비즈니스 가치를 창출하는 것입니다. 기술보다는 문제 해결에 집중하세요.

다음 주에는 Istio의 미래와 최신 트렌드에 대해 학습해볼 예정입니다. 계속해서 깊이 있는 학습을 이어가겠습니다! 🚀

profile
성장해나가는 개발자입니다.

0개의 댓글