CloudNet@ 가시다님이 진행하는 Istio In Action 책 기반 Hands-on Study
Chap.3 Istio의 Data Plane Envoy Proxy
학습 과제
- 1.Istio안에서의 Envoy 동작 이해
- 2.Envoy 기능 살펴보기
- 3.Envoy 실습 및 디버깅 하기
1. Istio안에서의 Envoy 동작 이해
Proxy 란 ?
클라이언트와 서버 간 통신하는 과정 중 중간에 위치한 네트워크 중계요소입니다.
flowchart LR
A["클라이언트 (사용자)"] -->|요청| B["프록시 서버"]
B -->|요청 전달| C["목적지 서버"]
C -->|응답| B
B -->|응답 전달| A
Figure 1.1 Proxy 개념 설명
Proxy의 필요성
- 클라이언트가 서버와 통신 할 때
진입점
만 알고도 통신을 하게 해줄 수 있게 해줍니다.
flowchart LR
Client["클라이언트"] -->|요청| ReverseProxy["리버스 프록시"]
ReverseProxy -->|요청 전달| Server1["서버1"]
ReverseProxy -->|요청 전달| Server2["서버2"]
Server1 -->|응답| ReverseProxy
Server2 -->|응답| ReverseProxy
ReverseProxy -->|응답 전달| Client
Figure 1.2 ReverseProxy 설명
- Reverse Proxy설명을 통해 클라이언트는
리버스 프록시
의 주소만 알고 있어도 통신해야하는 서버거 어떤 서버인지 알 필요가 없습니다.
Envoy Proxy란 ?
- 분산 시스템 구축 시 발생하는
Application Network
문제를 해결하고자 도입된 오픈소스 프로젝트Proxy
입니다. - 리프트 사가 개발 했으며 C++ 으로 작성됐습니다.
- 2가지 원칙을 기준으로 개발 됐습니다.
- 네트워크는
투명
해야 한다. - 문제 발생 시
원인 파악
이 쉬워야 한다.
- 네트워크는
Envoy Proxy
는 일반적인 Proxy와 다르게Serivce Discovery
,Load Balancing
,Health Check
같은 추가 기능을 지원합니다.
Envoy Proxy의 특징
- 언어, 프레임워크와 무관하게 모든 Application이 사용할 수 있는 Proxy입니다.
- Request TimeOut, Retry, RetryTimeout, Circuit Breaker 와 같은 Application의 복원력을 위한 기능도 사용 가능합니다.
- Application 수준의 프로토콜도 이해할 수 있어, Application과 Envoy Proxy간의 요청/응답 정보를 수집할 수 있습니다.
- 해당 정보를 토대로 Application의 처리량, 오류율과 같은 지표를 얻을 수 있습니다.
- 다양한
프로토콜
을 지원합니다
Figure 1.3 Envoy가 지원하는 프로토콜 목록
Istio에서의 Envoy Prox 동작
flowchart LR
subgraph DownStream
Client["클라이언트"]
end
subgraph Cluster Edge
EdgeProxy["Edge Proxy (IngressGateway)"]
end
subgraph Istio Service Mesh
direction LR
subgraph ServiceA["서비스 A"]
AppA["애플리케이션 A"]
EnvoyA["Envoy Proxy (사이드카)"]
end
subgraph ServiceB["서비스 B"]
AppB["애플리케이션 B"]
EnvoyB["Envoy Proxy (사이드카)"]
end
end
subgraph Istio Control Plane
Istiod["istiod"]
end
Client -->|"외부 요청(Down Stream)"| EdgeProxy
EdgeProxy -->|Mesh 내부 트래픽| EnvoyA
EnvoyA -->|서비스 간 통신| EnvoyB
EnvoyA <-->|UpStream| AppA
EnvoyB <-->|UpStream| AppB
Istiod -.->|구성 및 정책 전달| EdgeProxy
Istiod -.->|구성 및 정책 전달| EnvoyA
Istiod -.->|구성 및 정책 전달| EnvoyB
Figure 1.3 Istio에서의 Envoy Proxy가 동작하는 프로세스
Envoy의 핵심 기능
Listener
Application
을 외부로 노출시키는 기능이며 해당 프로세스에서 Edge Proxy에 해당합니다.
Root
Listener
로 들어온 트래픽을 처리(라우팅)하는 기능이며 해당 프로세스에서Mesh 내부 트래픽
에 해당합니다.
Cluster
Root
가 라우팅을 하는 대상의Envoy Proxy
를 뜻합니다.해당 프로세스에서사이드 카
에 해당합니다.
Service Discovery
- 기존
Application Library
수준에서 제공하는 기능과 다르게, Envoy가 단순하게 End Point만 찾아가게 설멍 하면 간편하게 적용할 수 있습니다.Service Discovery
에 대한 정보는Control Plane
이 가지고 있기 때문에Control Plane
수준에서 적용하면 관리가 편해집니다.
Load Balancing
- Envoy는 Application에서 활용할 수 있는 고급 Load Balancing 알고리즘을 제공합니다.
- Figure 1.4 Envoy Proxy가 제공 하는 LB 알고리즘(Maglev(Sticky Session))*
트래픽 및 요청 기반 라우팅
- Envoy는 다양한 Application 프로토콜(HTTP/ gRPC etc....)을 사용할 수 있어
프로토콜 기반 라우팅
도 지원합니다. - 기본적인 Context-Path 기반 라우팅 뿐만 아니라,
헤더 및, 가중치 기반 라우팅
,Retry, Timeout, Fault Injection
같은 고급 기능들을 지원합니다.
Shadowing 기능 제공
flowchart LR
Client["클라이언트"] -->|실제 요청| Envoy["Envoy 프록시"]
Envoy -->|실제 트래픽| Service["원본 서비스"]
Envoy -. "Shadow(미러링) 요청".-> ShadowService["Shadow(테스트) 서비스"]
Figure 1.5 Shadowing 기능 설명 도표
Shadowing 기능이란 ?
- 실제 트래픽을 테스트 서비스에 같이 배포를 하여 테스트를 할 수 있는 기능을 말합니다.
네트워크 복원력
Retry
,Retry Timeout
과 같은 설정으로 Application의 복원력을 어느정도 해결 할 수 있지만, 해당 기능의 설정은 전반적으로Application의 책임
입입니다.- UpStream Cluster 호출 시 진행 주인 Connection or Request의 갯수를 제한 할 수 있고, 임계치를 넘어가면 Fail처리하도록 지정할 수 있습니다.
Outlier Filter
적용하여 문제를 일으키는 EndPoint를 LB풀에서 제거할 수 있습니다.
메트릭 수집을 통한 관찰 가능성
- Envoy는 네트워크를 이해하기 위한 다양한 메트릭을 수집합니다.
Figure 1.6 Envoy가 수집가능한 메트릭 정보
분산 트레이싱을 통한 관찰 가능성
Trace Span
정보를OpenTracing Engine(zipkin, jaeger, tempo...)
에 전달하여 트래픽 흐름, 홉, 지연 시간과 같은 정보르를 시각화 할 수 있습니다.- 별도의 라이브러리가 필요하지 않으며, Header를 통해 구현할 수 있습니다.
- 서비스 간 호출을 연관시키기 위해 x-request-id 헤더를 생성하고, Appliction이 호출을 연관 시키기위해서 자동으로 생성되는 헤더들은 다음과 같습니다.
- x-b3-traceid: 전체 트레이스(Trace)를 식별하는 고유한 ID (64bit)
- x-b3-spanid: 현재 작업(Span)을 식별하는 고유한 ID (64bit)
- x-b3-parentspanid: 현재 span의 부모 span을 식별하는 ID (64bit)
- x-b3-sampled: 이 요청을 트레이싱 시스템에 기록할지 여부를 결정 (0,1)
- x-b3-flags: 트레이싱 옵션(예: 디버그 모드)을 지정 (64bit)
자동 TLS 종료 및 시작
- 특정 서비스로 향하는 TLS 트래픽을 종료 할 수 있으며, Cluster Edge 뿐만 아니라, 서비스 메시 내부에서도 적용할 수 있습니다.
- Envoy가 UpStream Cluster로 TLS 트래픽을 시작 할 수 있습니다.
- 관리자나, 개발자가 언어별 KeyStore, 트러스트 스토어에 관여를 하지 않아도됩니다.
속도 제한
- Envoy의 Retry설정 시 특정 장애의 영향이 과도하게 확대되는 것을 막기 위해 전역 속도 제한 기능을 사용할 수 있습니다.
Envoy와 다른 프록시 비교 시 장점
비교 시 다양한 장점이 있지만, 제가 생각했을때 가장 큰 장점은 해당 사항들입니다.
- 유지보수 및 확장에 용이한 모듈식 코드베이스 기반
- 다양한 프로토콜 지원
- 심층 프로토콜 메트릭 수집
- 동적 설정으로 hot restart가 필요없음
2.Envoy 기능 살펴보기
Envoy 설정하기
- Envoy는
Listener, Root, Cluster
과 같은 기능 뿐만 아니라, Admin API 활성화 , 로그 경로, 트레이싱 엔진과 같은 설정을 지원합니다.
Envoy 정책 예시
static_resources:
clusters:
- name: xds_cluster # Control Plane에 연결하기 위한 클러스터
type: STRICT_DNS
connect_timeout: 5s
# HTTP/2 사용 명시 (gRPC는 HTTP/2 기반)
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {} # HTTP/2 활성화
load_assignment:
cluster_name: xds_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: istiod.istio-system.svc.cluster.local # Control Plane 주소
port_value: 15010
dynamic_resources:
lds_config:
resource_api_version: V3 # 사용할 리소스 API 버전 (v3가 현재 표준)
api_config_source: # 어디서, 어떻게 설정을 가져올지 정의
api_type: GRPC # API 통신 방식 (GRPC, REST, DELTA_GRPC 등) [3]
transport_api_version: V3 # 전송 프로토콜 API 버전
grpc_services: # gRPC 서비스 정의
- envoy_grpc:
cluster_name: xds_cluster
set_node_on_first_message_only: true
cds_config:
resource_api_version: V3
api_config_source: # LDS와 동일한 Control Plane 사용
api_type: GRPC
transport_api_version: V3
grpc_services:
- envoy_grpc:
cluster_name: xds_cluster
set_node_on_first_message_only: true
sds_config:
resource_api_version: V3
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
- envoy_grpc:
cluster_name: xds_cluster # 일반적으로 다른 xDS와 같은 서버 사용
set_node_on_first_message_only: true
Envoy 정적 구성
Listener 부는 Envoy가 수신할 포트를 지정합니다.
filter_chains 부는 Listener가 수신한 트래픽을 처리하는 부분입니다.http_connection_manager 는 HTTP 요청에 대해서 처리하는 부분입니다.
@tpye부 는 Envoy가 Filter로 수행할 http_connection_manager 부분에 대해 명세한 내용입니다.
virtual host 부는 호스트명, 매칭할 도메인 명을 지정하여 처리를 하는 부분입니다.
route, match 부를 사용하여 라우팅 대상을 지정합니다.
cluster 부는 리스너로 전달받은 트래픽을 어느 서비스로 전달하지 지정하는 부분입니다.
최종 도착지의 IP와 LB 방식과 같은 내용이 포함되어있습니다.
Envoy 동적 구성
- Envoy는 API호출을 통해, 재시작 없이 설정을 실시간으로 업데이트 할 수 있으며, 설정 시
xDS API
를 사용합니다. - LDS(Listener Discovery Service)
- Envoy가 노출해야할
Listener을 알려주는 API
서비스를 말합니다.
- Envoy가 노출해야할
- RDS(Route Discovery Serivce)
- LDS의 일부이며,
라우팅 정보를 가져오는 API 서비스
이며, 필수는 아닙니다.
- LDS의 일부이며,
- CDS(Cluster Discovery Service)
- Envoy가
클러스터 목록을 찾고 각 클러스터의 설정을 찾는 API 서비스
입니다.
- Envoy가
- EDS(Endpoint Discovery Serivce)
- CDS의 일부이며,
클러스터에서 어떤 엔드포인트를 사용해야할지 설정하는 API 서비스
입니다.
- CDS의 일부이며,
- SDS(Security Discovery Serivce)
인증서를 적용할 때 사용하는 API 서비스
입니다.
- ADS(Aggregate Discovert Serivce)
xDS API
는궁극적 일관성
을 기반이기 때문에 해당 기능을 구현하기 위한 API 서비스 입니다.
xds_config
항목들을 선언하여, 리스너를 설정합니다.
ads 필드
를 이용하여 리스너의 설정을 구현 합니다.
3.Envoy 실습 및 디버깅 하기
Envoy 실습 개요
sequenceDiagram
participant Client as 클라이언트
participant EnvoyProxy as Envoy Proxy
participant WebServer as HTTPS 웹 서버
Client->>+EnvoyProxy: HTTP 요청
Note right of EnvoyProxy: 수신된 HTTP 요청, 라우팅 규칙 확인
EnvoyProxy->>+WebServer: HTTP 요청
Note left of WebServer: 수신된 HTTP 요청 처리
WebServer-->>-EnvoyProxy: HTTP 응답
Note right of EnvoyProxy: 수신된 HTTP 응답 처리
EnvoyProxy-->>-Client: HTTP 응답
Figure 3.1 Envoy 실습 개요
Envoy 실습
# http 서비스 실행
docker run -d -e PORT=8000 --name httpbin mccutchen/go-httpbin
docker run -it --rm --link httpbin curlimages/curl curl -X GET http://httpbin:8000/headers
# Result
{
"headers": {
"Accept": [
"*/*"
],
"Host": [
"httpbin:8000"
],
"User-Agent": [
"curl/8.13.0"
]
}
}
# Envoy Proxy 설정 파일이 있는 경로로 이동
cd ~/istio-in-action/book-source-code-master/
cat ch3/simple.yaml
# Result Do not Copy!!!!!
admin:
address:
socket_address: { address: 0.0.0.0, port_value: 15000 }
static_resources:
listeners:
- name: httpbin-demo
address:
socket_address: { address: 0.0.0.0, port_value: 15001 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
http_filters:
- name: envoy.filters.http.router
route_config:
name: httpbin_local_route
virtual_hosts:
- name: httpbin_local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
auto_host_rewrite: true
cluster: httpbin_service
clusters:
- name: httpbin_service
connect_timeout: 5s
type: LOGICAL_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: httpbin
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: httpbin
port_value: 8000 # httpbin 포트
docker run --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat ch3/simple.yaml)"
# Result Do not Copy!!!!! (작동확인)
[2025-04-19 05:34:13.868][1][info][config] [source/server/listener_manager_impl.cc:834] all dependencies initialized. starting workers
[2025-04-19 05:34:13.870][1][info][main] [source/server/server.cc:804] starting main dispatch loop
# 세션 복제 후 curl로 Proxy 호출
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/header
# Result Do not Copy!!!!! (작동확인)
{
"headers": {
"Accept": [
"*/*"
],
"Host": [
"httpbin"
],
"User-Agent": [
"curl/8.13.0"
],
"X-Envoy-Expected-Rq-Timeout-Ms": [
"15000"
],
"X-Forwarded-Proto": [
"http"
],
"X-Request-Id": [
"f95484d5-4857-4ddd-bf7a-626fc6af6be7"
]
}
}
# Envoy Proxy 종료
docker rm -f proxy
X-Envoy-Expected-Rq-Timeout-Ms, X-Forwarded-Proto, X-Request-Id
헤더가 추가된 것을 확인 할 수 있습니다.
- X-Envoy-Expected-Rq-Timeout-Ms
- UpStream에 대한 힌트이며, 타임 아웃 시간을 나타냅니다.
- X-Forwarded-Proto
- 접속했던 사용했던 프로토콜을 나타냅니다.
- X-Request-Id
- 요쳥 간 파악을 위해 사용하는 헤더입니다.
설정파일을 수정하여 Envoy Proxy 추가 실습
# Timeout 설정을 추가한 Envoy Proxy 설정 적용
docker run --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat ch3/simple_change_timeout.yaml)"
# 설정 확인
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/headers
# Result Do not Copy!!!!!
# X-Envoy-Expected-Rq-Timeout-Ms 값 변경 사항 확인
{
"headers": {
"Accept": [
"*/*"
],
"Host": [
"httpbin"
],
"User-Agent": [
"curl/8.13.0"
],
"X-Envoy-Expected-Rq-Timeout-Ms": [
"1000"
],
"X-Forwarded-Proto": [
"http"
],
"X-Request-Id": [
"f31187f5-5cb7-4d53-9f1f-a1e79aae17aa"
]
}
}
# Envoy Admin API를 통해 변경된 Timeout이 정상적으로 작동하는지 확인
# LogLevel 변경
docker run -it --rm --link proxy curlimages/curl curl -X POST http://proxy:15000/logging?http=debug
# delay 2초 적용
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/delay/2
# Result Do not Copy!!!!!
upstream request timeout
Envoy Admin API 실습
# Envoy 통계 및 메트릭 출력
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats
# Result Do not Copy!!!!!
cluster.httpbin_service.assignment_stale: 0
cluster.httpbin_service.assignment_timeout_received: 0
cluster.httpbin_service.bind_errors: 0
cluster.httpbin_service.circuit_breakers.default.cx_open: 0
cluster.httpbin_service.circuit_breakers.default.cx_pool_open: 0
cluster.httpbin_service.circuit_breakers.default.rq_open: 0
cluster.httpbin_service.circuit_breakers.default.rq_pending_open: 0
...
# Admin API를 이용한 다른 설정 값 출력
# 머신상의 인증서
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/certs
# 엔보이에 설정한 클러스터
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/clusters
# 엔보이 설정 덤프
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/config_dump
# 엔보이에 설정한 리스너
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/listeners
# 로깅 설정 확인 가능
docker run -it --rm --link proxy curlimages/curl curl -X POST http://proxy:15000/logging
# 로깅 설정 편집 가능
docker run -it --rm --link proxy curlimages/curl curl -X POST http://proxy:15000/logging?http=debug
# 엔보이 통계(프로메테우스 레코드 형식)
docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats/prometheus
Envoy가 Istio와 적합한 이유
- Envoy를 최대한 활용하기 위해서 부가 기능을 구현 한 것이 Istio이기 떄문입니다.
- istiod의
Control Plane
에서 Envoy의 xDS API를 구현 하여 관리 포인트를 줄여 줍니다. - Envoy에서 발생한
Metric과 Telemetry 정보
들을 통합 하기 위해 Istio를 사용합니다. - Serivce Mesh 내의
TLS 트래픽의 종료 및 시작
을 설정하기 위해 Istio를 사용합니다.
graph LR
subgraph "Control Plane"
Istiod["Istiod (Control Plane)"]
end
subgraph "Kubernetes API"
K8sAPI["K8s API Server<br/>Services, Endpoints, Istio CRDs"]
end
subgraph "Data Plane"
subgraph "Pod A Client"
direction LR
App_A["App A"] -- "Traffic" --> Envoy_A["Envoy A"]
end
subgraph "Pod B Server"
direction LR
Envoy_B["Envoy B"] -- "Traffic" --> App_B["App B"]
end
end
subgraph "Observability"
ObservabilityBackend["Observability<br/>Prometheus, Jaeger, etc."]
end
%% Configuration Flow - Links with simplified labels
K8sAPI -- "WatchesResources" --> Istiod;
Istiod -- "PushesConfig" --> Envoy_A;
Istiod -- "PushesConfig" --> Envoy_B;
%% Data Flow - Link with simplified label
Envoy_A -- "ServiceTraffic_mTLS" --> Envoy_B;
%% Telemetry Flow - Links with simplified labels
Envoy_A -- "SendsTelemetry" --> ObservabilityBackend;
Envoy_B -- "SendsTelemetry" --> ObservabilityBackend;
%% Styling (Optional)
classDef control fill:#f9f,stroke:#333,stroke-width:2px;
classDef data fill:#ccf,stroke:#333,stroke-width:2px;
classDef infra fill:#cfc,stroke:#333,stroke-width:2px;
class Istiod control;
class Envoy_A,Envoy_B data;
class App_A,App_B data;
class K8sAPI,ObservabilityBackend infra;
Figure 3.2 Istio와 Envoy
'DevOps > Study' 카테고리의 다른 글
Istio Hands-on Study [1기] [3주차 1/2] Traffic Management (0) | 2025.04.26 |
---|---|
Istio Hands-on Study [1기] [2주차 2/2] Istio Gateway (0) | 2025.04.20 |
Istio Hands-on Study [1기] [1주차 연습과제] Istio Proxy 를 K8S Native Sidecars 로 구성 및 사용 (0) | 2025.04.16 |
Istio Hands-on Study [1기] [1주차 연습과제] Kubernetes Gateway API (0) | 2025.04.16 |
Istio Hands-on Study [1기] [1주차 연습과제] Sail Operator (0) | 2025.04.16 |