Hvordan man åbner en tunnel i en Kubernetes pod eller container med tcpserver og netcat

Bem. overs.: Denne praktiske note fra skaberen af LayerCI er en fremragende illustration af såkaldte tips & tricks til Kubernetes (og ikke kun). Løsningen her er kun en af få og, muligvis, ikke den mest oplagte (i nogle tilfælde kan den nævnte ‘native’ til K8s være passende). kubectl port-forward). Men det giver i det mindste mulighed for at se på problemet fra perspektivet af anvendelsen af klassiske værktøjer og deres videre kombination — samtidig enkelt, fleksibelt og kraftfuldt (se ‘andre idéer’ i slutningen for inspiration).

Hvordan man åbner en tunnel i en Kubernetes pod eller container med tcpserver og netcat

Forestil dig en typisk situation: du vil have, at en port på din lokale computer magisk omdirigerer trafik til en pod/kontainer (eller vice versa).

Mulige brugsituationer

  1. Tjek hvad HTTP endpointet returnerer /healthz pod’en i produktionsklassen.
  2. Forbind en TCP-debugger til pod’en på den lokale maskine.
  3. Få adgang til produktionsdatabasen fra lokale værktøjer uden at skulle rode med autentificering (normalt har localhost root-rettigheder).
  4. Køre et engangs migrationsscript for data i staging-klassen uden at skulle oprette en container til det.
  5. Forbind en VNC-session til pod’en med en kørende virtuel desktop (se XVFB).

Nogle ord om nødvendige værktøjer

Tcpserver — Open Source-værktøj, tilgængeligt i de fleste Linux-pakke-repositories. Det giver mulighed for at åbne en lokal port og omdirigere trafik til den via stdin/stdout fra en hvilken som helst angivet kommando:

colin@colin-work:~$ tcpserver 127.0.0.1 8080 echo -e 'HTTP/1.0 200 OK
Content-Length: 19<body>hej!</body>'&amp;
[1] 17377
colin@colin-work:~$ curl localhost:8080
<body>hej!</body>colin@colin-work:~$

(asciinema.org)

Netcat gør det modsatte. Det giver mulighed for at forbinde til en åben port og sende den modtagne input/output til 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:~$

(asciinema.org)

I ovenstående eksempel anmoder netcat om siden via HTTP. Flaget -C tvinger det til at tilføje CRLF i slutningen af linjen.

Sammenkobling med kubectl: lyt på værten og forbind til pod’en

Hvis vi kombinerer de præsenterede værktøjer med kubectl, får vi en kommando som denne:

tcpserver 127.0.0.1 8000 kubectl exec -i web-pod nc 127.0.0.1 8080

På samme måde, for at få adgang til port 80 inden i pod’en, er det nok at gøre 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

(asciinema.org)

Hvordan man åbner en tunnel i en Kubernetes pod eller container med tcpserver og netcat
Interaktionsskema for værktøjer

I den modsatte retning: lyt i pod'en og tilslut til værten

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

Denne kommando gør det muligt for pod'en at få adgang til port 8000 på den lokale maskine.

Bash-script

Jeg har skrevet et specialscript til Bash, der gør det muligt at administrere en produktions Kubernetes-klynge LayerCI, ved at bruge den ovenfor beskrevne metode:

kubetunnel() {
    POD="$1"
    DESTPORT="$2"
    if [ -z "$POD" -o -z "$DESTPORT" ]; then
        echo "Brug: kubetunnel [pod navn] [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 for access to $POD:$DESTPORT"
}

Hvis du tilføjer denne funktion til ~\/ .bashrc, kan du nemt åbne en tunnel i pod med kommandoen kubetunnel web-pod 8080 og udføre curl localhost:6666.

  • For tunnelen i Docker kan du ændre den primære linje til:
    tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
  • for tunnelen i K3s — ændr den til:
    tcpserver 127.0.0.1 6666 k3s kubectl exec …
  • osv.

Andre idéer

  • Du kan omdirigere UDP-trafik med kommandoerne netcat -l -u -c i stedet for tcpserver og netcat -u i stedet for netcat henholdsvis.
  • Se input/output gennem pipe viewer:

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

  • Du kan komprimere og dekomprimere trafik i begge ender ved hjælp af gzip.
  • For at forbinde til en anden computer med den relevante fil kubeconfig:

    tcpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80"

  • Du kan forbinde to pod'er i forskellige klynger ved hjælp af mkfifo og køre to separate kommandoer kubectl.

Mulighederne er uendelige!

P.S. fra oversætteren

Læs også på vores blog:

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster