Istio 심화 — 왜 그렇게 흐르는가 · pilot-agent 가 Envoy 에게 넘기는 것 · 이론
사이드카의 설정은 두 번에 나뉘어 들어온다
한 줄 요약
사이드카 컨테이너가 띄우는 것은 Envoy 가 아니라 pilot-agent 다. pilot-agent 가 컨테이너 인자·환경 변수·메시 설정을 모아 부트스트랩 한 장을 쓰고, 그 한 장에는 이 프록시가 누구인가(node)와 설정을 어디서 받는가(xds-grpc) 두 가지만 들어 있다. 나머지는 전부 istiod 에서 받아 온다.
왜 이게 필요했나
Envoy 는 설정 파일 한 장으로 뜬다. 그런데 메시의 프록시 수천 개에 서로 다른 설정 파일을 미리 구워 둘 수는 없다. 파드마다 IP 도 이름도 다르고, 서비스가 늘 때마다 모든 파일을 다시 써야 한다. 그래서 Istio 는 설정을 둘로 쪼갰다. 파드가 뜰 때 정해지는 작은 부트스트랩과, 뜬 뒤에 istiod 에서 받는 나머지 전부다.
이렇게 나누면 새로운 종류의 고장이 생긴다. 부트스트랩이 틀리면 프록시가 아예 뜨지 않고(CrashLoop), 부트스트랩은 맞는데 istiod 에 닿지 못하면 프록시는 떠 있는데 준비되지 않는다(Ready 0/2). 두 증상을 가르려면 부트스트랩이 어디서 무엇으로 만들어지는지 알아야 한다.
어떻게 동작하나
주입 산출물의 istio-proxy 는 proxy sidecar --domain $(POD_NAMESPACE).svc.cluster.local … 로 시작한다. $(POD_NAMESPACE) 는 셸 문법이 아니라 kubelet 이 같은 이름의 환경 변수로 바꿔 넣는 쿠버네티스 문법이다. 환경 변수는 두 부류다. CA_ADDR·TRUST_DOMAIN 처럼 주입할 때 정해진 값과, 파드 이름·네임스페이스·서비스 계정처럼 파드가 떠야 알 수 있어 fieldRef 로 받는 값이다.
pilot-agent 는 이것들을 모아 부트스트랩을 만든다.
| 부트스트랩 자리 | 재료 |
| --- | --- |
| node.id | 역할(sidecar)·파드 IP·<파드이름>.<네임스페이스>·<네임스페이스>.svc.cluster.local 네 칸을 물결표로 이은 것 |
| node.cluster | <워크로드>.<네임스페이스> |
| node.metadata | ISTIO_META_* 변수에서 접두사를 뗀 것(CLUSTER_ID, MESH_ID, WORKLOAD_NAME …) |
| static_resources.clusters | xds-grpc 하나. 메시 설정의 discoveryAddress(기본 istiod.istio-system.svc:15012) |
| dynamic_resources | ADS 로 CDS·LDS 를 받고, 첫 응답까지 무한히 기다린다(initial_fetch_timeout: 0s) |
istiod 는 설정 서버이면서 인증서 발급 기관이다. 그래서 기본 설치에서는 CA_ADDR 과 discoveryAddress 가 같은 15012 를 가리킨다. 신원 증명은 두 볼륨에서 시작한다. audience 가 istio-ca 로 좁혀진 투영 서비스 계정 토큰이 '나는 이 서비스 계정이다' 를 증명하고, istio-ca-root-cert ConfigMap 의 루트 인증서가 상대가 진짜 istiod 인지 확인한다.
현장에서 만나는 모습
사이드카만 CrashLoopBackOff. 커스텀 부트스트랩(sidecar.istio.io/bootstrapOverride)이나 EnvoyFilter 로 클러스터 이름을 건드렸다가 흔히 만난다. 로그 첫 줄이 Unknown gRPC client cluster 면 ADS 가 가리키는 이름과 정적 클러스터 이름이 어긋난 것이다. 이 종류는 --mode validate 로 배포 전에 걸러진다.
파드가 1/2 Ready 에서 멈춘다. 프록시는 떠 있는데 15021 이 503 이다. Envoy 가 PRE_INITIALIZING 에 머물러 있다면 istiod 에서 첫 설정을 받지 못한 것이다 — 네트워크 정책이 15012 를 막았거나, 토큰의 audience 가 맞지 않아 인증서를 못 받았거나, istiod 가 내려가 있다. 관리 포트는 이 상태에서도 열려 있으니 control_plane.connected_state 부터 본다.
멀티 클러스터에서 설정이 섞인다. CLUSTER_ID 가 두 클러스터에서 같으면 istiod 가 두 프록시를 구분하지 못해 엔드포인트가 뒤섞인다. 이름표는 설정을 고르는 열쇠다.
공식 문서: [pilot-agent](https://istio.io/latest/docs/reference/commands/pilot-agent/) · [Debugging Envoy and Istiod](https://istio.io/latest/docs/ops/diagnostic-tools/proxy-cmd/) · [Envoy bootstrap](https://www.envoyproxy.io/docs/envoy/v1.38.3/configuration/overview/bootstrap)
다음 실습에서 할 것
주입 산출물에서 인자·환경 변수·볼륨을 뽑고, 같은 모양의 부트스트랩을 손으로 써서 거른다. 클러스터 이름 하나를 틀려 Envoy 가 뜨기도 전에 거절하는 것을 보고, istiod 가 없는 파드에서 프록시가 준비되지 못한 채 기다리는 것을 관리 포트로 확인한다.