istio를 운영하면서 503 UC upstream_reset_before_response_started{connection_termination} 겪은 이슈와 나름의 해결 방법에 대해 소개하고자 한다.
이슈 상황

위 그림과 같이 특정 도메인(test.com) 으로 요청이 오는 경우, 쿠버네티스 바깥의 외부 서비스(external-service.com) 로 포워딩하도록 istio를 구성한 상황에서 간헐적으로 503 에러가 발생한 것을 확인하였다.
따져보자면 약 0.05% 내외의 비율로 200과 503에러가 각각 발생하는데, 큰 비율은 아니지만 서비스 안정성에 대해 좋지 않은 현상이 지속적으로 발생하는 것이기 때문에 원인을 파악하고 빠르게 조치를 하는 것이 필요하다.
초기 구성
초기 구성은 다음과 같다.
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: test
namespace: istio-system
spec:
hosts:
- test.com
gateways:
- test
http:
- route:
- destination:
host: external-service.com
---
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-service
namespace: istio-system
spec:
hosts:
- external-service.com
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: TLS
resolution: DNS
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: external-service
namespace: istio-system
spec:
host: external-service.com
trafficPolicy:
tls:
mode: SIMPLE
insecureSkipVerify: false
sni: external-service.com
- 특정 도메인으로 요청오는 경우, 쿠버네티스 밖의 외부 서비스로 포워딩 해야 하는데, Routing 등 istio의 관리를 받으려면 외부 서비스 도메인을 ServiceEntry에 등록해야 한다.
- HTTPS 외부 서비스로 포워딩하기 위해서는 TLS 처리가 되어야하는데 DestinationRule으로 TLS 처리를 할 수 있도록 한다.
사실 초기 구성에는 큰 문제는 없어보였다. 그래서 에러 내용에 주목해보았다.
에러 로그
istio Access log를 확인해보니 다음과 같았다.
[2025-08-04T11:57:10.861Z] "GET / HTTP/2" 503 UC upstream_reset_before_response_started{connection_termination} - "-" 0 95 617 - "192.168.65.3" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36" "169f9602-1d22-4de4-9980-460dc21833dd" "test.com" "x.x.x.x:443" outbound|443||external-service.com 10.1.0.176:54316 10.1.0.176:443 192.168.65.3:62790 test.com -
envoy response code details를 확인해보면 upstream_reset_before_response_started{connection_termination} 는 응답이 시작되기 전에 업스트림에서 연결을 종료할 때 발생하는 응답 코드이다. 즉, 외부 서비스에서 응답을 전달하기 전에 요청을 간헐적으로 종료한다는 것인데 이 원인에 대해 파악이 필요하다.
에러 원인
Istio ingressgateway의 본체인 Envoy proxy는 기본적으로 HTTP/2를 지원하며, 커넥션 풀을 가지고 있다. 기본적으로는 제한 없이 요청을 처리하는 데 필요한 만큼의 HTTP/2 커넥션풀을 생성한다.

여기서 외부 대상 서버와 커넥션풀이 이미 생성되어 있으면 해당 요청을 재사용한다. HTTP/2는 멀티플렉싱을 지원하기 때문에 이미 사용 중인 커넥션 풀을 동시에 사용하는 것도 가능하다.
그런데 만약 대상 서버에서 어떠한 이유로 연결을 끊어버린다면 이 때 통신 중인 요청은 비정상적으로 에러가 발생할 것이다. 바로 이러한 경우에 upstream_reset_before_response_started{connection_termination} 에러가 발생한다.

해결 방안
이슈가 발생했을 때는 대상 서버가 우리가 운영하는 서버가 아니었기 때문에 대상 서버를 제어할 수는 없었다. 그래서 운영 서버의 설정을 몇 가지 수정하여 간헐적으로 503 에러가 발생하는 이슈를 해결하였다. 나는 일단 두 가지 해결방안을 찾았다.
1. HTTP/2 옵션 제거
에러의 원인은 HTTP/2에서의 멀티플렉싱 기능을 사용하고, 대상 서버에서는 재사용 중인 커넥션을 간헐적으로 끊어버려서 에러가 발생한 것이다. 그래서 가장 간단하게 간헐적 에러를 끊는 방법은 대상 서버로 통신할 때 HTTP/2 업그레이드 옵션을 제거하는 것이다.
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: external-service
namespace: istio-system
spec:
host: external-service.com
trafficPolicy:
connectionPool:
http:
h2UpgradePolicy: DO_NOT_UPGRADE # HTTP/2 업그레이드 방지
tls:
mode: SIMPLE
insecureSkipVerify: false
sni: external-service.com
spec.trafficPolicy.connectionPool.http.h2UpgradePolicy를 DO_NOT_UPGRADE로 설정하면 http/2가 비활성화되고 http/1.1을 사용하기 때문에 해당 에러가 발생하지는 않는다. 대신 HTTP/2를 사용할 수 없기 때문에 성능적으로 이득을 볼 수 없을 것이다.
2. Retry
간헐적으로 서버측 커넥션이 끊겨서 에러가 발생하는 경우에는 VirtualService에서 retry 로직을 추가하는 방법도 있다. connection_termination 으로 인해 503이 떨어지면 envoy proxy에서 최대 두 번 재시도를 한다. 그러면 거의 에러가 발생하지 않는다.
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: test
namespace: istio-system
spec:
hosts:
- test.com
gateways:
- test
http:
- route:
- destination:
host: external-service.com
retries:
attempts: 2
retryOn: gateway-error,connect-failure,refused-stream,unavailable,cancelled,retrieable-status-codes
retryOn의 기본 값은connect-failure,refused-stream,unavailable,cancelled,retrieable-status-codes이다.gateway-error는 502, 503, 504 에러가 발생하는 경우를 의미한다.- 그 밖의 설정값은 아래 문서를 확인하면 알 수 있다.
Router — envoy 1.36.0-dev-d81269 documentation
upstream.maintenance_mode. % of requests that will result in an immediate 503 response. This overrides any routing behavior for requests that would have been destined for . This can be used for load shedding, failure injection, etc. Defaults to disabled. u
www.envoyproxy.io
'DevOps > Istio' 카테고리의 다른 글
| istio 버전 업그레이드 (0) | 2025.03.03 |
|---|---|
| istio EnvoyFilter에 대해 알아보자. (0) | 2025.03.03 |
| istio와 envoy proxy 세부적으로 파악해보기 (0) | 2025.02.20 |
| istio traffic 관리 (3) [Egress Gateway] (1) | 2025.01.18 |
| istio traffic 관리 (2) [Gateway] (0) | 2025.01.13 |
댓글