kubectl port-forward: Reach a Pod From the Runner
kubectl port-forward opens a local TCP port that tunnels through the API server to a pod or service port.
Integration tests on a runner often need to hit an in-cluster service. port-forward gives the job a localhost endpoint without exposing anything externally.
What it does
kubectl port-forward maps localPort:podPort and forwards traffic through the Kubernetes API server to the target pod (or a pod behind a service/deployment). It runs in the foreground until interrupted, so in CI you background it and wait for the port.
Common usage
kubectl port-forward pod/api 8080:8080
kubectl port-forward svc/api 8080:80 -n staging
# CI pattern: background, wait, run, clean up
kubectl port-forward svc/api 8080:80 >/dev/null 2>&1 &
PF=$!
until nc -z localhost 8080; do sleep 1; done
curl -fsS localhost:8080/health
kill $PFOptions
| Flag / Syntax | What it does |
|---|---|
| <local>:<remote> | Map a local port to the target port |
| :<remote> | Let kubectl choose a random free local port |
| svc/<name> | pod/<name> | Forward to a service or a specific pod |
| --address | Bind address(es), default 127.0.0.1 |
| -n, --namespace | Namespace of the target |
In CI
Background the process and store its PID so the job can kill it at the end; a leaked forward keeps the step alive. Wait for the port with nc -z or a curl retry loop rather than a fixed sleep. Forwarding to a Service load-balances to one backing pod, which is usually fine for a health check.
Common errors in CI
"error: unable to listen on any of the requested ports" means the local port is already in use; pick another or use :remote for a random one. "an error occurred forwarding ... connection refused" means the pod is not listening on that port yet; wait for readiness first. "lost connection to pod" appears if the pod restarts mid-forward; re-establish the forward.