본문으로 건너뛰기
장애 이야기: 간헐적 응답 이상

05 · 장애 이야기 — 메시가 낀 경로에서 간헐적 응답 이상 추적하기

  • 메시의 5xx는 어느 홉에서 났느냐가 전부입니다. 나침반은 Envoy response flag(UH/UF/UC/UO/NR…)입니다.
  • 추적 순서: 범위 축소 → flag 확인 → 설정 stale 여부(istioctl proxy-status) → mTLS → 라이프사이클 레이스 → 커넥션풀.
  • 간헐적 5xx는 특히 stale 엔드포인트배포 시점 라이프사이클 레이스가 단골 원인입니다.
  • 예방은 라이프사이클 훅 표준화, outlier detection, 컨트롤 플레인 수렴 관측, response_flags 대시보드 상시화.

그때 무슨 일이 있었나. EKS에 올려둔 서비스 하나가 간헐적으로 응답 이상을 냈습니다. 산발적인 5xx와 지연이었습니다. 애플리케이션 로그는 멀쩡해 보이는데 클라이언트는 이따금 실패했습니다. 요청 경로에 메시가 껴 있으니 “앱이 문제냐"로 끝낼 수 없고 앱 · 사이드카 · 컨트롤 플레인 · 네트워크를 층으로 나눠 봐야 했습니다. 이 문서는 그 추적을 순서 있는 체크리스트로 정리합니다 — 메시 장애의 나침반은 Envoy가 붙이는 response flag입니다.

관련 문서: 01 메시 기초 · 02 컨트롤 플레인 · 03 게이트웨이

먼저: 5xx는 누가 낸 것인가

메시를 지나는 요청 하나는 프록시를 여러 번 거칩니다. 똑같은 “503"이라도 어느 홉에서 났느냐에 따라 원인이 완전히 다릅니다.

요청 하나가 지나는 프록시 홉
도식 텍스트
  • client
  • ① ingress GW Envoy
  • ② source sidecar
  • ③ dest sidecar
  • ④ app

앱(④)이 낸 503과 dest 사이드카(③)가 “붙을 상대가 없어서” 낸 503은 전혀 다른 문제입니다. 이걸 구분해 주는 게 Envoy의 response flag입니다. Envoy 액세스 로그의 %RESPONSE_FLAGS% 필드에 두세 글자로 찍힙니다.

flag의미흔한 원인
UHno healthy Upstream Host대상 서비스에 건강한 엔드포인트가 없음 (EDS 미반영·전부 unready)
UFUpstream connection Failure상대 파드에 연결 자체가 실패 (죽음·네트워크·mTLS 불일치)
UCUpstream Connection termination연결이 중간에 끊김 (앱이 Envoy보다 먼저 keepalive 종료 등)
UOUpstream Overflow서킷브레이커·커넥션풀 상한 초과 (DestinationRule)
URXUpstream Retry limeXceeded재시도 한도 소진
NRNo Route매칭되는 라우트 없음 (VirtualService·Gateway 설정 문제)
DCDownstream Connection termination클라이언트가 먼저 끊음

간헐적 5xx라면 UH·UC·UF·UO가 단골입니다 — 전부 “가끔” 발생하는 성격입니다.

추적 순서

1) 범위를 좁힌다

무작정 파기 전에 패턴부터 봅니다. 특정 서비스만? 특정 경로만? 특정 AZ·노드만? 배포 직후에만? 메트릭 istio_requests_totaldestination_service, response_code, response_flags, source_workload로 쪼개 봅니다. 배포 타이밍과 겹치면 라이프사이클 문제(아래 5번)를 먼저 의심합니다.

2) 어느 홉인지 — 액세스 로그의 response flag

의심 구간의 Envoy 액세스 로그에서 response_flags를 확인합니다. 이 한 컬럼이 범인이 앱인지 프록시인지, 어느 방향인지를 바로 알려줍니다.

# 대상 워크로드 사이드카의 액세스 로그
kubectl logs deploy/<svc> -c istio-proxy | grep ' 503 '
# → RESPONSE_FLAGS 컬럼(UH/UC/UF/UO…)을 본다

flag가 없고 앱이 직접 503을 냈다면 그건 앱 문제입니다. flag가 붙어 있으면 아래로 갑니다.

3) 프록시가 든 설정이 최신인가 — proxy-status / proxy-config

간헐적 UH·NR은 대개 stale한 설정에서 옵니다. 컨트롤 플레인이 밀려(02의 수렴 지연) 프록시가 옛 엔드포인트·라우트를 들고 있으면 이미 사라진 파드로 요청을 보내다 실패합니다.

istioctl proxy-status                 # 각 프록시가 SYNCED인지 STALE인지
istioctl proxy-config endpoints <pod> # 이 프록시가 아는 실제 엔드포인트 목록
istioctl proxy-config routes <pod>    # 라우팅 규칙이 기대대로인지

STALE이 보이거나 endpoints 목록이 실제 파드와 다르면 02의 컨트롤 플레인 문제로 넘어갑니다 — pilot_proxy_convergence_time을 확인합니다.

4) mTLS·정책 불일치 — UF의 단골

간헐적 UF에는 mTLS 미스매치가 잦습니다. PeerAuthentication이 STRICT인데 일부 호출자가 평문이거나 마이그레이션 중 한쪽만 mTLS면 그쪽 연결이 실패합니다. AuthorizationPolicy가 특정 조건에서만 막고 있을 수도 있습니다.

istioctl proxy-config secret <pod>    # 인증서가 제대로 발급됐는지
# PeerAuthentication / AuthorizationPolicy 범위와 mode 점검

5) 파드 라이프사이클 레이스 — 배포 직후 간헐 장애의 진짜 원인

간헐적 5xx가 롤링 배포 시점에 몰린다면 십중팔구 사이드카-앱의 시작·종료 순서 문제입니다.

  • 시작 레이스 — 앱 컨테이너가 사이드카 Envoy보다 먼저 떠서 트래픽을 받으면 아직 준비 안 된 프록시 때문에 실패합니다. → holdApplicationUntilProxyStarts: true로 프록시가 준비될 때까지 앱을 붙잡습니다.
  • 종료 레이스 — 파드 종료 시 사이드카가 앱보다 먼저 죽으면 아직 처리 중이던 요청이 UC로 끊깁니다. → preStop 훅에 짧은 sleep을 두거나 연결이 빠질 때까지 프록시 종료를 늦추고 terminationDrainDuration·엔드포인트 제거(readiness)를 맞춥니다.
  • 엔드포인트 갱신 랙 — 파드는 죽었는데 EDS 갱신이 늦어 UH가 뜹니다. → 3번(수렴)과 이어집니다. DestinationRule의 outlier detection으로 문제 엔드포인트를 자동 축출하면 간헐 실패를 데이터 플레인에서 흡수할 수 있습니다.

6) 커넥션풀·서킷브레이커 — UO

간헐적 UO는 DestinationRule의 커넥션풀·서킷브레이커 상한에 트래픽이 순간 몰려 부딪힌 결과입니다. 상한이 너무 빡빡한지, 트래픽 특성(버스트)에 맞는지 재검토합니다.

층으로 가르는 지도

메시 장애는 네 개 층으로 나눠 놓고 나침반(response flag)을 따라갑니다.

무엇을 보나도구·지표
앱이 직접 낸 에러인가앱 로그, flag 없는 5xx
사이드카(데이터 플레인)연결·라우팅·mTLS·풀액세스 로그 response_flags, istioctl proxy-config
컨트롤 플레인설정이 stale인가, 수렴이 밀리나istioctl proxy-status, pilot_proxy_convergence_time02
네트워크·게이트웨이관문·LB·노드 레벨게이트웨이 Envoy 로그, LB 지표 → 03

재발 방지 체크리스트

  • 라이프사이클 — holdApplicationUntilProxyStarts, preStop sleep, terminationDrainDuration을 표준 템플릿에 박아둡니다. (배포 시점 간헐 5xx의 최대 예방책)
  • 탄력성 — 적정한 timeout·retry(멱등 요청에 한해), DestinationRule outlier detection으로 나쁜 엔드포인트 자동 축출.
  • 컨트롤 플레인 여유 — 수렴 시간을 SLO로 관측(02). 배포가 몰리는 시간대에 istiod가 밀리지 않는지 봅니다.
  • 관측 표준화 — 액세스 로그에 %RESPONSE_FLAGS%를 반드시 포함하고 istio_requests_total을 flag·code로 쪼개는 대시보드를 상시 띄워둡니다. 나침반이 없으면 매번 처음부터 헤맵니다.

이 문서에서 가져갈 것

  • 메시의 5xx는 어느 홉에서 났느냐가 전부입니다. 그걸 판별하는 나침반이 Envoy response flag(UH/UF/UC/UO/NR…)입니다.
  • 추적은 범위 축소 → flag 확인 → 설정 stale 여부 → mTLS → 라이프사이클 레이스 → 커넥션풀 순서. 간헐적 5xx는 특히 stale 엔드포인트배포 시점 라이프사이클 레이스가 잦습니다.
  • 예방은 라이프사이클 훅 표준화·탄력성 설정·컨트롤 플레인 수렴 관측·flag 대시보드. 층을 나눠 보는 습관이 메시 장애 대응을 좌우합니다.
마지막 수정 일자