{
  "test_id": "T93",
  "verdict": "pass",
  "environment": {
    "date": "2026-07-05",
    "cluster": "homelab (kubespray bare-metal, k8s v1.30.6, CNI Calico, cluster domain homelab.local)",
    "istio_version": "1.30.0",
    "istioctl": "1.30.0 (client/control-plane/data-plane 일치)",
    "lab_kit": "content/docs/istio/egress/dr-connection-settings/files/lab/ (setup.sh · run-scenario.sh · cleanup.sh · 00~30.yaml · dr-scenarios/s1~s7)"
  },
  "observed": "번들 랩 킷 files/lab/ 만으로 DR connectionPool 발동 재현 랩의 전체 생애주기(cleanup→setup→s1~s7→cleanup)를 라이브로 재현했다. setup.sh 는 cluster domain 을 coredns Corefile 에서 homelab.local 로 자동 발견했고 backend/client sidecar 가 문제없이 rollout 됐다. 판정은 프록시 기동 이래 누적되는 cx/rq 카운터를 이 run 내 before→after 델타로 격리해 내렸다. S1(maxConnections:1): mid-load 게이지 circuit_breakers.default.cx_open=1, upstream_cx_overflow +41, 요청은 모두 200(초과분은 default 무제한 pending 으로 흡수). S2(+http1MaxPendingRequests:1): rq_pending_open=1, upstream_rq_pending_overflow +12 = fortio 503 12건과 정확히 일치(즉시 거부/UO). S3(maxRequestsPerConnection:1): upstream_cx_max_requests +20, upstream_cx_total +20(거부 아닌 UPSTREAM 커넥션 turnover — fortio 다운스트림은 Sockets 1 로 안 보임). S4(http.idleTimeout:2s): upstream_cx_idle_timeout +1. S5(tcp.maxConnectionDuration:5s): upstream_cx_max_duration_reached +2(10s 창에서 5s 수명 2회 교체, graceful 200 100%). S6(connectTimeout:1s, blackhole→198.51.100.10): upstream_cx_connect_timeout +15, 액세스로그 503 URX,UF upstream_reset_before_response_started{connection_timeout}, auto-VIP 240.240.0.12→198.51.100.10. S7 config: tcp_keepalive{probes3,time300,interval30}, circuit_breakers.thresholds maxRetries=2·나머지 4294967295, http2_protocol_options.maxConcurrentStreams=64, useClientProtocol→use_downstream_protocol_config 존재+explicit h2 승격 ABSENT 을 istioctl pc cluster config_dump 로 확인. cleanup.sh 로 DR/SE→namespace 삭제 후 NotFound, 멱등 통과.",
  "claims": [
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "KIT",
      "empirical": "supports-claim",
      "note": "번들 킷(files/lab/) 만으로 cleanup→setup→s1~s7→cleanup 전체 생애주기를 독자가 자기 클러스터에서 재현 가능함을 라이브 확인. setup.sh 는 CTX 자동 감지 + cluster domain 자동 발견(homelab.local), run-scenario.sh 는 conn-dr/conn-blackhole-dr 이름 재사용으로 같은 host 다중 DR 스택 회피 + run 내 델타로 판정, cleanup.sh 는 --ignore-not-found 로 멱등."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S1",
      "empirical": "supports-claim",
      "note": "tcp.maxConnections:1 → circuit_breakers.thresholds[].max_connections. 실측: mid-load gauge circuit_breakers.default.cx_open=1, upstream_cx_overflow delta +41, upstream_cx_total +2, 요청 200 100%(거부 아닌 pending 흡수). 커넥션 서킷브레이커 발동 확인."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S2",
      "empirical": "supports-claim",
      "note": "tcp.maxConnections:1 + http.http1MaxPendingRequests:1 → +max_pending_requests. 실측: gauge rq_pending_open=1, upstream_rq_pending_overflow delta +12 = fortio Code 503 12건과 정확히 일치(즉시 거부/UO). 공식 circuit-breaking task 패턴 재현."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S3",
      "empirical": "supports-claim",
      "note": "http.maxRequestsPerConnection:1 → common_http_protocol_options.max_requests_per_connection. 실측: upstream_cx_max_requests +20, upstream_cx_total +20(요청 수만큼 신규 커넥션). 거부 아닌 커넥션 turnover이며, fortio 다운스트림은 Sockets used 1(재사용)로 turnover 가 안 보임 = UPSTREAM(sidecar→backend)에서만 발생하는 관측 함정 확인."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S4",
      "empirical": "supports-claim",
      "note": "http.idleTimeout:2s → common_http_protocol_options.idle_timeout. 실측: 요청 1회 후 5s idle 대기에 upstream_cx_idle_timeout +1, upstream_cx_total +1. 활성 요청 없는 풀 커넥션의 idle 종료 확인."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S5",
      "empirical": "supports-claim",
      "note": "tcp.maxConnectionDuration:5s → common_http_protocol_options.max_connection_duration(HTTP 클러스터 경로, 이름은 tcp.* 지만 S7 config 로 위치 확인). 실측: keepalive 10s 부하에 upstream_cx_max_duration_reached +2(5s 수명 2회 교체), upstream_cx_total +2, 200 100%(graceful close)."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S6",
      "empirical": "supports-claim",
      "note": "tcp.connectTimeout:1s(blackhole→198.51.100.10) → Cluster.connect_timeout. 실측: upstream_cx_connect_timeout delta +15, upstream_cx_connect_fail +15, 액세스로그 503 URX,UF upstream_reset_before_response_started{connection_timeout}. UF(upstream connection failure) + 상세 connection_timeout 확인. auto-VIP 240.240.0.12→STATIC endpoint 198.51.100.10 라우팅(sidecar DNS 프록시)."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S7-config",
      "empirical": "supports-claim",
      "note": "config 반영 검증(발동 아님): ① upstream_connection_options.tcp_keepalive={probes:3,time:300,interval:30} ② circuit_breakers.thresholds maxRetries=2 ③④ explicit_http_config.http2_protocol_options.maxConcurrentStreams=64 ④' useClientProtocol:true→use_downstream_protocol_config 존재 + explicit h2 승격 ABSENT(무력화). istioctl pc cluster --fqdn backend.conn-lab.svc.homelab.local -o json 으로 4종 반영 위치·값 확인."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S7-defaults-§5-2",
      "empirical": "supports-claim",
      "note": "연구 §5-2 확정: connectionPool 을 걸고 circuit breaker 필드를 생략하면 Istio 가 thresholds 에 4294967295(=2^32-1)를 명시 주입. S7-full 은 maxConnections/maxPendingRequests/maxRequests=4294967295(maxRetries 만 설정값 2), S7c 는 4종 전부 4294967295. 즉 'DR 을 걸면' 사실상 무제한을 명시 주입 → Envoy native 기본(1024/1024/1024/3)은 DR 을 아예 안 걸 때만 유효."
    },
    {
      "doc": "istio/egress/dr-connection-settings",
      "cid": "S7-defaults-§5-1",
      "empirical": "supports-claim",
      "note": "연구 §5-1 확정: h2UpgradePolicy:UPGRADE 이되 maxConcurrentStreams 를 생략하면 Istio 는 http2_protocol_options={} 로 아무 값도 주입하지 않는다(2^31-1 도 1024 도 config 에 안 나타남). 실효 기본값은 Envoy proto 기본(1024)이 런타임에 적용되는 것이며, istio.io 문서의 '2^31-1'은 config_dump 에 나타나는 값이 아니다. 설정 시(64)만 명시됨."
    }
  ],
  "deviations": [
    "연구 §5-3 정정: 연구 인벤토리는 upstream_rq_active_overflow 가 'cluster_stats 레퍼런스에 없는 카운터'라 가정했으나, 이 실측에서는 실제로 노출됨(blackhole·xds-grpc 클러스터에서 값 0 관측). 다만 http2MaxRequests '발동' 자체는 S1~S7 범위 밖(H2 업스트림 오버플로 시나리오 미수행)이라, http2MaxRequests 초과가 active_overflow 로 집계되는지 pending_overflow 로 집계되는지는 미검증. S2 에서 http1MaxPendingRequests 발동은 upstream_rq_pending_overflow 로 집계 확인.",
    "S6 신규 발견(연구에 없던 상호작용): connectTimeout 단독이 아니라 Istio 기본 mesh 재시도 정책(기본 2회)이 connect 실패마다 재시도 → 요청당 connect 시도 3회(cx_connect_timeout 이 요청 5개에 +15) → 요청당 ~3s 지연 → 최종 response flag URX(retry limit exceeded)까지 함께 관측. 실무에서 connectTimeout 지연 체감은 'connectTimeout × (1+기본재시도)'로 곱해짐.",
    "maxRetries 의 '발동'(URX by max_retries circuit breaker) 재현은 T93 범위 밖(난이도 높음 — 동시 재시도 폭증 유도 필요). S7 에서 config 반영(circuit_breakers.thresholds.max_retries=2)만 확인. S6 의 URX 는 max_retries CB overflow 가 아니라 retry policy 의 retry-limit-exceeded 로, 별개 메커니즘임에 유의.",
    "tcpKeepalive 발동은 소켓 옵션이라 stat 재현이 불가능(연구 §1-A). S7 config_dump 의 upstream_connection_options.tcp_keepalive 로만 검증(발동 관측 아님).",
    "관측 스코프 주의: filter=backend 는 타 ns 의 backend.service-a 클러스터도 매칭 → 하네스는 filter=backend.conn-lab 로 스코프. stat 이름은 세미콜론 구분자 형식(cluster.<name>;.<metric>: value). cx/rq 카운터는 누적이라 판정은 항상 run 내 델타로 격리했고, 파드 재시작 후 미사용 overflow 카운터가 lazy 하게 사라졌다 재등장하는 것도 관측."
  ]
}
