Kubernetes how-to
kubectl port-forward: Reach a Pod From Your Laptop
kubectl port-forward opens a tunnel from a port on your machine to a port inside the cluster, through the API server. Use it to reach a pod, a Deployment or a Service that has no public route, for example a database admin UI or an internal API you want to test. It is a debugging tool, not a way to serve traffic.
By Muhammad Soliman, Founder at SeaGit
·
Key takeaways
- The command forwards local ports to a pod, Deployment or Service. The syntax is LOCAL:REMOTE, and the local side defaults to the same number as the remote side.
- The session ends when the selected pod terminates. A Deployment or Service target picks one pod, so a rollout breaks the tunnel and you must run the command again.
- --address controls which local interfaces listen. The default is localhost. Binding to 0.0.0.0 exposes the port to your network, so do not do that on a shared machine.
- Port-forward is for debugging. Users reach production through a Service, an Ingress or a Gateway, not through a tunnel from a laptop.
The syntax and the three targets
The general form is kubectl port-forward TYPE/NAME with one or more port pairs. If you omit the type, kubectl treats the name as a pod. The three targets behave differently, and that matters when a pod restarts.
# A specific pod: local 8080 to pod port 80
kubectl port-forward pod/my-api-7c9f 8080:80 -n prod
# A Deployment: kubectl picks one of its pods
kubectl port-forward deployment/my-api 8080:80 -n prod
# A Service: forwards to the targetPort of a pod behind it
kubectl port-forward service/my-api 8443:https -n prod
# A random free local port, forwarding to 5000 in the pod
kubectl port-forward pod/my-api-7c9f :5000 -n prodWhy the tunnel drops, and how to keep it up
The official synopsis says the forwarding session ends when the selected pod terminates, and that a rerun is needed to resume. This is the most common surprise. A deploy, a node drain or an OOM kill replaces the pod, and your tunnel goes with it. There is no reconnect.
# Run the tunnel in the background, then stop it later
kubectl port-forward deployment/my-api 8080:80 -n prod &
echo $! > /tmp/pf.pid
# Stop it
kill "$(cat /tmp/pf.pid)"A simple reconnect loop
If you need the tunnel for a long debugging session, wrap it in a loop. The loop does not hide a crash, so keep the pod logs open in another window while it runs.
while true; do
kubectl port-forward deployment/my-api 8080:80 -n prod
echo "tunnel dropped, retrying in 2s" >&2
sleep 2
doneBind address: localhost is the safe default
By default the forwarded port listens on localhost. The reference shows that --address changes that. Listening on 0.0.0.0 makes the port reachable from every interface the machine has, including the office network or a coffee-shop Wi-Fi. A port forward carries the pod credentials of whatever the app exposes, so treat it as an open door.
# Safe: only this machine can connect (the default)
kubectl port-forward --address localhost pod/my-api-7c9f 8080:80 -n prod
# Exposes the port on every interface. Only on a machine you trust.
kubectl port-forward --address 0.0.0.0 pod/my-api-7c9f 8080:80 -n prodCommon errors and what they mean
Most failures come from the target, not from kubectl. Check the pod first, then the port.
- Pod is not running. The target pod is Pending, CrashLoopBackOff or already gone. Run kubectl get pods and kubectl describe pod, then fix the pod before the tunnel will work.
- Address already in use. Another process holds the local port. Pick another local port, for example 18080:80, or find the holder with lsof -i :8080.
- Connection works but the page is empty or 502. The tunnel is up, but the app listens on another port or on 127.0.0.1 inside the container. Check the container port in the manifest and the bind address in the app.
- Forward stops after a deploy. Expected. Rerun the command. A Deployment target now picks a new pod.
kubectl get pods -n prod -l app=my-api
kubectl get pod my-api-7c9f -n prod -o jsonpath='{.spec.containers[0].ports}{"\n"}'When not to use port-forward
Port-forward is a single-user, single-connection tool that depends on one pod. It is not a load balancer, it does not survive rollouts, and it routes through the API server, which is not built for data-plane traffic. For anything other people or services must call, expose the workload with a Service and an Ingress or a Gateway. For a stateful tool that runs on your laptop only, a port-forward is the right choice.