=== CMD1: apply + wait (already done above, re-recording state) === $ kubectl apply -f manifest.yaml && kubectl -n istio-vt-t55 wait --for=condition=Ready pod/client --timeout=90s NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES client 2/2 Running 0 11s 10.255.159.183 k8s-master1 === CMD2: baseline sysctl BEFORE traffic === $ kubectl -n istio-vt-t55 exec client -c istio-proxy -- sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_time = 7200 === CMD3: generate traffic client->echo (background + foreground curl) === $ kubectl -n istio-vt-t55 exec client -c curl -- sh -c 'curl ... & sleep 2; curl ...' curl1 http_code=200 curl2 http_code=200 === CMD4: ss -to on istio-proxy to inspect upstream socket keepalive === $ kubectl -n istio-vt-t55 exec client -c istio-proxy -- ss -to dst echo.istio-vt-t55.svc.homelab.local State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess ESTAB 0 0 10.255.159.183:60042 10.250.194.224:http ESTAB 0 0 10.255.159.183:60058 10.250.194.224:http --- fallback: ss -to state established dport :80 --- Recv-Q Send-Q Local Address:Port Peer Address:PortProcess 0 0 10.255.159.183:60042 10.250.194.224:http 0 0 10.255.159.183:60058 10.250.194.224:http --- broader: all established tcp with timer info on istio-proxy --- State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 10.255.159.183:51232 10.250.46.228:15012 timer:(keepalive,119min,0) ESTAB 0 0 10.255.159.183:51246 10.250.46.228:15012 timer:(keepalive,119min,0) ESTAB 0 0 10.255.159.183:60042 10.250.194.224:80 ESTAB 0 0 10.255.159.183:60058 10.250.194.224:80 ESTAB 0 0 127.0.0.1:52274 127.0.0.1:15020 ESTAB 0 0 127.0.0.1:53076 127.0.0.1:15020 ESTAB 0 0 127.0.0.1:34278 127.0.0.1:15000 timer:(keepalive,14sec,0) ESTAB 0 0 127.0.0.1:15000 127.0.0.1:34278 ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:52274 timer:(keepalive,12sec,0) ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:53076 timer:(keepalive,589ms,0) === ENVIRONMENTAL FINDING: DR host mismatch === istioctl analyze warning: IST0174 - host echo.istio-vt-t55.svc.homelab.local does not match any services in the mesh Envoy cluster is actually named: outbound|80||echo.istio-vt-t55.svc.cluster.local (upstream_connection_options: null) Reason: this Istio install's internal service registry uses the default clusterDomain=cluster.local regardless of the kubeadm/coredns actual cluster domain (homelab.local). Only explicit ServiceEntries (e.g. mock.istio-verify-ext.svc.homelab.local) get custom-domain cluster names; auto-discovered k8s Services always get svc.cluster.local cluster names in this cluster. => The DR as literally specified (host=*.svc.homelab.local) is a silent no-op: it does not attach to any real Envoy cluster, so tcpKeepalive settings are NEVER pushed to the sidecar for that cluster. CORRECTIVE RETEST: patching DR host to the actual registered name (svc.cluster.local) to genuinely test the underlying claim (whether Istio's tcpKeepalive DR field manifests as socket keepalive option). === CORRECTED CLUSTER CONFIG (host=svc.cluster.local matches real Envoy cluster) === outbound|80||echo.istio-vt-t55.svc.cluster.local upstream_connection_options: {"tcp_keepalive": {"keepalive_probes": 5, "keepalive_time": 45, "keepalive_interval": 7}} === CMD3-retry: generate NEW traffic client->echo with corrected DR active === curl1 http_code=200 curl2 http_code=200 === CMD4-retry: ss -to on istio-proxy (post-fix) === State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess ESTAB 0 0 10.255.159.183:60042 10.250.194.224:http ESTAB 0 0 10.255.159.183:60058 10.250.194.224:http --- broader established view --- State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 10.255.159.183:51232 10.250.46.228:15012 timer:(keepalive,116min,0) ESTAB 0 0 10.255.159.183:51246 10.250.46.228:15012 timer:(keepalive,116min,0) ESTAB 0 0 10.255.159.183:60042 10.250.194.224:80 ESTAB 0 0 10.255.159.183:60058 10.250.194.224:80 ESTAB 0 0 127.0.0.1:52274 127.0.0.1:15020 ESTAB 0 0 127.0.0.1:53076 127.0.0.1:15020 ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:52274 timer:(keepalive,8.395ms,0) ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:53076 timer:(keepalive,8.225ms,0) === Restarted client pod to force FRESH upstream connections under corrected DR === new client pod IP: 10.255.159.186 === CMD2-final: baseline sysctl on fresh pod === net.ipv4.tcp_keepalive_time = 7200 === CMD3-final: generate fresh traffic === curl1 http_code=200 curl2 http_code=200 === CMD4-final: ss -to on fresh connection === State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess ESTAB 0 0 10.255.159.186:33482 10.250.194.224:http ESTAB 0 0 10.255.159.186:38670 10.250.194.224:http --- full established view --- State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 127.0.0.1:15000 127.0.0.1:58546 ESTAB 0 0 10.255.159.186:33482 10.250.194.224:80 ESTAB 0 0 127.0.0.1:58546 127.0.0.1:15000 timer:(keepalive,14sec,0) ESTAB 0 0 10.255.159.186:39106 10.250.46.228:15012 timer:(keepalive,119min,0) ESTAB 0 0 10.255.159.186:39112 10.250.46.228:15012 timer:(keepalive,119min,0) SYN-SENT 0 1 10.255.159.186:48494 169.254.169.254:80 timer:(on,2.219ms,7) ESTAB 0 0 127.0.0.1:48384 127.0.0.1:15020 ESTAB 0 0 10.255.159.186:38670 10.250.194.224:80 SYN-SENT 0 1 10.255.159.186:48508 169.254.169.254:80 timer:(on,2.283ms,7) ESTAB 0 0 127.0.0.1:48396 127.0.0.1:15020 ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:48384 timer:(keepalive,12sec,0) ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:48396 timer:(keepalive,,0) === SECOND environmental finding: HTTP virtual-host routing ALSO keyed to cluster.local, not homelab.local === RDS route config '80' virtual host domains for our service: ['echo.istio-vt-t55.svc.cluster.local', ..., 'echo', 'echo.istio-vt-t55.svc', 'echo.istio-vt-t55', '10.250.194.224'] NOTE: NO homelab.local domain alias present. Live cluster stats confirmed the actual traffic fell through to PassthroughCluster (bypassing ALL Istio per-service policy) because curl's Host header 'echo.istio-vt-t55.svc.homelab.local' matched no virtual host in the shared HTTP:80 listener's route table: PassthroughCluster::10.250.194.224:80::cx_active::2 (our 2 curls) outbound|80||echo.istio-vt-t55.svc.cluster.local::...::cx_active::0, cx_total::0 CORRECTIVE RETEST 2: using 'curl http://echo/' (bare short name IS a registered virtual-host alias and IS in DNS search domain, so it resolves fine AND matches Istio's route table) to reach the real named cluster and genuinely observe the DR's tcpKeepalive effect. === CMD3-retry2: traffic using Host-matching short name === curl1 http_code=200 curl2 http_code=200 === CMD4-final-genuine: ss -to shows keepalive timer on properly-routed connection === ESTAB 10.255.159.186:45696 -> 10.255.159.184:8080 (echo pod IP, via named cluster w/ DR) timer:(keepalive,37sec,0) DR configured time=45s; observed ~37sec remaining ~8s after last data exchange -- consistent with 45s keepalive timer. cluster stats: outbound|80||echo.istio-vt-t55.svc.cluster.local cx_active=1, cx_total=1 (this request landed on the DR-governed cluster) (the OTHER two stale connections 33482/38670 remain on PassthroughCluster (Host-header mismatch, no timer -- expected, since PassthroughCluster has no custom keepalive)) === CMD5-final: sysctl re-check AFTER traffic w/ correct routing -- must remain unchanged (7200) === net.ipv4.tcp_keepalive_time = 7200 === SUMMARY === Two nested environmental gotchas discovered in this cluster (kubeadm clusterDomain=homelab.local but Istio internal service-registry/route-table domain defaults to cluster.local, unconfigured): 1. DestinationRule host=*.svc.homelab.local does not match any mesh service (istioctl analyze IST0174) -> DR is a no-op. 2. Even with DR host corrected to cluster.local, HTTP traffic addressed via a homelab.local Host header does not match any RDS virtual-host domain on the shared 0.0.0.0_80 listener -> falls through to PassthroughCluster (bypasses ALL per-service Istio policy silently, still returns 200 OK). After correcting BOTH (DR host -> svc.cluster.local; curl target -> bare short name 'echo', a registered virtual-host alias) the traffic landed on cluster outbound|80||echo.istio-vt-t55.svc.cluster.local (cx_total=1) and ss -to showed timer:(keepalive,37sec,0) on the direct client->pod:8080 socket (45s configured minus ~8s elapsed = ~37s, consistent). sysctl net.ipv4.tcp_keepalive_time stayed at 7200 (kernel default) both before and after -- unchanged by the DR. CONCLUSION: DR tcpKeepalive time/interval/probes DOES manifest as a per-socket SO_KEEPALIVE override (setsockopt), NOT a netns-wide sysctl change -- claim C1 supported, once traffic actually reaches the DR-governed Envoy cluster (which required correcting for the homelab.local/cluster.local mismatch).