Istio 507 에러와 istiod 연결 끊김, 해결책은?

by DD
9시간 전
조회수 0

Envoy의 request payload retry buffer limit 초과로 인해 예상치 못한 507 Insufficient Storage 에러가 발생하는 문제 상황을 분석함

대용량 요청(Large Request Payload)과 재시도(Retry)가 겹칠 때 발생하는 Envoy의 보이지 않는 버퍼 제한에 대한 이해를 높임

istiod와의 xDS 연결 끊김을 탐지하기 위한 envoy_control_plane_connected_stateenvoy_cluster_upstream_cx_active 메트릭 활용 방안을 제시함

기본 readinessProbe의 한계를 보완하기 위한 커스텀 readinessProbe 도입 필요성을 제기함

Envoy의 507 에러: Retry Buffer Limit 초과 원인 분석

Envoy에서 발생하는 507 Insufficient Storage 에러는 애플리케이션의 디스크 부족이 아닌, 대용량 요청(Large Request Payload) 처리 중 재시도(Retry)가 필요할 때 Envoy의 내부 버퍼 제한을 초과하여 발생하는 현상임.

Envoy는 요청을 스트리밍(Streaming)으로 전달하지만, 재시도를 위해 일정량의 요청 본문(Request Body)을 버퍼에 보관해야 함.

이 보관 용량이 `per_connection_buffer_limit_bytes` (기본 1MB)를 초과하면, Envoy는 더 이상 요청을 재시도할 수 없어 507 로컬 응답(Local Reply)을 반환함.

이는 명시적인 요청 크기 제한(413 Content Too Large)과는 다르며, "대용량 요청 + 재시도 가능한 실패" 조건에서 발생하는 예상치 못한 문제임.

따라서 대용량 POST 요청에 대한 재시도 정책 적용 시, Envoy의 버퍼 한계를 고려하여 클라이언트 또는 애플리케이션 레벨에서의 재시도 로직 구현이 필요함.

Istiod 연결 끊김 탐지를 위한 메트릭 활용

Istio Ambient Mode 환경에서 Gateway/Waypoint의 istiod와의 xDS 연결 상태를 탐지하는 것은 운영 안정성 확보에 중요함.

`envoy_control_plane_connected_state`: Envoy의 xDS gRPC 스트림 상태를 나타내는 메트릭으로, 0은 연결 끊김, 1은 연결됨을 의미함. 이는 Envoy와 local pilot-agent 간의 연결 상태를 반영하며, pilot-agent의 istiod 연결 실패 시 간접적으로 활용 가능함.

`envoy_cluster_upstream_cx_active{cluster_name="xds-grpc"}`: xds-grpc 클러스터의 활성 연결 수를 나타내며, 정상 시 1, 연결 실패 시 0으로 떨어짐. 이 역시 Envoy-pilot-agent 간 연결 상태를 보여줌.

이 메트릭들은 `proxyStatsMatcher` 설정을 통해 Prometheus로 수집해야 하며, 설정 오류 시 데이터 수집에 실패할 수 있음. 또한, 이 메트릭들은 Envoy의 `readinessProbe`와 연동하여 서비스 엔드포인트에서 제외하는 방식으로 활용될 수 있음.

기존 Readiness Probe의 한계와 개선 방안

Istio의 기본 `readinessProbe`는 Envoy가 최초 xDS 설정을 수신했는지 여부에 초점을 맞추므로, 이후 istiod와의 연결이 장시간 끊기는 상황을 탐지하기에 부족함.

기본 Probe는 최초 설정 수신 후에는 연결이 끊겨도 `ready` 상태를 유지할 수 있어, 최신 설정이나 인증서 갱신 정보를 받지 못하는 문제가 발생할 수 있음.

이를 보완하기 위해 `envoy_control_plane_connected_state` 메트릭을 활용한 커스텀 `readinessProbe` 도입을 고려할 수 있음.

커스텀 Probe 구현 시, 연속적인 연결 성공/실패 임계값(failureThreshold, successThreshold)을 설정하여 재연결 루프(Reconnection Loop)로 인한 Flapping 현상을 방지하는 것이 중요함. 예를 들어, 3회 연속 실패 시 NotReady로, 3회 연속 성공 시 Ready로 복귀하도록 설정할 수 있음.

Envoy의 Retry 메커니즘과 대용량 요청 처리

Envoy의 재시도(Retry) 메커니즘은 서비스 안정성 향상에 기여하지만, 대용량 요청(Large Request Payload) 처리 시에는 예상치 못한 동작을 유발할 수 있음.

Envoy는 재시도를 위해 요청 본문(Request Body)을 버퍼에 보관해야 하는데, 이 버퍼 크기 제한(`per_connection_buffer_limit_bytes`)을 초과하면 507 에러가 발생함.

이는 명시적인 요청 크기 제한(413 Content Too Large)과는 다른 문제로, "대용량 요청 + 재시도 필요 상황"이라는 복합적인 조건에서 발생함.

따라서 대용량 파일 업로드나 메일 발송과 같이 요청 자체가 무거운 API의 경우, Envoy의 재시도 기능에만 의존하기보다 애플리케이션 레벨에서 멱등성(Idempotency)을 보장하고 재시도 로직을 직접 구현하는 것이 더 안전하고 명확한 접근 방식임.

Envoy와 Istiod 간의 연결 구조 및 장애 전파

Istio Gateway/Waypoint Pod 내에서 Envoy는 직접 istiod와 통신하는 것이 아니라, 로컬 pilot-agent를 거쳐 통신하는 구조임.

Envoy는 `xds-grpc` 클러스터를 통해 pilot-agent의 UDS(Unix Domain Socket)와 통신하고, pilot-agent가 다시 istiod와 TCP/TLS 연결을 맺음.

장애 발생 지점은 Envoy ↔ pilot-agent UDS 연결 또는 pilot-agent ↔ istiod TCP/TLS 연결 두 구간임.

관찰된 로그(`lookup istiod.istio-system.svc: i/o timeout`)는 pilot-agent가 istiod로 연결하는 과정에서 DNS 타임아웃이 발생했음을 시사함.

중요한 점은 pilot-agent가 istiod 연결 실패 시, 해당 에러를 Envoy의 xDS 스트림에 전파하여 Envoy의 `connected_state`를 0으로 만들고 재연결을 시도하게 함. 이 과정에서 장애가 상위 컴포넌트로 전파되는 메커니즘을 이해하는 것이 중요함.

Istio 3-4편: 507 status code와 istiod disconnected 탐지