Envoy 내부 구조 · 네 개의 개념 · 이론
Envoy 설정을 읽는 순서
한 줄 요약
리스너로 받아서, 필터체인을 통과시키고, 라우트가 고른 클러스터의 엔드포인트로 보낸다. Envoy 설정은 전부 이 다섯 단어의 조합이다.
왜 이게 필요했나
Envoy 설정 JSON 은 처음 보면 압도적이다. 그런데 구조는 단순하다. 들어오는 쪽과 나가는 쪽이 짝을 이룬다.
| 개념 | 대응하는 것 | 하는 일 |
|---|---|---|
| Listener | nginx 의 server { listen } | 어느 주소·포트에서 받나 |
| Filter chain | nginx 의 location + 모듈 | 받은 것을 어떻게 처리하나 |
| Route | nginx 의 location 매칭 | 어느 백엔드로 보낼지 고른다 |
| Cluster | nginx 의 upstream | 백엔드 묶음(정책 포함) |
| Endpoint | upstream 의 server 한 줄 | 실제 주소:포트 |
어떻게 동작하나
요청 하나가 지나가는 길은 이렇다.
클라이언트 → Listener (0.0.0.0:15001) → Filter chain (TLS 종료 → HTTP 커넥션 매니저) → Route (Host: shop.example.com, path /api/* ) → Cluster (outbound|8080||shop.default.svc.cluster.local) → Endpoint (10.244.1.7:8080) ← 로드밸런싱으로 하나 고름핵심은 클러스터와 엔드포인트가 나뉘어 있다는 것이다. 클러스터는 정책(로드밸런싱 알고리즘, 커넥션 풀 크기, 이상치 감지, 서킷 브레이커)을 담고, 엔드포인트는 그 순간의 실제 주소 목록이다. 파드가 뜨고 죽어도 클러스터 정의는 그대로고 엔드포인트 목록만 바뀐다.
xDS — 설정이 흘러드는 통로
Envoy 는 설정 파일을 다시 읽고 재시작하지 않는다. 컨트롤 플레인이 gRPC 스트림으로 밀어 넣는다. 종류마다 이름이 있다.
| 약자 | 무엇을 보내나 |
|---|---|
| LDS | Listener |
| RDS | Route |
| CDS | Cluster |
| EDS | Endpoint |
| SDS | 인증서(Secret) |
Istio 의 istiod 가 하는 일이 정확히 이것이다. 여러분이 쓴 VirtualService 는 RDS 로, DestinationRule 은 CDS 로, 서비스의 파드 목록은 EDS 로 번역돼 각 사이드카에 밀린다.
그래서 "Istio 설정을 고쳤는데 반영이 안 된다" 를 조사하는 방법도 정해진다 — 사이드카가 실제로 받은 설정을 본다.
istioctl proxy-config route <pod> # RDS 로 받은 것istioctl proxy-config cluster <pod> # CDSistioctl proxy-config endpoint <pod> # EDSVirtualService 를 다시 읽는 것은 소용이 없다. 우리가 쓴 것과 프록시가 받은 것이 다를 수 있고, 그 차이가 바로 원인이다.
흔한 착각
"사이드카가 요청을 느리게 만든다" — Envoy 자체의 지연은 보통 밀리초 이하다. 체감 지연의 대부분은 커넥션 풀 설정, mTLS 핸드셰이크, 그리고 재시도 설정에서 온다. 특히 재시도는 장애 시 부하를 몇 배로 키운다.
클러스터 이름이 랜덤해 보이는 것. outbound|8080||shop.default.svc.cluster.local 은 규칙이다 — 방향|포트|서브셋|호스트. 서브셋이 비어 있으면 DestinationRule 의 subset 을 안 쓴다는 뜻이다. 이 규칙을 알면 설정 덤프에서 원하는 줄을 바로 찾는다.
실무에서 진짜 중요한 것
Envoy 통계 이름도 규칙이 있고, 그게 장애 조사의 지도다.
cluster.<클러스터이름>.upstream_rq_5xx 백엔드가 낸 5xxcluster.<클러스터이름>.upstream_rq_pending_overflow 커넥션 풀이 넘쳤다cluster.<클러스터이름>.outlier_detection.ejections_active 쫓겨난 엔드포인트 수listener.<주소>.downstream_cx_total 들어온 연결 수upstream_rq_pending_overflow 가 늘어나면 애플리케이션이 느린 게 아니라 커넥션 풀이 작은 것이다. 이 둘은 대처가 정반대다.