#!/usr/bin/env bash # T48: L4 tcp_proxy downstream:upstream connection mapping (1:1, no pooling/multiplexing) # # NOTE on adaptations vs. the raw spec (see result.txt for full discovery log): # 1. Cluster's default meshConfig proxyStatsMatcher excludes raw per-cluster Envoy stats from the # plain-text /stats endpoint. We add pod annotation # sidecar.istio.io/statsInclusionRegexps: ".*upstream_cx_total.*" to the client pod so the # spec's literal `curl localhost:15000/stats | grep ... upstream_cx_total` observation works. # 2. The ServiceEntry's declared host (mock.istio-verify-ext.svc.homelab.local) resolves via CoreDNS # to the SAME ClusterIP as the real k8s Service `mock`, which already has its own dedicated # per-VIP Envoy listener (tcp_proxy -> outbound|443||mock.istio-verify-ext.svc.cluster.local, # Istio's internal default clusterDomain, independent from kubeadm's actual homelab.local # domain). That dedicated listener wins over the generic 0.0.0.0:443 SNI-passthrough listener # where the ServiceEntry's own cluster lives, so real traffic never touches the SE's cluster. # Both clusters are confirmed (via config_dump) to use envoy.filters.network.tcp_proxy, so we # observe the cluster that ACTUALLY carries the traffic (svc.cluster.local) instead. set -euo pipefail NS="istio-vt-t48" DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CLUSTER_FILTER='outbound|443||mock.istio-verify-ext.svc.cluster.local.*upstream_cx_total' cleanup() { kubectl delete namespace "$NS" --wait=false --ignore-not-found >/dev/null 2>&1 || true } trap cleanup EXIT kubectl create namespace "$NS" kubectl label namespace "$NS" istio-injection=enabled kubectl apply -f "$DIR/manifest.yaml" kubectl -n "$NS" wait --for=condition=Ready pod/client --timeout=90s kubectl -n "$NS" rollout status deployment/echo --timeout=120s echo "=== BEFORE ===" kubectl -n "$NS" exec client -c istio-proxy -- curl -s 'localhost:15000/stats' | grep "$CLUSTER_FILTER" | tee /tmp/before_cx.txt echo "=== 5 separate short-lived connections ===" for i in $(seq 1 5); do kubectl -n "$NS" exec client -c curl -- curl -sk -o /dev/null --max-time 4 https://mock.istio-verify-ext.svc.homelab.local/ done echo "=== AFTER 5 ===" kubectl -n "$NS" exec client -c istio-proxy -- curl -s 'localhost:15000/stats' | grep "$CLUSTER_FILTER" | tee /tmp/after5_cx.txt echo "=== 3 requests over ONE reused connection (single curl invocation, keepalive) ===" kubectl -n "$NS" exec client -c curl -- curl -sk -o /dev/null --max-time 6 \ https://mock.istio-verify-ext.svc.homelab.local/ \ https://mock.istio-verify-ext.svc.homelab.local/ \ https://mock.istio-verify-ext.svc.homelab.local/ echo "=== AFTER REUSE ===" kubectl -n "$NS" exec client -c istio-proxy -- curl -s 'localhost:15000/stats' | grep "$CLUSTER_FILTER" | tee /tmp/after_reuse_cx.txt echo "=== SUMMARY ===" echo "before: $(cat /tmp/before_cx.txt)" echo "after5: $(cat /tmp/after5_cx.txt)" echo "after_reuse: $(cat /tmp/after_reuse_cx.txt)"