Note: translation.: This practical note from the creator of LayerCI is an excellent illustration of the so-called tips & tricks for Kubernetes (and beyond). The solution proposed here is just one of the few and perhaps not the most obvious ones (for some cases, the 'native' for K8s mentioned in the comments might suffice). ). However, it at least allows you to look at the problem from the perspective of applying classic utilities and their further combination — simultaneously simple, flexible, and powerful (see 'other ideas' at the end for inspiration).

Imagine a typical situation: you want a port on your local computer to magically redirect traffic to a pod/container (or vice versa).
Possible use cases
- Check what an HTTP endpoint returns
/healthzof the pod in the production cluster. - Connect a TCP debugger to the pod on your local machine.
- Access the production database from local database management tools without having to deal with authentication (usually, localhost has root permissions).
- Run a one-off migration script for data in the staging cluster without needing to create a container for it.
- Connect a VNC session to the pod running a virtual desktop (see XVFB).
A few words about necessary tools
— An open-source utility available in most Linux package repositories. It allows you to open a local port and redirect traffic received via stdin/stdout from any specified command:
colin@colin-work:~$ tcpserver 127.0.0.1 8080 echo -e 'HTTP/1.0 200 OK\nContent-Length: 19\n\n<body>hello!</body>'&\n[1] 17377\ncolin@colin-work:~$ curl localhost:8080
<body>hello!</body>colin@colin-work:~$()
Netcat does the opposite. It allows you to connect to an open port and send the input/output received from it to stdin/stdout:
colin@colin-work:~$ nc -C httpstat.us 80
GET /200 HTTP/1.0
Host: httpstat.us
HTTP/1.1 200 OK
Cache-Control: private
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.1
Access-Control-Allow-Origin: *
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=93fdbab9d364704de8ef77182b4d13811344b7dd1ec45d3a9682bbd6fa154ead;Path=/;HttpOnly;Domain=httpstat.us
Date: Fri, 01 Nov 2019 17:53:04 GMT
Connection: close
Content-Length: 0
^C
colin@colin-work:~$()
In the example above, netcat requests the page via HTTP. The flag -C causes it to append CRLF at the end of the line.
Combining with kubectl: listen on the host and connect to the pod
If we combine the tools presented above with kubectl, we would get a command like this:
tcpserver 127.0.0.1 8000 kubectl exec -i web-pod nc 127.0.0.1 8080 Similarly, to access port 80 inside the pod, you just need to do curl "127.0.0.1:80":
colin@colin-work:~$ sanic kubectl exec -it web-54dfb667b6-28n85 bash
root@web-54dfb667b6-28n85:/web# apt-get -y install netcat-openbsd
Reading package lists... Done
Building dependency tree
Reading state information... Done
netcat-openbsd is already the newest version (1.195-2).
0 upgraded, 0 newly installed, 0 to remove and 10 not upgraded.
root@web-54dfb667b6-28n85:/web# exit
colin@colin-work:~$ tcpserver 127.0.0.1 8000 sanic kubectl exec -i web-54dfb667b6-28n85 nc 127.0.0.1 8080&
[1] 3232
colin@colin-work:~$ curl localhost:8000/healthz
{"status":"ok"}colin@colin-work:~$ exit()

Utility Interaction Diagram
In the opposite direction: listen in the pod and connect to the host
nc 127.0.0.1 8000 | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 catThis command allows the pod to access port 8000 on the local machine.
Bash Script
I wrote a special Bash script to manage the production Kubernetes cluster. , using the method described above:
kubetunnel() {
POD="$1"
DESTPORT="$2"
if [ -z "$POD" -o -z "$DESTPORT" ]; then
echo "Usage: kubetunnel [pod name] [destination port]"
return 1
fi
pkill -f 'tcpserver 127.0.0.1 6666'
tcpserver 127.0.0.1 6666 kubectl exec -i "$POD" nc 127.0.0.1 "$DESTPORT"&
echo "Connect to 127.0.0.1:6666 to access $POD:$DESTPORT"
} If you add this function to ~/ .bashrc, you can easily open a tunnel to the pod with the command kubetunnel web-pod 8080 and execute curl localhost:6666.
- For the tunnel in Docker you can replace the main line with:
tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT" - for the tunnel in K3s — change it to:
tcpserver 127.0.0.1 6666 k3s kubectl exec … - etc.
Other Ideas
- Redirecting UDP traffic can be done with commands
netcat -l -u -cinstead oftcpserverandnetcat -uinstead ofnetcatrespectively. - View input/output through pipe viewer:
nc 127.0.0.1 8000 | pv --progress | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 cat - Traffic can be compressed and decompressed on both ends using
gzip. - Connect via SSH to another computer with the appropriate file
kubeconfig:tcpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80" - You can connect two pods in different clusters using
mkfifoand run two separate commandskubectl.
The possibilities are endless!
P.S. from the translator
Also read in our blog:
- «»;
- «»;
- «»;
- «».
Source: habr.com
