채널코퍼레이션 DevOps팀의 Istio Ambient mode 도입기 시리즈 3-4편으로, 운영 중 만난 Istio/Envoy 이슈 두 가지를 부록처럼 정리했다. 하나는 낯선 507 status code의 정체, 다른 하나는 istiod와 연결이 끊긴 것으로 보이는 gateway/waypoint를 어떻게 탐지할 것인가다. 둘 다 Ambient mode 한정 문제가 아니라 Envoy의 요청 buffering·retry 방식과 xDS 연결을 readiness로 어떻게 볼지에 가까워 sidecar mode나 ingress gateway 환경에도 적용된다.
핵심 포인트- 507은 애플리케이션의 저장 공간 부족이 아니라 Envoy가 만든 local reply였고, 상세 사유는 request_payload_exceeded_retry_buffer_limit이었다.
- 507은 413과 다르다. payload가 커서 거부한 것이 아니라 retry하려면 body를 replay해야 하는데 buffer만으로는 replay할 수 없다는 뜻이다.
- retry를 켜면 명시적으로 request body size 제한을 걸지 않았어도 "보이지 않는 buffer limit"이 생긴다. Envoy 기본값은 1MB다.
- 두 번째 이슈는 원인을 특정하지 못해, 단일 root cause를 파는 대신 탐지와 완화에 초점을 옮겼다.
- Istio 기본 readinessProbe는 "최초 xDS config를 받았는가"에 가까워, 한 번 ready가 된 뒤 장시간 disconnected 상태가 되는 것을 잡지 못한다.
상세 정리- 발견 경위: 애플리케이션에서 메일 발송 실패 에러가 보고됐고 메시지에 exceeded request buffer limit while retrying upstream이 담겨 있었다. 503이나 504와 달리 507은 익숙하지 않아 처음에는 애플리케이션 서버의 스토리지 부족을 의심했다.
- Envoy 문서 설명: streaming proxying 중인데 retry를 시도하려고 기다리는 사이 너무 많은 데이터가 도착했다는 뜻이다.
- 왜 큰 payload 자체는 문제가 아닌가: Envoy는 request body 전체를 메모리에 올리지 않고 chunk 단위로 받아 upstream으로 흘려보낸다. 수십 MB라도 한 번에 전체를 buffer로 들 필요가 없다.
- 문제가 생기는 지점: upstream 실패 시 재시도하려면 같은 request를 다시 보낼 수 있어야 하는데, 이미 streaming으로 흘려보낸 POST body를 다시 보내려면 retry에 필요한 만큼을 buffer에 갖고 있어야 한다.
- 동작 순서: retry나 shadowing을 위해 decoding buffer에 데이터를 쌓다가 새 데이터를 더하면 effective buffer limit을 넘는지 확인하고, 넘으면 buffering을 포기한다. 이후 retry가 필요한 상황이 오면 replay할 수 없어 507 local reply를 반환한다.
- 정확한 성격: "payload가 커서 실패했다"가 아니라 "large payload request에서 retry가 필요해지는 순간 실패했다"가 맞다고 정리한다.
- 대응안 1 buffer limit 증가: 값을 늘리면 더 큰 payload에도 retry buffer를 유지할 수 있지만 몇 MB까지 허용할지 정해야 하고 media나 file upload까지 고려하면 무작정 키우기 어렵다. 많은 connection에서 큰 request가 동시에 들어오면 메모리 압박으로 이어진다.
- 적용 범위도 고민거리다. 전체 gateway/waypoint에 일괄 적용하면 blast radius가 커지고 특정 route나 service에만 적용하면 관리 복잡도가 올라간다.
- 대응안 2 retry 끄기: retry를 안 하면 replay가 필요 없어 문제가 사라지지만, 3-1편에서 확인했듯 waypoint/ztunnel 구간의 reset에 retry가 필요해서 끄면 다른 많은 요청에서 503이 사용자에게 그대로 노출된다.
- 대응안 3 채택: large payload 요청은 client나 호출 애플리케이션 레벨에서 retry한다. 업로드·메일 발송·문서 처리처럼 요청 자체가 무거운 API는 애플리케이션 레벨에서 멱등성 키나 중복 처리 방어를 갖추고 5xx에 재시도하는 편이 더 명시적이고 안전하다.
- 두 번째 이슈의 증상: 특정 gateway/waypoint Envoy가 xDS 연결을 유지하지 못하는 것으로 보였고, 로그에는 pilot-agent가 istiod로 연결하는 과정의 DNS timeout과 최초 실패 이후 오랜 시간 반복되는 stream close/retry가 찍혔다.
- 진단이 멈춘 지점: 메시지는 DNS failure처럼 보였지만 같은 시간대 클러스터 전체에 광범위한 DNS 에러가 없었고 CoreDNS 자체도 이상이 없어 보여, root cause를 특정할 근거가 부족했다.
- 연결 구조: gateway/waypoint Pod 안에는 Envoy와 pilot-agent가 함께 있고 Envoy가 직접 istiod에 붙는 것이 아니다. xds-grpc cluster의 실제 목적지는 같은 Pod 안의 pilot-agent UDS이며 pilot-agent가 다시 istiod로 TCP/TLS 연결을 맺어 stream을 중계한다.
- 그래서 장애 지점은 Envoy와 pilot-agent 사이의 Pod 내부 UDS 연결, pilot-agent와 istiod 사이의 Kubernetes DNS·network를 거치는 연결 두 구간으로 나뉜다.
- 에러 전파: Istio agent의 xDS proxy 구현은 istiod upstream 연결 실패를 Envoy downstream stream에 숨기지 않고 전파한다. Envoy는 stream close 시 연결 상태 지표를 0으로 내리고 backoff 후 다시 연결을 시도한다.
- 관찰의 함정: 재연결을 시도할 때마다 Envoy와 pilot-agent 사이 UDS stream이 잠깐 열려 지표가 1로 올라갔다가 istiod 연결 실패로 다시 0으로 내려간다. 실제로 통신하지 못하는 상황에서도 관찰 시점에 따라 값이 달라 보인다.
- readiness의 한계: pilot-agent status probe에는 최초 config 수신 여부에 해당하는 상태가 있어 한 번 ready가 된 뒤에는 연결이 끊겨도 readiness가 곧바로 실패하지 않는다. startup readiness에는 적합하지만 장시간 disconnected 탐지에는 부족하다.
- 운영상 중요한 이유: gateway/waypoint는 이미 받은 config로 한동안 트래픽을 처리할 수 있지만, 장시간 끊기면 새 config·endpoint·certificate rotation 같은 control plane 업데이트를 받지 못한다.
- 메트릭 1: xDS gRPC stream이 열려 있으면 1이 되는 gauge를 본다. 다만 이 값을 Prometheus로 내보내려면 stat 필터링 설정이 Envoy 내부 stat 이름 기준이라는 점을 지켜야 하는데, 실제 장애 당시 이 설정이 잘못돼 있어 사후 분석에 바로 쓸 수 없었다.
- 메트릭 2: xds-grpc cluster의 active connection 수는 정상 상태에서 보통 1이고, pilot-agent가 istiod와 연결하지 못해 stream이 계속 닫히면 0으로 떨어지거나 Pod scraping이 안 되면 시계열이 소실된다. 이 값도 Envoy와 pilot-agent 사이 연결을 보는 것이지만 에러가 전파되는 케이스에서는 실용적인 신호다.
- readiness 반영 방안: 메트릭만으로는 alert에 도움이 되어도 Service endpoint에서 pod를 빼지 못하므로 readinessProbe에 xDS 연결 상태를 반영하는 방안을 검토했다.
- 그 함정: 재연결 루프 때문에 값이 0과 1을 오가는데 기본 successThreshold가 1이라 probe가 한 번만 성공해도 Ready로 돌아와 flapping이 생긴다. 그래서 failureThreshold뿐 아니라 Ready 복귀에도 연속 성공을 요구해 3회 연속 실패로 NotReady, 3회 연속 성공으로 Ready가 되게 완충을 뒀다.
- 한계 인정: 이 지표는 Envoy가 istiod에 직접 붙어 있는지를 보는 것이 아니라 xDS stream 상태를 보는 것이고, probe에서 매번 stat을 파싱하는 방식은 거칠어 설정을 잘못하면 startup 지연이나 flapping을 만들 수 있다고 밝힌다.
왜 읽나Istio나 Envoy를 운영하며 낯선 5xx의 출처를 가려야 하거나, 기본 readiness만으로는 control plane 단절을 못 잡는다고 느끼는 인프라 엔지니어에게 구체적 신호와 대응 선택지를 준다.