Network Loss — 패킷 손실 주입 및 Ingress retry 설정 비교
목적: 패킷 손실 상황에서의 서비스 영향을 관찰하고, NGINX Ingress retry/timeout 설정을 조정해 실패율과 tail latency 간의 trade-off를 비교하고, 실험 환경에서의 최종 설정을 도출한다
1. 개요
Chaos Mesh의 NetworkChaos(action: loss)로 podinfo Pod 중 하나에 50% 패킷 손실을 주입하고, k6로 동일한 부하를 주며 서비스 영향을 관찰했다. 이 실험은 다음 세 단계로 진행했다.
단계 | 설정 | 목적 |
개선 전 | retry/timeout 튜닝 없음 | Network Loss 영향 관찰 |
1차 개선 | tries 3, timeout 3 | 실패율 감소 시도 |
2차 개선 | tries 2, timeout 2 | 실패율과 tail latency 균형 최적화 (최종 채택) |
2. 실험 환경
•
대상 서비스: podinfo (http://podinfo.chaos-lab.local)
•
부하 도구: k6 (Rate 15 req/s, Duration 6m)
•
장애 주입: Chaos Mesh (NetworkChaos)
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: podinfo-network-loss
namespace: chaos-mesh
spec:
action: loss
mode: one
duration: "2m"
selector:
namespaces:
- podinfo
labelSelectors:
app.kubernetes.io/name: podinfo
loss:
loss: "50"
correlation: "50"
YAML
복사
mode: one으로 podinfo Pod 중 하나에만 50% 패킷 손실을 주입했다. 나머지 Pod는 정상 상태를 유지하므로, Ingress가 upstream error/timeout을 감지했을 때 다른 정상 endpoint로 재시도할 여지가 있는 시나리오다.
•
모니터링: Prometheus + Grafana
3. 개선 전
결과
지표 | 값 |
총 요청 수 | 5,384 건 |
실패율 | 0.78% (42건) |
p50 latency | 2.45ms |
p90 latency | 37.33ms |
p95 latency | 210.60ms |
p99 latency | 870.26ms |
max latency | 3,002ms |
checks 통과율 | 99.13% |
Grafana 대시보드
패킷 손실이 주입된 구간에서 p95/p99 latency가 급격히 상승했고, fail count가 42건(0.78%)으로 baseline(0.28%) 대비 약 3배 수준이었다. 개선 전에는 Network Loss 대응을 위한 명시적인 Ingress retry/timeout annotation을 적용하지 않았다. 이 상태에서는 패킷 손실이 발생한 Pod로 라우팅된 일부 요청이 timeout 또는 연결 오류로 이어지며 failed rate와 tail latency가 증가했다.
4. 개선 — NGINX Ingress retry 설정 적용
mode: one으로 하나의 Pod에만 패킷 손실이 주입되므로, Ingress에서 실패한 요청을 다른 정상 Pod로 재시도하도록 retry 설정을 적용했다. 공통 설정은 다음과 같이 유지하고, proxy-next-upstream-tries와 proxy-next-upstream-timeout만 두 차례 변경해 비교했다.
# apps/podinfo/local/values.yaml (Ingress annotations)
nginx.ingress.kubernetes.io/proxy-connect-timeout: "1"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1"
nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout http_500 http_502 http_503 http_504"
nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "2"
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "2"
YAML
복사
retry 횟수(proxy-next-upstream-tries)와 총 retry 허용 시간(proxy-next-upstream-timeout)을 조합해 두 가지 설정을 비교했다.
단계 | tries | next-upstream-timeout |
1차 개선 | 3 | 3s |
2차 개선 | 2 | 2s |
tries 3 / timeout 3 설정은 더 많은 upstream 재시도 기회를 제공하지만, 실패한 upstream을 거친 요청이 더 오래 대기할 수 있어 tail latency가 증가할 수 있다.
5. 1차 개선 결과 (tries 3, timeout 3)
결과
지표 | 개선 전 | 1차 개선 | 변화 |
실패율 | 0.78% (42건) | 0.46% (25건) | 감소 |
p50 latency | 2.45ms | 2.13ms | 유사 |
p90 latency | 37.33ms | 17.95ms | 감소 |
p95 latency | 210.60ms | 209.31ms | 유사 |
p99 latency | 870.26ms | 1,002.57ms | 악화 |
max latency | 3,002ms | 2,014ms | 감소 |
checks 통과율 | 99.13% | 99.01% | 유사 |
실패율은 0.78% → 0.46%로 줄었지만, p99 latency가 870ms → 1,002ms로 오히려 악화되었다. retry 설정의 부작용으로 해석할 수 있다. tries 3 × timeout 3s 조합은 성공으로 전환된 요청이라도 최대 수 초에 걸친 재시도 대기 시간을 거쳐야 하므로, tail latency가 retry 누적으로 늘어날 수 있다. 즉 1차 개선은 HTTP 실패율을 낮추는 데는 효과가 있었지만, latency check와 p99 관점에서는 retry 비용이 tail latency로 전가된 것으로 볼 수 있다.
Grafana 대시보드
6. 2차 개선 결과 (tries 2, timeout 2) — 최종 채택
결과
지표 | 개선 전 | 1차 개선 | 2차 개선 | 변화 |
실패율 | 0.78% (42건) | 0.46% (25건) | 0.56% (30건) | 개선 전 대비 감소 |
p50 latency | 2.45ms | 2.13ms | 2.08ms | 유사 |
p90 latency | 37.33ms | 17.95ms | 12.12ms | 감소 |
p95 latency | 210.60ms | 209.31ms | 76.44ms | 크게 감소 |
p99 latency | 870.26ms | 1,002.57ms | 872.13ms | 개선 전 수준 회복 |
max latency | 3,002ms | 2,014ms | 2,003ms | 감소 |
checks 통과율 | 99.13% | 99.01% | 99.27% | 개선 |
tries 2, timeout 2로 줄이자 p95가 210ms → 76ms로 크게 낮아졌고, 1차 개선에서 악화되었던 p99도 870ms 수준으로 회복되었다. 실패율(0.56%)은 개선 전(0.78%)보다 낮고, retry 비용으로 인한 tail latency 부담도 1차 대비 완화되었다.
Grafana 대시보드
7. 결론 및 학습 내용
결론
Network Loss는 mode: one으로 일부 Pod에만 패킷 손실을 주입하는 시나리오로, Ingress retry 설정이 실질적인 대응 수단이 될 수 있다. 다만 retry 횟수와 timeout은 실패율과 tail latency 사이의 trade-off를 직접 결정하는 파라미터다. tries 3, timeout 3 조합은 실패율을 줄였지만 p99를 악화시켰고, tries 2, timeout 2로 줄이자 p95가 크게 낮아지면서 전반적인 균형이 개선되었다. 이번 실험은 GET 요청 중심의 부하에서 retry 효과를 검증한 것이다. 실제 운영 환경에서 POST, 결제, 주문 생성과 같은 비멱등 요청에 retry를 적용할 경우 중복 처리 가능성을 별도로 고려해야 한다.
학습 내용
•
retry 설정은 실패율과 tail latency를 동시에 개선할 수 없는 trade-off를 가진다. tries × timeout이 클수록 더 많은 요청이 재시도 과정에서 성공으로 전환되지만, 재시도를 거치는 요청 자체의 응답 시간이 길어져 상위 percentile latency를 악화시킨다. 이번 실험에서 1차 개선이 p99를 악화시킨 것이 그 예다.
•
retry 설정의 적정 수준은 시스템의 SLO(어느 지표를 우선시하는가)에 따라 달라진다. 실패율을 낮추는 것이 우선이라면 tries를 늘리는 방향으로, tail latency를 통제하는 것이 우선이라면 tries와 timeout을 줄이는 방향으로 설계해야 한다. 두 목표를 동시에 달성하려면 retry 대신 upstream의 근본적인 안정성을 높이는 접근이 필요하다.
•
proxy-next-upstream-tries와 proxy-next-upstream-timeout은 각각 독립적으로도 동작하지만 실질적인 한계는 둘 중 먼저 도달하는 조건에 의해 결정된다. timeout을 짧게 유지하는 것이 tail latency 제어에 더 직접적인 효과를 가진다.
부록. NGINX Ingress retry 설정
항목 | 값 |
proxy-connect-timeout | 1s |
proxy-read-timeout | 1s |
proxy-send-timeout | 1s |
proxy-next-upstream | error, timeout, http_500~504 |
proxy-next-upstream-tries | 2 |
proxy-next-upstream-timeout | 2s |


