LabHub

ICA — 이스티오 인증 어소시에이트 · 관측성·앰비언트·업그레이드 · 이론

프록시를 파드에서 떼어내면 무엇이 달라지나

LabHub 에서 이어서 보기

한 줄 요약

앰비언트 모드는 L4 와 L7 을 분리해, 모든 워크로드가 풀 Envoy 비용을 강제로 내지 않게 만든 구조입니다. 대신 장애 도메인이 파드에서 노드로 커집니다.

왜 이게 필요했나

사이드카 모델의 비용은 숫자로 보면 분명합니다. 파드 500개 클러스터에서 사이드카 하나당 메모리 120MiB 라면 그것만으로 약 58GiB, CPU request 100m 씩이면 50 vCPU 가 스케줄링 용량에서 사라집니다. 게다가 프록시가 파드 안에 있으니 버전을 올리려면 전 워크로드를 롤링 재시작해야 하고, 주입 라벨·리비전 태그·웹훅 설정 중 하나만 어긋나도 "어떤 파드는 메시 안, 어떤 파드는 메시 밖"인 상태가 됩니다. 이 상태에서 STRICT 를 켜면 주입 안 된 파드가 전부 끊깁니다.

여기에 결정적인 관찰이 하나 더해집니다. 실제로 L7 기능이 필요한 서비스는 전체의 일부입니다. 나머지 대다수는 mTLS 와 기본 텔레메트리면 충분한데 사이드카 모델은 이들에게도 풀 Envoy 를 부과했습니다.

어떻게 동작하나

앰비언트는 두 층으로 나뉩니다.

노드 사이는 HBONE 터널로 흐릅니다. 포트 15008 에서 mTLS 위에 HTTP/2 CONNECT 로 원본 TCP 스트림을 감싸는 방식입니다. HTTP/2 의 스트림 다중화 덕분에 같은 노드 쌍의 여러 연결이 하나의 mTLS 연결을 공유해 핸드셰이크 비용이 줄고, CONNECT 헤더에 원 목적지와 신원이 실리므로 수신 측 ztunnel 은 페이로드를 열지 않고도 L4 인가를 판정합니다.

설계 원칙 하나를 반드시 기억해야 합니다. waypoint 는 목적지 소유입니다. 사이드카 모델에서는 클라이언트 측 프록시가 라우팅과 재시도를 했지만, 앰비언트에서는 목적지 서비스를 소유한 팀이 자기 waypoint 에서 L7 정책을 집행합니다. 정책 소유권이 명확해지는 대신, "호출자별로 다른 타임아웃" 같은 클라이언트 측 정책은 재설계가 필요합니다.

정직하게 반대급부도 봐야 합니다. waypoint 를 경유하는 경로는 홉이 3개(ztunnel → waypoint → ztunnel)라 사이드카(홉 2)보다 길어질 수 있습니다. 그리고 ztunnel 이 죽으면 그 노드의 모든 메시 트래픽이 영향을 받습니다. 사이드카는 프록시 장애가 파드 하나에 갇혔지만 앰비언트는 노드 단위 장애 도메인입니다. PodDisruptionBudget, 우선순위 클래스, 재시작 모니터링을 운영 설계에 반드시 반영해야 합니다.

디버깅은 순서가 전부입니다. istioctl proxy-config트래픽이 흐르는 순서대로 읽습니다.

listener  이 프록시가 그 포트를 듣고 있는가   ->route     VirtualService 가 라우팅 테이블로 번역됐는가   ->cluster   DestinationRule(서킷브레이커, TLS)이 반영됐는가   ->endpoint  그 subset 에 실제 파드 IP 가 잡혀 있는가

어느 단계에서 기대와 어긋나는지 찾으면 고칠 리소스가 자동으로 정해집니다. 503 의 응답 플래그 판독표도 같은 맥락입니다.

| 플래그 | 의미 | 첫 의심 |
| --- | --- | --- |
| UH | no healthy upstream | subset 라벨과 파드 라벨 불일치 |
| UO | upstream overflow | connectionPool 한도 초과 |
| UF | upstream connection failure | 한쪽만 STRICT 인 mTLS 불일치, 포트 프로토콜 오인 |
| NR | no route | VirtualService 매칭 누락, catch-all 부재 |
| URX | max retries reached | 재시도 소진 — 근본 원인은 다른 플래그와 함께 추적 |

관측성 쪽에서 마지막으로 하나. Envoy 는 스팬을 자동으로 만들지만, 애플리케이션이 인바운드 요청의 트레이스 헤더를 아웃바운드로 전파하지 않으면 트레이스가 끊깁니다. 메시를 깔았는데 트레이스가 조각조각 나오는 이유는 대부분 이것이고, 메시가 대신 해 줄 수 없는 유일한 부분이기도 합니다.

현장에서 만나는 모습

저자의 홈랩에서 hubble-relay 와 hubble-ui 가 Pending 에 머문 적이 있습니다. 이벤트는 0/1 nodes are available: 1 node(s) had untolerated taint(s) 였습니다. 원인은 단순했습니다. 컨트롤 플레인 노드에는 node-role.kubernetes.io/control-plane:NoSchedule taint 가 걸려 있고, 이 두 구성요소는 DaemonSet 이 아니라 Deployment 라 toleration 이 없었습니다. CoreDNS 는 기본 toleration 을 갖고 있어 정상 기동한 것과 대비됐고, 워커가 조인하자 바로 해소됐습니다.

이 사례가 앰비언트를 이해하는 데 그대로 쓰입니다. ztunnel 은 DaemonSet, waypoint 는 Deployment 입니다. 즉 ztunnel 은 노드마다 자동으로 뜨지만 waypoint 는 스케줄러가 자리를 찾아 줘야 합니다. taint 가 걸린 노드만 남았거나 리소스가 부족하면 waypoint 는 조용히 Pending 에 머물고, 그 네임스페이스의 L7 정책은 아예 집행되지 않습니다. "L4 는 되는데 L7 정책만 안 먹는다"는 증상의 첫 확인 지점이 waypoint 파드 상태인 이유입니다.

또 하나. 그 홈랩은 --skip-phases=addon/kube-proxy 로 kube-proxy 를 설치 후 삭제가 아니라 처음부터 미설치로 세웠습니다. 한 번이라도 돌면 KUBE-SERVICES / KUBE-SVC-* / KUBE-SEP-* 체인이 노드에 남기 때문입니다. 사이드카에서 앰비언트로 전환할 때도 같은 원칙이 적용됩니다. 한 네임스페이스에 주입 라벨과 ambient 라벨이 공존하면 안 되고, 주입 라벨을 지운 뒤 반드시 롤아웃 재시작으로 기존 사이드카를 걷어낸 다음 ambient 라벨을 붙여야 합니다.

다음 퀴즈에서 확인할 것

이 모듈은 개념 모듈입니다. 실습 대신 퀴즈로 앰비언트 구조, HBONE, 장애 도메인, proxy-config 읽는 순서, 응답 플래그 판독을 점검합니다. 이 다섯 가지는 시험뿐 아니라 실제 장애 대응에서 가장 먼저 꺼내 쓰는 도구입니다.