It's a common scenario: You want a port on your local computer to magically forward traffic to your pod/container (or vice-versa.)

Use cases

  1. Check what the /healthz HTTP endpoint of a pod is returning in a production cluster
  2. Attach a TCP debugger to a pod running locally.
  3. Access the production database from local database tools without needing to fiddle with auth (usually localhost has root auth)
  4. Run a one-time migration script on data in a staging cluster without needing to create a container for it.
  5. Connect a VNC session to a pod with a virtual desktop running in it (see: XVFB)

Introducing the tools

"tcpserver" is an open source utility that's available in most linux package repositories. It lets you open a local port and forward traffic via stdin/stdout to any command you specify.

"netcat" is the opposite. It lets you make a connection to an open port and forward the input/output provided to it through stdin/stdout:

The above example  requests an HTTP page using netcat. The -C flag sets netcat to send HTTP line endings.

Combine with kubectl: Listen on host and connect to pod

If we combine the tools above with kubectl, we get a command like this:

tcpserver 8000 kubectl exec -i web-pod nc 8080

Which then lets us curl "" to access port 80 internally in the pod:

Diagram for what programs are connecting to what

In reverse: Listen in pod and connect to host:

nc 8000 | kubectl exec -i web-pod tcpserver 8080 cat

This command would allow the web pod to access port 8000 on the local computer.

Utility bash script

I've made a utility bash script to manage LayerCI's production kubernetes cluster with this method:

kubetunnel() {
    if [ -z "$POD" -o -z "$DESTPORT" ]; then
    	echo "Usage: kubetunnel [pod name] [destination port]"
        return 1
    pkill -f 'tcpserver 6666'
    tcpserver 6666 kubectl exec -i "$POD" nc "$DESTPORT"&
    echo "Connect to to access $POD:$DESTPORT"

Appending this function to my ~/.bashrc lets me kubetunnel web-pod 8080 and curl localhost:6666 easily.

Equivalently, you can use tcpserver 6666 docker exec -i "$CONTAINER" nc "$DESTPORT" for a dockertunnel script, or tcpserver 6666 k3s kubectl exec ... for a k3stunnel script, et cetera.

Other ideas

  • Forward UDP traffic with netcat -l -u -c instead of tcpserver and netcat -u instead of netcat respectively
  • View I/O with "pipe viewer": nc 8000 | pv --progress | kubectl exec -i web-pod tcpserver 8080 cat
  • Compress and decompress traffic with gzip at both ends.
  • Connect to another computer that has your kubeconfig on it with ssh: tcpserver ssh workcomputer "kubectl exec -i my-pod nc 80"
  • Connect two pods in two different clusters with mkfifo and starting two separate kubectl commands
  • The opportunities are limitless!