Post

Istio Sidecar 모드 완전 정복 - 아키텍처, 트래픽 관리, 보안, Observability (공식문서 Deep Dive)

Istio Sidecar 모드 완전 정복 - 아키텍처, 트래픽 관리, 보안, Observability (공식문서 Deep Dive)

Istio Sidecar 모드는 프로덕션 환경에서 가장 오래 검증된 Service Mesh 배포 방식이다. 이 글에서는 공식 문서를 기반으로 Istio의 아키텍처, Sidecar Injection 메커니즘, xDS 프로토콜, 트래픽 관리, 보안, Observability를 단계별로 깊이 있게 정리한다.


1. Istio 소개

원문 (Istio - What is Istio?): “A service mesh is an infrastructure layer that gives applications capabilities like zero-trust security, observability, and advanced traffic management, without code changes. Istio is the most popular, powerful, and trusted service mesh. Founded by Google, IBM and Lyft in 2016, Istio is a graduated project in the Cloud Native Computing Foundation alongside projects like Kubernetes and Prometheus.”

번역: Service Mesh는 애플리케이션에 코드 변경 없이 제로 트러스트 보안, 관측성, 고급 트래픽 관리 기능을 제공하는 인프라 계층이다. Istio는 가장 인기 있고, 강력하며, 신뢰받는 Service Mesh이다. 2016년 Google, IBM, Lyft가 공동 창립했으며, Kubernetes, Prometheus와 함께 CNCF Graduated 프로젝트이다.

Istio는 마이크로서비스 간 네트워크 통신의 복잡성을 애플리케이션 코드에서 분리하여 인프라 계층에서 해결한다. 각 서비스가 개별적으로 재시도, 타임아웃, 암호화, 접근 제어를 구현하는 대신, 사이드카 프록시가 이 모든 것을 투명하게 처리한다.

1.1 핵심 기능

Istio 공식 문서에서 명시하는 핵심 기능은 다음과 같다.

기능설명
Secure by default워크로드 간 mTLS 자동 적용, 인증서 자동 로테이션
Powerful traffic managementVirtualService, DestinationRule을 통한 세밀한 트래픽 제어
Observable코드 변경 없이 메트릭, 로그, 분산 추적 자동 수집
ExtensibleWebAssembly 플러그인, Envoy 필터 체인을 통한 확장

2. Architecture (공식문서 기반)

원문 (Istio Architecture): “An Istio service mesh is logically split into a data plane and a control plane. The data plane is composed of a set of intelligent proxies (Envoy) deployed as sidecars. These proxies mediate and control all network communication between microservices. They also collect and report telemetry on all mesh traffic. The control plane manages and configures the proxies to route traffic.”

번역: Istio Service Mesh는 논리적으로 데이터 플레인과 컨트롤 플레인으로 나뉜다. 데이터 플레인은 사이드카로 배포되는 지능형 프록시(Envoy) 집합으로 구성된다. 이 프록시들은 마이크로서비스 간 모든 네트워크 통신을 중재하고 제어한다. 또한 모든 메시 트래픽에 대한 텔레메트리를 수집하고 보고한다. 컨트롤 플레인은 프록시를 관리하고 설정하여 트래픽을 라우팅한다.

이 아키텍처의 핵심은 관심사의 분리(Separation of Concerns)이다. 컨트롤 플레인은 “무엇을 할 것인가”를 결정하고, 데이터 플레인은 “어떻게 실행할 것인가”를 담당한다.

2.1 전체 아키텍처 다이어그램

graph TB
    subgraph Control_Plane["Control Plane"]
        istiod["istiod<br/>(Pilot + Citadel + Galley)"]
    end

    subgraph Data_Plane["Data Plane"]
        subgraph Pod_A["Pod A"]
            AppA["App Container"]
            InitA["istio-init<br/>(iptables 설정)"]
            ProxyA["Envoy Sidecar<br/>:15001 outbound<br/>:15006 inbound"]
            AgentA["pilot-agent"]
        end

        subgraph Pod_B["Pod B"]
            AppB["App Container"]
            InitB["istio-init<br/>(iptables 설정)"]
            ProxyB["Envoy Sidecar<br/>:15001 outbound<br/>:15006 inbound"]
            AgentB["pilot-agent"]
        end

        subgraph Gateway["Istio Gateway"]
            IGW["Ingress Gateway<br/>(Envoy)"]
            EGW["Egress Gateway<br/>(Envoy)"]
        end
    end

    subgraph External["External"]
        Client["External Client"]
        ExtSvc["External Service"]
    end

    K8sAPI["Kubernetes API Server"]

    K8sAPI -->|"Watch: Service, Endpoint,<br/>VirtualService, DestinationRule"| istiod
    istiod -->|"xDS API<br/>(LDS/RDS/CDS/EDS/SDS)"| ProxyA
    istiod -->|"xDS API"| ProxyB
    istiod -->|"xDS API"| IGW
    istiod -->|"xDS API"| EGW
    istiod -->|"SPIFFE X.509 인증서"| AgentA
    istiod -->|"SPIFFE X.509 인증서"| AgentB

    Client -->|"Ingress Traffic"| IGW
    IGW --> ProxyA
    AppA <--> ProxyA
    ProxyA <-->|"mTLS"| ProxyB
    AppB <--> ProxyB
    ProxyB --> EGW
    EGW -->|"Egress Traffic"| ExtSvc

2.2 Control Plane - istiod

Istio 1.5 이전에는 Pilot, Citadel, Galley가 별도 프로세스로 동작했지만, 1.5부터 istiod라는 단일 바이너리로 통합되었다. 이로 인해 운영 복잡도가 크게 감소했고, 컴포넌트 간 통신 오버헤드도 제거되었다.

원문 (Istio - Introducing istiod): “istiod unifies functionality that Pilot, Citadel, Galley and the sidecar injector previously performed, into a single binary.”

번역: istiod는 이전에 Pilot, Citadel, Galley, 사이드카 인젝터가 수행하던 기능을 하나의 바이너리로 통합한다.

각 컴포넌트의 역할은 다음과 같다.

컴포넌트역할상세
Pilot서비스 디스커버리, Envoy 프록시 설정Kubernetes API Server를 watch하여 Service, Endpoint 변경을 감지하고 xDS API로 프록시에 push
Citadel워크로드 ID 발급, 인증서 관리SPIFFE X.509 인증서 발급, 자동 로테이션 (기본 24시간), Root CA 관리
Galley설정 검증 및 분배VirtualService, DestinationRule 등 Istio CRD의 스키마 검증, 유효성 확인 후 Pilot에 전달

istiod는 다음과 같은 포트를 사용한다.

포트프로토콜용도
15010gRPC (plaintext)xDS API (디버깅용)
15012gRPC (mTLS)xDS API (프로덕션)
15014HTTP컨트롤 플레인 모니터링
15017HTTPSWebhook (Sidecar Injection, Config Validation)
443HTTPSWebhook (15017로 리다이렉트)

2.3 Data Plane - Envoy Proxy

원문 (Envoy - What is Envoy): “Envoy is an L7 proxy and communication bus designed for large modern service oriented architectures.”

번역: Envoy는 대규모 현대 서비스 지향 아키텍처를 위해 설계된 L7 프록시이자 통신 버스이다.

Istio의 데이터 플레인에서 Envoy는 다음 기능을 수행한다.

  • Dynamic service discovery: istiod로부터 xDS를 통해 서비스 목록을 동적으로 수신
  • Load balancing: 다양한 알고리즘 지원 (ROUND_ROBIN, LEAST_REQUEST, RANDOM, RING_HASH)
  • TLS termination: 인바운드/아웃바운드 mTLS 자동 처리
  • HTTP/2 and gRPC proxies: 프로토콜 레벨 인식 및 최적화
  • Circuit breakers: 연결 풀, 요청 수 기반 회로 차단
  • Health checks: 능동적/수동적 헬스 체크
  • Staged rollouts with %-based traffic split: 가중치 기반 트래픽 분할
  • Fault injection: 지연, 중단 주입으로 카오스 테스팅
  • Rich metrics: L4/L7 메트릭 자동 수집 및 보고

3. Sidecar Injection 메커니즘

Istio의 사이드카 주입은 Kubernetes의 MutatingAdmissionWebhook을 활용한다. Pod 생성 요청이 API Server에 도달하면, istiod의 웹훅이 Pod spec을 수정하여 istio-init init container와 istio-proxy sidecar container를 추가한다.

원문 (Istio - Installing the Sidecar): “In order to take advantage of all of Istio’s features, pods in the mesh must be running an Istio sidecar proxy. Sidecars can be injected automatically with a mutating webhook admission controller, or manually using istioctl.”

번역: Istio의 모든 기능을 활용하려면 메시 내 Pod에 Istio 사이드카 프록시가 실행되어야 한다. 사이드카는 Mutating Webhook Admission Controller를 통해 자동으로 주입하거나, istioctl을 사용하여 수동으로 주입할 수 있다.

3.1 주입 제어 방법

방법적용 범위예시
Namespace label네임스페이스 전체kubectl label namespace default istio-injection=enabled
Pod annotation개별 Podsidecar.istio.io/inject: "true"
Revision label특정 istiod revisionistio.io/rev=canary (카나리 업그레이드용)
1
2
3
4
5
6
7
# Namespace 레벨 자동 주입 활성화
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    istio-injection: enabled
1
2
3
4
5
6
7
8
9
10
11
12
13
# Pod 레벨 주입 제어
apiVersion: v1
kind: Pod
metadata:
  name: my-app
  annotations:
    sidecar.istio.io/inject: "true"          # 주입 활성화
    sidecar.istio.io/proxyCPU: "100m"        # 사이드카 CPU 요청
    sidecar.istio.io/proxyMemory: "128Mi"    # 사이드카 메모리 요청
spec:
  containers:
    - name: my-app
      image: my-app:v1

3.2 Sidecar Injection 시퀀스

sequenceDiagram
    participant User as kubectl / CI/CD
    participant API as Kubernetes API Server
    participant Webhook as istiod<br/>(MutatingWebhook)
    participant Kubelet as Kubelet
    participant Init as istio-init
    participant Agent as pilot-agent
    participant Proxy as Envoy Proxy
    participant Istiod as istiod<br/>(Control Plane)

    User->>API: Pod 생성 요청
    API->>Webhook: MutatingAdmissionWebhook 호출
    Webhook->>Webhook: injection 조건 확인<br/>(namespace label, pod annotation)
    Webhook->>API: Pod spec 수정 반환<br/>(istio-init + istio-proxy 추가)
    API->>Kubelet: 수정된 Pod 스케줄링

    Note over Kubelet,Init: Init Container 단계
    Kubelet->>Init: istio-init 실행
    Init->>Init: iptables 규칙 설정<br/>INBOUND → 15006<br/>OUTBOUND → 15001
    Init->>Kubelet: 완료

    Note over Kubelet,Proxy: Main Container 단계
    Kubelet->>Agent: pilot-agent 시작
    Agent->>Proxy: Envoy 프로세스 시작
    Agent->>Istiod: SDS 요청 (인증서)
    Istiod->>Agent: SPIFFE X.509 인증서 발급
    Agent->>Proxy: 인증서 전달
    Proxy->>Istiod: xDS 연결 수립<br/>(LDS/RDS/CDS/EDS)
    Istiod->>Proxy: 초기 설정 push
    Proxy->>Proxy: 트래픽 처리 시작

3.3 istio-init Container (iptables 설정)

istio-init은 init container로 실행되어 Pod의 네트워크 네임스페이스에 iptables 규칙을 설정한다. 이 규칙에 의해 모든 인바운드/아웃바운드 트래픽이 Envoy 프록시를 경유하게 된다.

원문 (Istio - Debugging Envoy and Istiod): “Envoy intercepts all inbound and outbound traffic for the pod.”

번역: Envoy는 Pod의 모든 인바운드 및 아웃바운드 트래픽을 가로챈다.

핵심 iptables 규칙의 동작 원리는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
# istio-init이 설정하는 iptables 규칙 (간소화 버전)

# 인바운드 트래픽: 모든 TCP → 0.0.0.0:15006 (Envoy inbound listener)
iptables -t nat -A PREROUTING -p tcp -j REDIRECT --to-ports 15006

# 아웃바운드 트래픽: 모든 TCP → 0.0.0.0:15001 (Envoy outbound listener)
iptables -t nat -A OUTPUT -p tcp -j ISTIO_OUTPUT
iptables -t nat -A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN  # Envoy 자체 트래픽 제외
iptables -t nat -A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN  # Envoy 자체 트래픽 제외
iptables -t nat -A ISTIO_OUTPUT -j REDIRECT --to-ports 15001
포트방향용도
15006InboundEnvoy 인바운드 리스너 (외부 → Pod)
15001OutboundEnvoy 아웃바운드 리스너 (Pod → 외부)
15020-헬스 체크 (merged Prometheus telemetry)
15090-Envoy Prometheus telemetry

Infinite loop 방지: UID/GID 1337(istio-proxy 사용자)에서 발생하는 트래픽은 iptables 규칙에서 제외된다. 이를 통해 Envoy가 자신이 생성한 트래픽을 다시 가로채는 무한 루프를 방지한다.

3.4 pilot-agent 역할

pilot-agent는 Envoy 프록시의 라이프사이클을 관리하는 프로세스이다. 사이드카 컨테이너의 ENTRYPOINT로 실행되며, 다음 역할을 수행한다.

  • Envoy 프로세스 관리: 시작, 재시작, 그레이스풀 셧다운
  • 인증서 로테이션: istiod로부터 SDS를 통해 인증서를 수신하고 Envoy에 전달
  • 헬스 체크 프록시: 애플리케이션의 헬스 체크를 Envoy를 통해 노출
  • Bootstrap 설정 생성: Envoy 초기 설정 파일 생성
  • DNS 프록시: .svc.cluster.local 도메인 해석 (Istio DNS Proxy 기능)
graph LR
    subgraph Sidecar_Container["istio-proxy container"]
        PA["pilot-agent<br/>(PID 1)"]
        EP["Envoy Proxy<br/>(child process)"]
    end

    Istiod["istiod"]

    PA -->|"프로세스 관리"| EP
    PA <-->|"SDS (인증서)"| Istiod
    EP <-->|"xDS (설정)"| Istiod
    PA -->|"Bootstrap 생성"| EP

4. xDS Protocol (상세)

xDS(x Discovery Service)는 Envoy와 컨트롤 플레인 간의 통신 프로토콜이다. istiod는 Kubernetes API Server의 리소스 변경을 감지하면 이를 Envoy 설정으로 변환하여 xDS를 통해 push한다.

원문 (Envoy - xDS configuration API overview): “Envoy discovers its various dynamic resources via the filesystem or by querying one or more management servers. Collectively, these discovery services and their corresponding APIs are referred to as xDS.”

번역: Envoy는 파일시스템을 통해서 또는 하나 이상의 관리 서버에 쿼리하여 다양한 동적 리소스를 발견한다. 이러한 디스커버리 서비스와 해당 API를 통칭하여 xDS라고 한다.

4.1 xDS 프로토콜 종류

프로토콜Full Name역할Istio 리소스 매핑
LDSListener Discovery Service리스너 설정 (포트, 프로토콜, 필터 체인)Gateway, Sidecar
RDSRoute Discovery Service라우팅 규칙 (호스트, 경로, 가중치)VirtualService
CDSCluster Discovery Service업스트림 클러스터 (로드밸런싱, 연결 풀)DestinationRule
EDSEndpoint Discovery Service엔드포인트 (Pod IP, 포트, 상태)Kubernetes Endpoints
SDSSecret Discovery ServiceTLS 인증서 (mTLS, 서버 인증서)PeerAuthentication

4.2 xDS Push 흐름

sequenceDiagram
    participant K8s as Kubernetes API Server
    participant Istiod as istiod (Pilot)
    participant Envoy as Envoy Proxy

    K8s->>Istiod: Watch 이벤트<br/>(Service/Endpoint/CRD 변경)
    Istiod->>Istiod: 변경 감지 및<br/>Envoy 설정 변환
    Istiod->>Envoy: CDS push (클러스터 정보)
    Envoy->>Istiod: ACK
    Istiod->>Envoy: EDS push (엔드포인트)
    Envoy->>Istiod: ACK
    Istiod->>Envoy: LDS push (리스너)
    Envoy->>Istiod: ACK
    Istiod->>Envoy: RDS push (라우팅)
    Envoy->>Istiod: ACK

    Note over Istiod,Envoy: SDS는 별도 채널로<br/>인증서 로테이션 시 push

4.3 xDS 디버깅

실제 운영 시 Envoy가 수신한 xDS 설정을 확인하는 것은 트러블슈팅의 핵심이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 특정 Pod의 Envoy 설정 전체 확인
istioctl proxy-config all <pod-name> -n <namespace>

# 리스너 확인 (LDS)
istioctl proxy-config listeners <pod-name> -n <namespace>

# 라우트 확인 (RDS)
istioctl proxy-config routes <pod-name> -n <namespace>

# 클러스터 확인 (CDS)
istioctl proxy-config clusters <pod-name> -n <namespace>

# 엔드포인트 확인 (EDS)
istioctl proxy-config endpoints <pod-name> -n <namespace>

# 시크릿 확인 (SDS)
istioctl proxy-config secret <pod-name> -n <namespace>

# istiod-Envoy 동기화 상태 확인
istioctl proxy-status

5. Traffic Management (공식문서 상세)

원문 (Traffic Management): “Istio’s traffic routing rules let you easily control the flow of traffic and API calls between services. Istio simplifies configuration of service-level properties like circuit breakers, timeouts, and retries, and makes it easy to set up important tasks like A/B testing, canary rollouts, and staged rollouts with percentage-based traffic splits.”

번역: Istio의 트래픽 라우팅 규칙을 사용하면 서비스 간 트래픽 흐름과 API 호출을 쉽게 제어할 수 있다. Istio는 서킷 브레이커, 타임아웃, 재시도와 같은 서비스 레벨 속성 설정을 단순화하고, A/B 테스트, 카나리 롤아웃, 퍼센트 기반 트래픽 분할과 같은 중요한 작업을 쉽게 설정할 수 있게 한다.

Istio의 트래픽 관리는 다음 CRD(Custom Resource Definition)를 통해 이루어진다.

graph TB
    subgraph Traffic_Management_CRDs["Traffic Management CRDs"]
        VS["VirtualService<br/>라우팅 규칙"]
        DR["DestinationRule<br/>목적지 정책"]
        GW["Gateway<br/>인그레스/이그레스"]
        SE["ServiceEntry<br/>외부 서비스 등록"]
        SC["Sidecar<br/>프록시 범위 제한"]
    end

    Client["Client"] --> GW
    GW --> VS
    VS --> DR
    DR --> Service["Kubernetes Service"]
    SE --> DR
    SC -.->|"scope 제한"| VS

5.1 Virtual Services

VirtualService는 Istio 트래픽 라우팅의 핵심 리소스이다. Kubernetes Service로 향하는 트래픽을 어떻게 라우팅할지 정의한다.

원문 (Virtual Service): “A VirtualService defines a set of traffic routing rules to apply when a host is addressed.”

번역: VirtualService는 호스트에 접근할 때 적용할 트래픽 라우팅 규칙 집합을 정의한다.

5.1.1 기본 트래픽 분할 (카나리 배포)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: reviews-route
  namespace: bookinfo
spec:
  hosts:
    - reviews                    # 대상 서비스 호스트명
  http:
    - route:
        - destination:
            host: reviews
            subset: v1           # DestinationRule에서 정의한 subset
          weight: 90             # 90% 트래픽 → v1
        - destination:
            host: reviews
            subset: v2
          weight: 10             # 10% 트래픽 → v2 (카나리)

5.1.2 헤더 기반 라우팅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: reviews-header-route
  namespace: bookinfo
spec:
  hosts:
    - reviews
  http:
    - match:                      # 매칭 조건
        - headers:
            end-user:
              exact: jason        # end-user 헤더가 "jason"이면
      route:
        - destination:
            host: reviews
            subset: v3            # v3로 라우팅 (특정 사용자 테스트)
    - route:                      # 기본 라우팅 (매칭 안 되면)
        - destination:
            host: reviews
            subset: v1

5.1.3 URI 기반 라우팅 + 타임아웃 + 재시도 + 장애 주입

원문 (Traffic Management): “Amount of time that an Envoy proxy should wait for replies from a given service.”

번역: Envoy 프록시가 지정된 서비스의 응답을 기다리는 시간이다.

원문 (Traffic Management): “Maximum number of times an Envoy proxy attempts to connect if initial call fails.”

번역: 초기 호출이 실패했을 때 Envoy 프록시가 연결을 시도하는 최대 횟수이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: ratings-route
  namespace: bookinfo
spec:
  hosts:
    - ratings
  http:
    # 1) /api/v2 경로 → v2 subset (타임아웃 + 재시도)
    - match:
        - uri:
            prefix: /api/v2
          method:
            exact: GET
      route:
        - destination:
            host: ratings
            subset: v2
      timeout: 3s                 # 3초 타임아웃
      retries:
        attempts: 3               # 최대 3회 재시도
        perTryTimeout: 1s         # 재시도당 1초 타임아웃
        retryOn: "5xx,reset,connect-failure,retriable-4xx"

    # 2) 장애 주입 (카오스 테스팅)
    - match:
        - headers:
            x-chaos-test:
              exact: "true"
      fault:
        delay:
          percentage:
            value: 50.0           # 50% 요청에 2초 지연 주입
          fixedDelay: 2s
        abort:
          percentage:
            value: 10.0           # 10% 요청에 500 에러 반환
          httpStatus: 500
      route:
        - destination:
            host: ratings
            subset: v1

    # 3) 기본 라우팅
    - route:
        - destination:
            host: ratings
            subset: v1

5.1.4 Match 조건 전체 목록

필드설명예시
uriURI 경로exact: /api, prefix: /api/v1, regex: /api/v[0-9]+
headersHTTP 헤더exact, prefix, regex
methodHTTP 메서드exact: GET
port포트 번호80
queryParams쿼리 파라미터exact: debug
sourceLabels소스 Pod 라벨app: frontend
sourceNamespace소스 네임스페이스default

5.2 Destination Rules

DestinationRule은 VirtualService가 라우팅한 트래픽이 목적지에 도달한 후 적용되는 정책을 정의한다.

원문 (Destination Rule): “DestinationRule defines policies that apply to traffic intended for a service after routing has occurred.”

번역: DestinationRule은 라우팅이 발생한 후 서비스를 향하는 트래픽에 적용되는 정책을 정의한다.

5.2.1 Subset 정의 + 로드밸런싱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: reviews-destination
  namespace: bookinfo
spec:
  host: reviews                    # 대상 서비스
  trafficPolicy:                   # 기본 트래픽 정책
    loadBalancer:
      simple: LEAST_REQUEST        # 최소 요청 수 기반 로드밸런싱
  subsets:
    - name: v1
      labels:
        version: v1                # version=v1 라벨을 가진 Pod
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN      # v1 subset은 라운드 로빈
    - name: v2
      labels:
        version: v2
    - name: v3
      labels:
        version: v3

5.2.2 로드밸런싱 알고리즘

알고리즘설명적합한 상황
ROUND_ROBIN순차적 분배 (기본값)일반적인 무상태 서비스
LEAST_REQUEST가장 적은 활성 요청을 가진 인스턴스요청 처리 시간이 불균일한 서비스
RANDOM무작위 분배간단한 분산이 필요한 경우
PASSTHROUGH프록시가 로드밸런싱하지 않음클라이언트가 직접 제어
LEAST_CONN최소 연결 수 기반장시간 연결 유지 서비스

5.2.3 연결 풀 + 서킷 브레이커 (Outlier Detection)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: reviews-circuit-breaker
  namespace: bookinfo
spec:
  host: reviews
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100        # 최대 TCP 연결 수
        connectTimeout: 5s         # TCP 연결 타임아웃
      http:
        h2UpgradePolicy: DEFAULT
        http1MaxPendingRequests: 100  # 최대 대기 요청 수
        http2MaxRequests: 1000        # HTTP/2 최대 동시 요청
        maxRequestsPerConnection: 10  # 연결당 최대 요청 수
        maxRetries: 3                 # 최대 재시도 수
    outlierDetection:              # 이상치 감지 (서킷 브레이커)
      consecutive5xxErrors: 5      # 연속 5xx 에러 5회 발생 시
      interval: 10s                # 검사 주기
      baseEjectionTime: 30s        # 최소 제외 시간
      maxEjectionPercent: 50       # 최대 제외 비율 (50%)
      minHealthPercent: 30         # 최소 건강 비율

서킷 브레이커 동작 흐름은 다음과 같다.

stateDiagram-v2
    [*] --> Closed: 정상 상태

    Closed --> Open: 연속 5xx 에러 ≥ 5회
    Open --> HalfOpen: baseEjectionTime(30s) 경과
    HalfOpen --> Closed: 정상 응답 확인
    HalfOpen --> Open: 에러 재발생

    note right of Closed
        모든 트래픽 정상 전달
    end note

    note right of Open
        해당 엔드포인트 제외
        (ejection)
    end note

    note right of HalfOpen
        제한된 트래픽으로
        상태 확인
    end note

5.2.4 TLS 설정 (클라이언트 측)

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: external-tls
spec:
  host: external-api.example.com
  trafficPolicy:
    tls:
      mode: MUTUAL                 # 클라이언트 mTLS
      clientCertificate: /etc/certs/client.pem
      privateKey: /etc/certs/key.pem
      caCertificates: /etc/certs/ca.pem
TLS 모드설명
DISABLETLS 비활성화
SIMPLE단방향 TLS (서버 인증만)
MUTUAL양방향 mTLS (서버 + 클라이언트 인증)
ISTIO_MUTUALIstio가 자동 관리하는 mTLS

5.3 Gateways

Gateway는 메시 경계에서 인바운드/아웃바운드 트래픽을 관리한다.

원문 (Gateways): “Gateways are primarily used to manage ingress traffic, but you can also configure egress gateways.”

번역: Gateway는 주로 인그레스 트래픽을 관리하는 데 사용되지만, 이그레스 게이트웨이도 설정할 수 있다.

5.3.1 Ingress Gateway (North-South 트래픽)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: bookinfo-gateway
  namespace: bookinfo
spec:
  selector:
    istio: ingressgateway           # Istio Ingress Gateway Pod 선택
  servers:
    - port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: SIMPLE                # 단방향 TLS
        credentialName: bookinfo-tls  # Kubernetes Secret 참조
      hosts:
        - "bookinfo.example.com"
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "bookinfo.example.com"
      tls:
        httpsRedirect: true         # HTTP → HTTPS 리다이렉트
---
# Gateway와 연결되는 VirtualService
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: bookinfo-vs
  namespace: bookinfo
spec:
  hosts:
    - "bookinfo.example.com"
  gateways:
    - bookinfo-gateway              # Gateway 참조
  http:
    - match:
        - uri:
            prefix: /productpage
      route:
        - destination:
            host: productpage
            port:
              number: 9080

5.3.2 Egress Gateway (아웃바운드 제어)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: external-egress
  namespace: istio-system
spec:
  selector:
    istio: egressgateway
  servers:
    - port:
        number: 443
        name: tls
        protocol: TLS
      tls:
        mode: PASSTHROUGH
      hosts:
        - "external-api.example.com"
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: external-egress-vs
spec:
  hosts:
    - "external-api.example.com"
  gateways:
    - mesh                          # 메시 내부 트래픽
    - external-egress               # 이그레스 게이트웨이
  tls:
    - match:
        - gateways:
            - mesh
          sniHosts:
            - "external-api.example.com"
      route:
        - destination:
            host: istio-egressgateway.istio-system.svc.cluster.local
            port:
              number: 443
    - match:
        - gateways:
            - external-egress
          sniHosts:
            - "external-api.example.com"
      route:
        - destination:
            host: "external-api.example.com"
            port:
              number: 443

5.4 Service Entries

ServiceEntry는 Istio의 내부 서비스 레지스트리에 외부 서비스를 등록한다. 이를 통해 외부 서비스에도 Istio의 트래픽 관리 기능(재시도, 타임아웃, 장애 주입 등)을 적용할 수 있다.

원문 (Service Entry): “ServiceEntry enables adding additional entries into Istio’s internal service registry, so that auto-discovered services in the mesh can access/route to these manually specified services.”

번역: ServiceEntry는 Istio의 내부 서비스 레지스트리에 추가 항목을 등록하여, 메시에서 자동 발견된 서비스가 수동으로 지정된 서비스에 접근/라우팅할 수 있게 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: external-api
spec:
  hosts:
    - "api.external-service.com"
  location: MESH_EXTERNAL           # 메시 외부 서비스
  ports:
    - number: 443
      name: https
      protocol: TLS
  resolution: DNS                   # DNS 기반 해석
---
# 외부 서비스에 DestinationRule 적용
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: external-api-dr
spec:
  host: "api.external-service.com"
  trafficPolicy:
    tls:
      mode: SIMPLE                  # TLS 활성화
    connectionPool:
      tcp:
        maxConnections: 50
    outlierDetection:
      consecutive5xxErrors: 3
      interval: 30s
      baseEjectionTime: 60s
resolution설명
NONE해석 없음 (IP 직접 사용)
STATICendpoints 필드에 지정된 고정 IP 사용
DNSDNS 조회로 IP 해석
DNS_ROUND_ROBINDNS 결과를 라운드 로빈으로 사용

5.5 Sidecar (프록시 범위 제한)

Sidecar 리소스는 Envoy 프록시가 수신하는 xDS 설정의 범위를 제한한다. 기본적으로 모든 Envoy 프록시는 메시 내 모든 서비스의 설정을 수신하는데, 대규모 클러스터에서는 이것이 메모리와 CPU 오버헤드를 크게 증가시킨다.

원문 (Sidecar): “By default, Istio will program all sidecar proxies in the mesh with the necessary configuration required to reach every workload instance in the mesh, as well as accept traffic on all the ports associated with the workload.”

번역: 기본적으로 Istio는 메시 내 모든 사이드카 프록시에 메시의 모든 워크로드 인스턴스에 도달하는 데 필요한 설정과, 워크로드와 연관된 모든 포트에서 트래픽을 수신하는 설정을 프로그래밍한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
  name: default
  namespace: bookinfo
spec:
  workloadSelector:                # 적용 대상 (없으면 네임스페이스 전체)
    labels:
      app: reviews
  ingress:
    - port:
        number: 9080
        protocol: HTTP
        name: http
      defaultEndpoint: 127.0.0.1:9080  # 앱 컨테이너 포트
  egress:
    - hosts:
        - "./*"                    # 같은 네임스페이스의 모든 서비스
        - "istio-system/*"         # istio-system의 모든 서비스
      port:
        number: 443
        protocol: HTTPS

대규모 클러스터(서비스 1000개 이상)에서는 Sidecar 리소스를 반드시 사용해야 한다. 각 Envoy가 전체 메시의 설정을 보유하면, 서비스 하나 변경 시 수천 개의 프록시에 xDS push가 발생하여 컨트롤 플레인에 부하를 가중시킨다.

5.6 Network Resilience

5.6.1 Timeouts

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: ratings-timeout
spec:
  hosts:
    - ratings
  http:
    - route:
        - destination:
            host: ratings
      timeout: 3s                   # 3초 타임아웃

5.6.2 Retries

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: ratings-retry
spec:
  hosts:
    - ratings
  http:
    - route:
        - destination:
            host: ratings
      retries:
        attempts: 3                 # 최대 3회 재시도
        perTryTimeout: 2s           # 재시도당 2초 타임아웃
        retryOn: "5xx,reset,connect-failure,retriable-4xx"
        retryRemoteLocalities: true # 다른 locality의 엔드포인트로 재시도
retryOn 값설명
5xx5xx 응답 시 재시도
gateway-error502, 503, 504 응답 시 재시도
reset연결 리셋 시 재시도
connect-failure연결 실패 시 재시도
retriable-4xx재시도 가능한 4xx (409 등)
refused-streamREFUSED_STREAM 에러 시 재시도

5.6.3 Circuit Breakers

서킷 브레이커는 DestinationRule의 connectionPooloutlierDetection으로 구성된다. (5.2.3 섹션의 예시 참조)

동작 원리:

  1. connectionPool: 동시 연결 수, 대기 요청 수를 제한하여 과부하 방지
  2. outlierDetection: 비정상 엔드포인트를 감지하여 로드밸런싱 풀에서 일시 제거

5.6.4 Fault Injection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: ratings-fault
spec:
  hosts:
    - ratings
  http:
    - fault:
        delay:
          percentage:
            value: 10.0             # 10% 요청에 지연 주입
          fixedDelay: 5s            # 5초 지연
        abort:
          percentage:
            value: 5.0              # 5% 요청에 에러 주입
          httpStatus: 503           # 503 응답 반환
      route:
        - destination:
            host: ratings
            subset: v1

장애 주입은 애플리케이션의 회복력(resilience)을 테스트하는 카오스 엔지니어링의 핵심 도구이다. 코드 변경 없이 인프라 레벨에서 장애를 시뮬레이션할 수 있다.


6. Security (공식문서 상세)

원문 (Security): “Istio provides every workload with a strong identity–based on the workload’s service account–that is used to establish and verify mutual TLS connections between workloads.”

번역: Istio는 모든 워크로드에 워크로드의 서비스 계정을 기반으로 하는 강력한 ID를 제공하며, 이 ID는 워크로드 간 상호 TLS 연결을 수립하고 검증하는 데 사용된다.

Istio의 보안 모델은 세 가지 축으로 구성된다.

graph TB
    subgraph Security["Istio Security Model"]
        Auth["Authentication<br/>(누구인가?)"]
        Authz["Authorization<br/>(무엇을 할 수 있는가?)"]
        Encrypt["Encryption<br/>(통신이 안전한가?)"]
    end

    Auth --> PeerAuth["PeerAuthentication<br/>(mTLS)"]
    Auth --> ReqAuth["RequestAuthentication<br/>(JWT)"]
    Authz --> AuthzPolicy["AuthorizationPolicy<br/>(ALLOW/DENY/CUSTOM/AUDIT)"]
    Encrypt --> mTLS["자동 mTLS<br/>(SPIFFE X.509)"]

6.1 Authentication (인증)

원문 (Security - Authentication): “Istio provides two types of authentication” Peer authentication: “used for service-to-service authentication to verify the client making the connection.” Request authentication: “Used for end-user authentication to verify the credential attached to the request”

번역: Istio는 두 가지 유형의 인증을 제공한다. Peer 인증은 연결을 생성하는 클라이언트를 검증하는 서비스 간 인증에 사용된다. Request 인증은 요청에 첨부된 자격 증명을 검증하는 최종 사용자 인증에 사용된다.

6.1.1 PeerAuthentication (mTLS 모드)

PeerAuthentication은 워크로드 간 mTLS 통신 정책을 정의한다. Mesh 전체, 네임스페이스, 개별 워크로드 수준으로 설정 가능하다.

원문 (Peer Authentication): “PeerAuthentication defines how traffic will be tunneled (or not) to the sidecar.”

번역: PeerAuthentication은 트래픽이 사이드카로 터널링되는 방식(또는 터널링 여부)을 정의한다.

원문 (Security - Mutual TLS): “Mesh-wide peer authentication policies with an unset mode use the PERMISSIVE mode by default.” “There can be only one mesh-wide peer authentication policy, and only one namespace-wide peer authentication policy per namespace.”

번역: 모드가 설정되지 않은 메시 전체 피어 인증 정책은 기본적으로 PERMISSIVE 모드를 사용한다. 메시 전체 피어 인증 정책은 하나만 존재할 수 있고, 네임스페이스별 피어 인증 정책도 네임스페이스당 하나만 존재할 수 있다.

mTLS 모드설명사용 시점
STRICTmTLS만 허용 (평문 거부)프로덕션 환경 (완전 전환 후)
PERMISSIVEmTLS + 평문 모두 허용마이그레이션 과정 (기본값)
DISABLEmTLS 비활성화특수한 경우 (레거시 연동)
UNSET상위 정책 상속명시적 설정 불필요 시
1
2
3
4
5
6
7
8
9
# 1) Mesh 전체 STRICT mTLS
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system            # istio-system에 설정하면 mesh-wide
spec:
  mtls:
    mode: STRICT
1
2
3
4
5
6
7
8
9
# 2) 네임스페이스 레벨 PERMISSIVE (마이그레이션 중)
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: legacy-namespace
spec:
  mtls:
    mode: PERMISSIVE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 3) 특정 워크로드에만 적용 (포트별 제어)
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: finance-app-strict
  namespace: finance
spec:
  selector:
    matchLabels:
      app: finance-api
  mtls:
    mode: STRICT
  portLevelMtls:
    8080:
      mode: PERMISSIVE              # 8080 포트만 PERMISSIVE

정책 우선순위: workload-specific > namespace-wide > mesh-wide. 더 구체적인 정책이 우선 적용된다.

6.1.2 RequestAuthentication (JWT 검증)

RequestAuthentication은 외부에서 들어오는 요청의 JWT 토큰을 검증한다.

원문 (Request Authentication): “RequestAuthentication defines what request authentication methods are supported by a workload.”

번역: RequestAuthentication은 워크로드가 지원하는 요청 인증 방법을 정의한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
  name: jwt-auth
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: productpage
  jwtRules:
    - issuer: "https://accounts.google.com"
      jwksUri: "https://www.googleapis.com/oauth2/v3/certs"
      fromHeaders:
        - name: Authorization
          prefix: "Bearer "
      fromParams:
        - "access_token"            # 쿼리 파라미터에서도 토큰 추출
      forwardOriginalToken: true    # 원본 토큰을 upstream에 전달
      outputPayloadToHeader: "x-jwt-payload"  # 디코딩된 페이로드를 헤더로 전달

원문 (Security - Request Authentication): “Request authentication policies specify the values needed to validate a JSON Web Token (JWT).” “When requests carry no token, they are accepted by default.”

번역: Request 인증 정책은 JSON Web Token(JWT)을 검증하는 데 필요한 값을 지정한다. 요청에 토큰이 없으면 기본적으로 수락된다.

주의: RequestAuthentication은 JWT가 존재할 때만 검증하고, JWT가 없는 요청은 통과시킨다. JWT 없는 요청을 차단하려면 AuthorizationPolicy를 함께 사용해야 한다.

6.2 Authorization (인가)

6.2.1 AuthorizationPolicy

AuthorizationPolicy는 워크로드에 대한 접근 제어를 정의한다.

원문 (Authorization Policy): “Istio Authorization Policy enables access control on workloads in the mesh.”

번역: Istio Authorization Policy는 메시 내 워크로드에 대한 접근 제어를 활성화한다.

원문 (Security - Authorization): “Istio’s authorization features provide mesh-, namespace-, and workload-wide access control for your workloads in the mesh.” “Each Envoy proxy runs an authorization engine that authorizes requests at runtime.” “You don’t need to explicitly enable Istio’s authorization features; they are available after installation.” “For workloads without authorization policies applied, Istio allows all requests.”

번역: Istio의 인가 기능은 메시 내 워크로드에 대해 메시, 네임스페이스, 워크로드 수준의 접근 제어를 제공한다. 각 Envoy 프록시는 런타임에 요청을 인가하는 인가 엔진을 실행한다. Istio의 인가 기능을 명시적으로 활성화할 필요가 없으며, 설치 후 바로 사용 가능하다. 인가 정책이 적용되지 않은 워크로드에 대해 Istio는 모든 요청을 허용한다.

Action설명
ALLOW조건에 맞으면 허용
DENY조건에 맞으면 거부 (ALLOW보다 우선)
CUSTOM외부 인가 서비스에 위임
AUDIT감사 로그만 기록 (트래픽 영향 없음)

원문 (Security - Authorization): Evaluation order: “CUSTOM, DENY, and then ALLOW.” “The deny policy takes precedence over the allow policy.”

번역: 평가 순서는 CUSTOM, DENY, 그다음 ALLOW이다. deny 정책이 allow 정책보다 우선한다.

정책 평가 순서: CUSTOM > DENY > ALLOW > 암묵적 허용(정책 미설정 시)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1) DENY: 특정 소스 차단
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: deny-untrusted
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: productpage
  action: DENY
  rules:
    - from:
        - source:
            notNamespaces: ["bookinfo", "istio-system"]  # 허용 네임스페이스 외 차단
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 2) ALLOW: 세밀한 접근 제어
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-read
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - "cluster.local/ns/bookinfo/sa/productpage"  # 특정 서비스 어카운트만
            namespaces:
              - "bookinfo"
      to:
        - operation:
            methods: ["GET"]         # GET만 허용
            paths: ["/api/v1/*"]     # 특정 경로만
            ports: ["9080"]
      when:
        - key: request.headers[x-api-version]
          values: ["v1", "v2"]       # 특정 헤더 값 조건
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 3) JWT 기반 인가 (RequestAuthentication과 조합)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: require-jwt
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
    - from:
        - source:
            requestPrincipals: ["https://accounts.google.com/*"]
      when:
        - key: request.auth.claims[groups]
          values: ["admin", "editor"]  # JWT claims의 groups 필드 검증
1
2
3
4
5
6
7
8
# 4) 전체 네임스페이스 기본 거부 (deny-all)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: bookinfo
spec:
  {}                                # 빈 spec = 모든 트래픽 거부

6.2.2 Source 필드 상세

필드설명예시
principalsSPIFFE IDcluster.local/ns/default/sa/my-sa
notPrincipalsSPIFFE ID 제외(위와 동일 형식)
namespaces소스 네임스페이스["bookinfo"]
notNamespaces네임스페이스 제외["untrusted"]
ipBlocks소스 IP 대역["10.0.0.0/8"]
notIpBlocksIP 대역 제외["10.0.1.0/24"]
requestPrincipalsJWT subject["issuer/subject"]
remoteIpBlocks원본 클라이언트 IPX-Forwarded-For 기반

6.3 mTLS 내부 동작

6.3.1 SPIFFE Identity

원문 (Security - Identity): “Identity is a fundamental concept of any security infrastructure.”

번역: ID는 모든 보안 인프라의 근본적인 개념이다.

Istio는 SPIFFE(Secure Production Identity Framework For Everyone) 표준을 따르는 ID를 모든 워크로드에 부여한다.

원문 (SPIFFE): “SPIFFE, the Secure Production Identity Framework for Everyone, is a set of open-source standards for securely identifying software systems in dynamic and heterogeneous environments.”

번역: SPIFFE는 동적이고 이기종 환경에서 소프트웨어 시스템을 안전하게 식별하기 위한 오픈 소스 표준 집합이다.

SPIFFE ID 형식:

1
spiffe://cluster.local/ns/{namespace}/sa/{service-account}

예시:

  • spiffe://cluster.local/ns/bookinfo/sa/productpage - bookinfo 네임스페이스의 productpage 서비스 어카운트
  • spiffe://cluster.local/ns/istio-system/sa/istiod - istiod 자체의 ID

6.3.2 인증서 발급 및 로테이션 흐름

원문 (Security - Certificate Management): “istiod offers a gRPC service to take certificate signing requests (CSRs)” “When a workload is started, Envoy requests the certificate and key from the Istio agent in the same container via the Envoy secret discovery service (SDS) API”

번역: istiod는 인증서 서명 요청(CSR)을 받기 위한 gRPC 서비스를 제공한다. 워크로드가 시작되면, Envoy는 같은 컨테이너에 있는 Istio 에이전트에게 Envoy SDS(Secret Discovery Service) API를 통해 인증서와 키를 요청한다.

sequenceDiagram
    participant App as Application Pod
    participant Agent as pilot-agent
    participant Envoy as Envoy Proxy
    participant Istiod as istiod (Citadel)
    participant K8s as Kubernetes API

    Note over Agent,Istiod: 인증서 초기 발급
    Agent->>Agent: CSR(Certificate Signing Request) 생성
    Agent->>Istiod: SDS 요청 + CSR
    Istiod->>K8s: ServiceAccount 토큰 검증
    K8s->>Istiod: 검증 결과
    Istiod->>Istiod: SPIFFE X.509 인증서 서명
    Istiod->>Agent: 서명된 인증서 + CA 번들
    Agent->>Envoy: SDS로 인증서 전달

    Note over Agent,Istiod: 인증서 자동 로테이션 (기본 24시간)
    loop 만료 전 로테이션
        Agent->>Agent: 새 CSR 생성
        Agent->>Istiod: SDS 갱신 요청
        Istiod->>Agent: 새 인증서 발급
        Agent->>Envoy: Hot reload (연결 중단 없음)
    end

핵심 포인트:

  • 인증서 기본 수명: 24시간 (환경 변수로 조정 가능)
  • 로테이션은 만료 전에 자동 수행되므로 서비스 중단이 없다
  • SDS를 통해 인증서를 메모리에서 직접 전달하므로, 디스크에 인증서를 저장하지 않는다 (보안 강화)

6.3.3 mTLS Handshake 과정

원문 (Security - Mutual TLS): “Istio tunnels service-to-service communication through the client- and server-side PEPs, which are implemented as Envoy proxies.” “secure naming check to verify that the service account presented in the server certificate is authorized to run the target service.” “Istio configures TLSv1_2 as the minimum TLS version.” “Istio mutual TLS has a permissive mode, which allows a service to accept both plaintext traffic and mutual TLS traffic at the same time.”

번역: Istio는 Envoy 프록시로 구현된 클라이언트 및 서버 측 PEP를 통해 서비스 간 통신을 터널링한다. 보안 명명 검사를 통해 서버 인증서에 제시된 서비스 어카운트가 대상 서비스를 실행할 권한이 있는지 검증한다. Istio는 TLSv1_2를 최소 TLS 버전으로 설정한다. Istio mTLS에는 permissive 모드가 있어 서비스가 평문 트래픽과 mTLS 트래픽을 동시에 수신할 수 있다.

sequenceDiagram
    participant ClientApp as Client App
    participant ClientProxy as Client Envoy
    participant ServerProxy as Server Envoy
    participant ServerApp as Server App

    ClientApp->>ClientProxy: 평문 HTTP 요청<br/>(localhost → 15001)
    ClientProxy->>ClientProxy: 목적지 확인 (xDS)<br/>mTLS 정책 확인

    Note over ClientProxy,ServerProxy: TLS Handshake
    ClientProxy->>ServerProxy: ClientHello + SPIFFE ID
    ServerProxy->>ClientProxy: ServerHello + SPIFFE 인증서
    ClientProxy->>ClientProxy: 서버 인증서 검증<br/>(CA 체인 + SPIFFE ID)
    ClientProxy->>ServerProxy: 클라이언트 인증서 전송
    ServerProxy->>ServerProxy: 클라이언트 인증서 검증<br/>(CA 체인 + SPIFFE ID)
    Note over ClientProxy,ServerProxy: 암호화 채널 수립 완료

    ClientProxy->>ServerProxy: 암호화된 요청
    ServerProxy->>ServerApp: 평문 HTTP 요청<br/>(15006 → localhost)
    ServerApp->>ServerProxy: 평문 HTTP 응답
    ServerProxy->>ClientProxy: 암호화된 응답
    ClientProxy->>ClientApp: 평문 HTTP 응답

7. Observability (공식문서 상세)

원문 (Observability): “Istio generates detailed telemetry for all communications within a service mesh. This telemetry provides observability of service mesh behavior, empowering operators to troubleshoot, maintain, and optimize their applications.”

번역: Istio는 Service Mesh 내 모든 통신에 대한 상세한 텔레메트리를 생성한다. 이 텔레메트리는 Service Mesh 동작에 대한 관측성을 제공하여, 운영자가 애플리케이션을 트러블슈팅하고 유지 관리하고 최적화할 수 있게 한다.

Istio의 관측성은 코드 변경 없이 프록시 레벨에서 자동으로 수집된다. 이것이 Service Mesh의 가장 큰 장점 중 하나이다.

7.1 Metrics

원문 (Observability - Metrics): “Metrics provide a way of monitoring and understanding behavior in aggregate.”

번역: 메트릭은 동작을 집계 수준에서 모니터링하고 이해하는 방법을 제공한다.

원문 (Istio Standard Metrics): “Istio generates metrics based on the four ‘golden signals’ of monitoring – latency, traffic, errors, and saturation.”

번역: Istio는 모니터링의 4가지 “골든 시그널” – 지연 시간, 트래픽, 에러, 포화도 – 에 기반한 메트릭을 생성한다.

7.1.1 Proxy-level Metrics (Envoy Stats)

Envoy는 자체적으로 수백 개의 메트릭을 노출한다. 주요 메트릭은 다음과 같다.

메트릭설명
envoy_cluster_upstream_cx_active활성 업스트림 연결 수
envoy_cluster_upstream_cx_total총 업스트림 연결 수
envoy_cluster_upstream_rq_total총 업스트림 요청 수
envoy_cluster_upstream_rq_timeout타임아웃 요청 수
envoy_cluster_upstream_rq_retry재시도 횟수
envoy_server_memory_allocatedEnvoy 메모리 사용량

7.1.2 Service-level Metrics (Istio 표준)

Istio가 생성하는 표준 메트릭은 모든 서비스 통신에 대해 자동으로 수집된다.

메트릭설명라벨
istio_requests_total총 요청 수source, destination, response_code
istio_request_duration_milliseconds요청 지연 시간source, destination (histogram)
istio_request_bytes요청 바이트 수source, destination (histogram)
istio_response_bytes응답 바이트 수source, destination (histogram)
istio_tcp_connections_opened_totalTCP 연결 수립source, destination
istio_tcp_connections_closed_totalTCP 연결 종료source, destination
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Istio Telemetry API로 메트릭 커스터마이징
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: custom-metrics
  namespace: bookinfo
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - match:
            metric: REQUEST_COUNT
            mode: CLIENT_AND_SERVER
          tagOverrides:
            request_host:
              operation: UPSERT
              value: "request.host"

7.1.3 Control Plane Metrics

istiod 자체도 다음 메트릭을 노출한다.

메트릭설명
pilot_xds_pushesxDS push 횟수 (type별)
pilot_proxy_convergence_time프록시 설정 수렴 시간
pilot_conflict_inbound_listener인바운드 리스너 충돌
pilot_conflict_outbound_listener_tcp_over_current_tcp아웃바운드 리스너 충돌
citadel_server_csr_countCSR 처리 횟수
galley_validation_failed설정 검증 실패

7.2 Distributed Tracing

원문 (Observability - Distributed Tracing): “Distributed tracing provides a way to monitor and understand behavior by monitoring individual requests as they flow through a mesh.”

번역: 분산 추적은 개별 요청이 메시를 통과할 때 이를 모니터링하여 동작을 모니터링하고 이해하는 방법을 제공한다.

원문 (Distributed Tracing): “Distributed tracing enables users to track a request through mesh that is distributed across multiple services.”

번역: 분산 추적은 사용자가 여러 서비스에 분산된 메시를 통과하는 요청을 추적할 수 있게 한다.

Istio는 Envoy 프록시에서 자동으로 스팬(span)을 생성한다. 그러나 분산 추적이 정상적으로 동작하려면 애플리케이션이 트레이스 컨텍스트 헤더를 전파(propagation)해야 한다. 이는 Istio가 해결할 수 없는 애플리케이션 책임이다.

7.2.1 전파해야 하는 헤더

헤더설명형식
x-request-idEnvoy 생성 요청 IDUUID
x-b3-traceidZipkin B3 트레이스 ID64/128-bit hex
x-b3-spanidZipkin B3 스팬 ID64-bit hex
x-b3-parentspanid부모 스팬 ID64-bit hex
x-b3-sampled샘플링 여부0 or 1
x-b3-flags디버그 플래그0 or 1
b3B3 단일 헤더 형식{traceid}-{spanid}-{sampled}-{parentspanid}
traceparentW3C Trace Context{version}-{trace-id}-{parent-id}-{trace-flags}
tracestateW3C Trace State벤더별 추가 정보
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Python Flask 예시: 트레이스 헤더 전파
from flask import Flask, request
import requests

app = Flask(__name__)

# 전파해야 하는 헤더 목록
TRACE_HEADERS = [
    'x-request-id',
    'x-b3-traceid',
    'x-b3-spanid',
    'x-b3-parentspanid',
    'x-b3-sampled',
    'x-b3-flags',
    'b3',
    'traceparent',
    'tracestate',
]

@app.route('/api/v1/products')
def get_products():
    # 인바운드 요청에서 트레이스 헤더 추출
    headers = {}
    for header in TRACE_HEADERS:
        value = request.headers.get(header)
        if value:
            headers[header] = value

    # 다운스트림 서비스 호출 시 헤더 전파
    reviews = requests.get(
        'http://reviews:9080/api/v1/reviews',
        headers=headers  # 트레이스 헤더 포함
    )
    return reviews.json()

7.2.2 트레이싱 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Telemetry API로 트레이싱 설정
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: tracing-config
  namespace: istio-system
spec:
  tracing:
    - providers:
        - name: zipkin              # 또는 jaeger, opentelemetry
      randomSamplingPercentage: 1.0 # 1% 샘플링 (프로덕션 권장)
      customTags:
        environment:
          literal:
            value: "production"

7.3 Access Logs

원문 (Observability - Access Logs): “Access logs provide a way to monitor and understand behavior from the perspective of an individual workload instance.”

번역: 액세스 로그는 개별 워크로드 인스턴스의 관점에서 동작을 모니터링하고 이해하는 방법을 제공한다.

Envoy 액세스 로그는 모든 요청/응답의 상세 정보를 기록한다.

원문 (Envoy Access Logging): “Envoy proxies can be configured to provide access logs containing information about requests.”

번역: Envoy 프록시는 요청 정보를 포함하는 액세스 로그를 제공하도록 설정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
# Telemetry API로 액세스 로그 설정
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: access-log
  namespace: istio-system
spec:
  accessLogging:
    - providers:
        - name: envoy
      filter:
        expression: "response.code >= 400"  # 4xx, 5xx만 로깅
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# MeshConfig로 글로벌 액세스 로그 설정 (IstioOperator)
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    accessLogFile: /dev/stdout
    accessLogEncoding: JSON
    accessLogFormat: |
      {
        "protocol": "%PROTOCOL%",
        "upstream_service_time": "%REQ(x-envoy-upstream-service-time)%",
        "upstream_cluster": "%UPSTREAM_CLUSTER%",
        "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%",
        "requested_server_name": "%REQUESTED_SERVER_NAME%",
        "route_name": "%ROUTE_NAME%",
        "response_code": "%RESPONSE_CODE%",
        "response_flags": "%RESPONSE_FLAGS%",
        "bytes_sent": "%BYTES_SENT%",
        "duration": "%DURATION%",
        "authority": "%REQ(:AUTHORITY)%",
        "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
        "method": "%REQ(:METHOD)%",
        "user_agent": "%REQ(USER-AGENT)%"
      }

주요 RESPONSE_FLAGS 값:

Flag설명
UHUpstream Healthy 없음 (no healthy upstream)
UFUpstream 연결 실패
UOUpstream Overflow (서킷 브레이커)
NRNo Route (라우팅 규칙 없음)
URXUpstream 재시도 한도 초과
DCDownstream 연결 종료
LHLocal Health Check 실패
UTUpstream 타임아웃
RLRate Limited
UAEXUnauthorized External (인가 실패)

7.4 Observability 스택 통합 아키텍처

graph TB
    subgraph Workloads["Workloads"]
        Pod1["Pod + Envoy"]
        Pod2["Pod + Envoy"]
        Pod3["Pod + Envoy"]
    end

    subgraph Observability["Observability Stack"]
        Prometheus["Prometheus<br/>(메트릭 수집)"]
        Grafana["Grafana<br/>(대시보드)"]
        Jaeger["Jaeger/Tempo<br/>(분산 추적)"]
        Loki["Loki<br/>(로그 집계)"]
        Kiali["Kiali<br/>(서비스 토폴로지)"]
    end

    Pod1 -->|"메트릭 (15090)"| Prometheus
    Pod2 -->|"메트릭 (15090)"| Prometheus
    Pod3 -->|"메트릭 (15090)"| Prometheus
    Pod1 -->|"스팬"| Jaeger
    Pod2 -->|"스팬"| Jaeger
    Pod1 -->|"액세스 로그"| Loki
    Pod2 -->|"액세스 로그"| Loki

    Prometheus --> Grafana
    Prometheus --> Kiali
    Jaeger --> Kiali

8. 왜 사용하는가

Istio Sidecar 모드를 도입하는 핵심 이유를 정리한다.

1) 애플리케이션 코드 수정 없이 트래픽/보안 정책 중앙 관리

각 서비스가 재시도, 타임아웃, 서킷 브레이커, TLS 등을 개별 구현하면 코드 중복과 불일치가 발생한다. Istio는 이를 인프라 레벨로 추출하여 CRD 기반으로 선언적 관리가 가능하게 한다.

2) 카나리/블루그린/트래픽 분할 배포 전략

VirtualService의 weight 기반 라우팅으로 코드 변경 없이 카나리 배포를 구현할 수 있다. 배포 파이프라인에서 weight 값만 조정하면 된다.

3) 서비스 간 통신 가시성과 제어력 확보

마이크로서비스 아키텍처에서 서비스 간 호출 관계는 빠르게 복잡해진다. Istio는 모든 트래픽을 프록시가 중재하므로, 코드 계측(instrumentation) 없이도 트래픽 흐름, 지연 시간, 에러율을 자동으로 수집한다.

4) Zero-trust security 구현

기존의 경계 기반 보안(perimeter security)은 내부 네트워크를 신뢰하는 모델이다. Istio의 mTLS와 AuthorizationPolicy를 사용하면, 서비스 간 통신도 인증/인가/암호화가 적용되는 제로 트러스트 모델을 구현할 수 있다.

5) Observability 표준화

서비스별로 다른 모니터링 라이브러리와 설정을 사용하는 대신, Envoy 프록시가 일관된 형식의 메트릭, 로그, 트레이스를 자동 생성한다.


9. 사용하지 않으면 어떻게 되는가

Service Mesh 없이 마이크로서비스를 운영하면 다음과 같은 문제가 발생한다.

1) 각 서비스가 재시도/타임아웃/회로차단/암호화를 중복 구현

서비스 A는 Go의 go-retryablehttp, 서비스 B는 Java의 Resilience4j, 서비스 C는 Python의 tenacity를 사용하는 식이다. 동일한 정책이 언어별로 다르게 구현되고, 설정 변경 시 모든 서비스를 개별 배포해야 한다.

2) 보안/접근 정책이 팀별 파편화, 거버넌스 난이도 상승

팀 A는 mTLS를 적용했지만, 팀 B는 평문 통신이고, 팀 C는 자체 인증 방식을 사용한다. 조직 전체에 일관된 보안 정책을 적용하기 어렵고, 감사(audit)도 서비스별로 별도 수행해야 한다.

3) 장애 분석 시 서비스 간 트래픽 흐름 추적 어려움

서비스 A → B → C → D 체인에서 장애가 발생하면, 각 서비스의 로그를 수동으로 상관관계(correlation)시켜야 한다. 분산 추적이 없으면 근본 원인(root cause) 분석에 시간이 기하급수적으로 증가한다.

4) mTLS 개별 구현 부담

인증서 발급, 갱신, 배포, 서비스 간 인증서 검증을 서비스별로 구현하면 운영 복잡도가 크게 증가한다. 인증서 만료로 인한 장애도 빈번해진다.


10. 대체 기술 비교

항목Istio SidecarLinkerdConsul ConnectKuma
프록시Envoy (C++)linkerd2-proxy (Rust)Envoy / built-inEnvoy
기능 폭매우 넓음핵심 기능 중심멀티런타임 (K8s + VM)중간
운영 복잡도중~상낮음
트래픽 정책매우 풍부 (VirtualService, DestinationRule, Gateway)핵심 (TrafficSplit, HTTPRoute)풍부 (Intentions, Service Router)중간
보안mTLS + AuthorizationPolicy + JWTmTLS + Server AuthorizationmTLS + IntentionsmTLS + TrafficPermission
학습 곡선가파름완만중간중간
리소스 오버헤드높음 (~50-100m CPU, ~100-200Mi memory per sidecar)낮음 (~10m CPU, ~20Mi memory)중간중간
CNCFGraduatedGraduated- (HashiCorp)Sandbox (→ Graduated 준비 중)
멀티클러스터지원 (Federation, Multi-primary)지원 (Multi-cluster)지원 (WAN Federation)지원 (Multi-zone)
VM 지원지원 (WorkloadEntry)미지원지원 (네이티브)지원 (Universal mode)

선택 기준 요약:

  • Istio: 기능이 가장 풍부하고 세밀한 제어가 필요한 대규모 프로덕션. 학습 비용을 감수할 수 있는 팀
  • Linkerd: 빠른 도입, 낮은 리소스 오버헤드, 핵심 기능만 필요한 경우. CNCF Graduated로 커뮤니티 안정적
  • Consul Connect: Kubernetes + VM 하이브리드 환경. HashiCorp 에코시스템(Vault, Nomad) 사용 시
  • Kuma: Envoy 기반이지만 Istio보다 간단한 설정을 원하는 경우. 멀티존 아키텍처

11. 활용 시 주의점

11.1 사이드카 리소스 오버헤드

모든 Pod에 Envoy 프록시가 추가되므로 클러스터 전체의 리소스 사용량이 증가한다.

항목기본값프로덕션 권장
CPU Request100m서비스 트래픽에 따라 조정
CPU Limit2000m500m ~ 1000m
Memory Request128Mi서비스 엔드포인트 수에 따라 조정
Memory Limit1Gi256Mi ~ 512Mi
1
2
3
4
5
6
7
8
9
10
11
12
13
# 사이드카 리소스 제한 (annotation)
apiVersion: v1
kind: Pod
metadata:
  annotations:
    sidecar.istio.io/proxyCPU: "100m"
    sidecar.istio.io/proxyCPULimit: "500m"
    sidecar.istio.io/proxyMemory: "128Mi"
    sidecar.istio.io/proxyMemoryLimit: "256Mi"
spec:
  containers:
    - name: app
      image: app:v1

11.2 정책 기본값 설계

프로덕션 환경에서는 “기본 거부(deny by default)” 원칙을 적용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Step 1: Mesh-wide STRICT mTLS
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
---
# Step 2: Namespace deny-all
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  {}
---
# Step 3: 필요한 통신만 ALLOW
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  selector:
    matchLabels:
      app: backend
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/frontend"]
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/*"]

11.3 앱 장애 vs 메시 장애 분리 관찰

트래픽이 프록시를 경유하므로, 장애 발생 시 원인이 애플리케이션인지 Envoy/istiod인지 구분이 필요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1) 프록시 상태 확인
istioctl proxy-status

# 2) 특정 Pod의 Envoy 설정 동기화 상태
istioctl analyze -n <namespace>

# 3) Envoy 내부 통계 직접 확인
kubectl exec <pod> -c istio-proxy -- pilot-agent request GET /stats

# 4) istiod 로그 확인 (push 실패 등)
kubectl logs -n istio-system -l app=istiod --tail=100

# 5) 프록시 로그 레벨 변경 (디버깅)
istioctl proxy-config log <pod> --level debug

11.4 Envoy 버전 호환성 확인

Istio 버전과 Envoy 버전의 호환성을 반드시 확인해야 한다. Istio는 특정 Envoy 버전과 함께 빌드/테스트되므로, 임의로 Envoy 버전을 변경하면 예기치 않은 동작이 발생할 수 있다.

1
2
3
4
5
# 현재 사용 중인 Envoy 버전 확인
istioctl version

# Pod별 Envoy 버전 확인
kubectl exec <pod> -c istio-proxy -- envoy --version

11.5 Large-scale 환경에서 xDS Push 최적화

서비스 수가 많은 클러스터에서는 Sidecar 리소스로 각 프록시의 xDS 범위를 제한해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
# 네임스페이스 기본 Sidecar (모든 Pod에 적용)
apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
  name: default
  namespace: bookinfo
spec:
  egress:
    - hosts:
        - "./*"                     # 같은 네임스페이스
        - "istio-system/*"          # istio-system
        - "monitoring/*"            # 모니터링
      # 전체 메시 대신 필요한 네임스페이스만 포함

xDS push 최적화 효과:

  • 메모리: 전체 메시 설정 대신 관련 서비스 설정만 보유 (수십 배 절감 가능)
  • CPU: 설정 변경 시 영향받는 프록시만 push
  • 네트워크: xDS 트래픽 감소

11.6 업그레이드 전략 (Canary Revision)

Istio 업그레이드는 canary revision을 사용하여 점진적으로 수행한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1) 새 revision 설치
istioctl install --set revision=1-22-0

# 2) 네임스페이스에 새 revision label 적용
kubectl label namespace bookinfo istio.io/rev=1-22-0 --overwrite
# 기존 istio-injection=enabled label 제거
kubectl label namespace bookinfo istio-injection-

# 3) 워크로드 재시작 (새 사이드카 주입)
kubectl rollout restart deployment -n bookinfo

# 4) 검증 후 이전 revision 제거
istioctl uninstall --revision 1-21-0
graph LR
    subgraph Before["업그레이드 전"]
        Old["istiod 1.21<br/>(stable)"]
        PodOld1["Pod (1.21 sidecar)"]
        PodOld2["Pod (1.21 sidecar)"]
    end

    subgraph During["Canary 진행 중"]
        OldD["istiod 1.21<br/>(stable)"]
        NewD["istiod 1.22<br/>(canary)"]
        PodD1["Pod (1.21 sidecar)"]
        PodD2["Pod (1.22 sidecar)"]
    end

    subgraph After["업그레이드 완료"]
        New["istiod 1.22<br/>(stable)"]
        PodNew1["Pod (1.22 sidecar)"]
        PodNew2["Pod (1.22 sidecar)"]
    end

    Before --> During --> After

12. 부수 개념

12.1 xDS (x Discovery Service)

원문 (Envoy - xDS Protocol): “The xDS API provides a way for Envoy to dynamically discover configuration.”

번역: xDS API는 Envoy가 설정을 동적으로 발견하는 방법을 제공한다.

xDS는 Envoy의 동적 설정 프로토콜의 총칭이다. ‘x’는 L(Listener), R(Route), C(Cluster), E(Endpoint), S(Secret) 등 다양한 디스커버리 서비스를 의미한다. gRPC 양방향 스트림 기반으로 동작하며, Envoy와 컨트롤 플레인 간 실시간 설정 동기화를 담당한다.

12.2 SPIFFE / SPIRE

원문 (SPIFFE Concepts): “SPIFFE provides a secure identity, in the form of a specially crafted X.509 certificate, to every workload in a modern, dynamic infrastructure.”

번역: SPIFFE는 현대적이고 동적인 인프라의 모든 워크로드에 특별히 제작된 X.509 인증서 형태의 보안 ID를 제공한다.

  • SPIFFE: ID 표준 (spiffe://trust-domain/path 형식)
  • SPIRE: SPIFFE 구현체 (identity attestation, certificate issuance)
  • Istio는 자체 Citadel에서 SPIFFE 호환 인증서를 발급하며, SPIRE와도 통합 가능하다

12.3 Envoy Filter

EnvoyFilter는 istiod가 생성하는 Envoy 설정을 직접 패치하는 고급 CRD이다. VirtualService나 DestinationRule로 표현할 수 없는 Envoy 네이티브 설정을 적용할 때 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-lua-filter
  namespace: bookinfo
spec:
  workloadSelector:
    labels:
      app: productpage
  configPatches:
    - 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.lua
          typed_config:
            "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
            inlineCode: |
              function envoy_on_request(handle)
                handle:headers():add("x-custom-header", "added-by-envoy")
              end

주의: EnvoyFilter는 Istio 버전 업그레이드 시 호환성이 깨질 수 있으므로, 가능하면 VirtualService/DestinationRule 등 상위 API를 우선 사용해야 한다.

12.4 WebAssembly Plugin

원문 (Wasm Plugin): “WasmPlugins provides a mechanism to extend the functionality provided by the Istio proxy through WebAssembly filters.”

번역: WasmPlugin은 WebAssembly 필터를 통해 Istio 프록시의 기능을 확장하는 메커니즘을 제공한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: custom-auth
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: productpage
  url: oci://ghcr.io/my-org/custom-auth-wasm:v1.0
  phase: AUTHN                      # 인증 단계에서 실행
  pluginConfig:
    api_key_header: "x-api-key"

WebAssembly 플러그인의 장점:

  • EnvoyFilter보다 안전한 확장 방식 (샌드박스 실행)
  • 다양한 언어로 작성 가능 (Rust, Go, C++ 등 → Wasm 컴파일)
  • OCI 레지스트리에서 배포 가능
  • Hot reload 지원

12.5 Istio CNI

원문 (Install Istio with the Istio CNI plugin): “The Istio CNI plugin removes the requirement for the istio-init containers.”

번역: Istio CNI 플러그인은 istio-init 컨테이너의 필요성을 제거한다.

istio-init container는 iptables 규칙을 설정하기 위해 NET_ADMINNET_RAW capability가 필요하다. 보안 정책이 엄격한 환경(PodSecurityPolicy, PSA restricted)에서는 이것이 문제가 된다. Istio CNI 플러그인은 노드 레벨에서 네트워크 규칙을 설정하므로 init container가 불필요해진다.

12.6 Multi-cluster Mesh

원문 (Multicluster Installation): “Istio can be configured to span multiple clusters.”

번역: Istio는 여러 클러스터에 걸쳐 설정할 수 있다.

모델설명적합한 상황
Multi-primary각 클러스터에 istiod, 상호 설정 공유HA, 지역 분산
Primary-remote한 클러스터에만 istiod, 나머지는 remote중앙 관리, 허브-스포크
External Control Plane외부에 istiod, 모든 클러스터가 remote관리형 서비스, SaaS

13. 실무 체크리스트

Istio Sidecar 모드를 프로덕션에 도입할 때 점검해야 할 항목을 정리한다.

설치 및 초기 설정

  • Istio 프로파일 선택 (demo, default, minimal, ambient)
  • istiod 리소스 설정 (CPU/Memory request/limit)
  • Ingress Gateway 배포 및 LoadBalancer/NodePort 설정
  • Istio CNI 사용 여부 결정 (보안 요구사항에 따라)
  • 네임스페이스 라벨링 전략 수립 (istio-injection=enabled 또는 revision label)

트래픽 관리

  • VirtualService/DestinationRule 기본 템플릿 작성
  • 타임아웃 기본값 설정 (서비스별 SLA 기반)
  • 재시도 정책 설정 (idempotent 요청만 재시도)
  • 서킷 브레이커 임계값 설정 (connectionPool, outlierDetection)
  • Sidecar 리소스로 xDS scope 제한 (서비스 50개 이상일 때)
  • ServiceEntry로 외부 서비스 명시적 등록

보안

  • PeerAuthentication mesh-wide STRICT 적용
  • AuthorizationPolicy deny-all 기본 정책 적용
  • 필요한 통신 경로만 ALLOW 정책 추가
  • RequestAuthentication 설정 (외부 API 엔드포인트)
  • 인증서 로테이션 주기 확인 (기본 24시간)

Observability

  • Prometheus 메트릭 수집 설정
  • Grafana Istio 대시보드 배포
  • 분산 추적 백엔드 설정 (Jaeger, Tempo, Zipkin)
  • 애플리케이션 트레이스 헤더 전파 구현
  • 액세스 로그 설정 (에러만 로깅 또는 전체)
  • Kiali 서비스 토폴로지 대시보드 배포

리소스 및 성능

  • 사이드카 리소스 제한 설정 (annotation 또는 global)
  • 사이드카 제외 대상 설정 (DaemonSet, batch Job 등)
  • HPA 설정 시 사이드카 리소스 고려
  • 프록시 동시성(concurrency) 설정 (기본 2 worker threads)

운영

  • Canary revision 기반 업그레이드 절차 수립
  • istioctl analyze 기반 설정 검증 자동화
  • istioctl proxy-status 모니터링 (SYNCED 상태 확인)
  • istiod HA 구성 (replicas >= 2)
  • Envoy 드레인 타임아웃 설정 (graceful shutdown)
  • 장애 시 사이드카 바이패스 절차 문서화

참고 문서

This post is licensed under CC BY 4.0 by the author.