Sådan åbner du en tunnel i en Kubernetes pod eller container med tcpserver og netcat

Bemærk. overs.: Denne praktiske note fra skaberen af ​​LayerCI er en fremragende illustration af de såkaldte tips & tricks til Kubernetes (og mere). Den her foreslåede løsning er kun en af ​​de få og måske ikke den mest åbenlyse (i nogle tilfælde kan den "native" for K8'ere, der allerede er nævnt i kommentarerne, være egnet kubectl port-forward). Det giver dig dog mulighed for i det mindste at se på problemet ud fra perspektivet om at bruge klassiske hjælpeprogrammer og yderligere kombinere dem - på samme tid enkel, fleksibel og kraftfuld (se "andre ideer" til sidst for inspiration).

Sådan åbner du en tunnel i en Kubernetes pod eller container med tcpserver og netcat

Forestil dig en typisk situation: du vil have en port på din lokale maskine til på magisk vis at videresende trafik til en pod/container (eller omvendt).

Mulige anvendelsestilfælde

  1. Tjek, hvad HTTP-endepunktet returnerer /healthz pod i produktionsklyngen.
  2. Tilslut en TCP-debugger til poden på den lokale maskine.
  3. Få adgang til produktionsdatabasen fra lokale databaseværktøjer uden at skulle bøvle med godkendelse (normalt har localhost root-rettigheder).
  4. Kør et engangsmigreringsscript for data i en staging-klynge uden at skulle oprette en container til det.
  5. Tilslut en VNC-session til en pod, der kører et virtuelt skrivebord (se XVFB).

Et par ord om de nødvendige værktøjer

Tcpserver — Et Open Source-værktøj tilgængeligt i de fleste Linux-pakkedepoter. Det giver dig mulighed for at åbne en lokal port og omdirigere trafik modtaget via stdin/stdout fra enhver specificeret kommando til den:

colin@colin-work:~$ tcpserver 127.0.0.1 8080 echo -e 'HTTP/1.0 200 OKrnContent-Length: 19rnrn<body>hello!</body>'&
[1] 17377
colin@colin-work:~$ curl localhost:8080
<body>hello!</body>colin@colin-work:~$

(asciinema.org)

Netcat gør det modsatte. Det giver dig mulighed for at oprette forbindelse til en åben port og overføre I/O modtaget fra den 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 over HTTP. Flag -C får den til at tilføje CRLF til slutningen af ​​linjen.

Forbindelse med kubectl: lyt på værten og opret forbindelse til poden

Hvis vi kombinerer ovenstående 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

Analogt vil det være nok at gøre for at få adgang til port 80 inde i poden 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)

Sådan åbner du en tunnel i en Kubernetes pod eller container med tcpserver og netcat
Utility interaktion diagram

I den modsatte retning: lyt i poden og opret forbindelse til værten

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

Denne kommando giver pod'en adgang til port 8000 på den lokale maskine.

Bash script

Jeg skrev et specielt script til Bash, der giver dig mulighed for at administrere en Kubernetes-produktionsklynge LayerCIved hjælp af metoden beskrevet ovenfor:

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"
}

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

  • Til tunnelen ind Docker du kan erstatte hovedlinjen med:
    tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
  • til tunnel ind K3s - ændre det til:
    tcpserver 127.0.0.1 6666 k3s kubectl exec …
  • etc.

Andre ideer

  • Du kan omdirigere UDP-trafik ved hjælp af kommandoerne netcat -l -u -c i stedet for tcpserver и netcat -u i stedet for netcat hhv.
  • Se I/O via 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 vha gzip.
  • Tilslut via SSH til en anden computer med den tilsvarende fil kubeconfig:

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

  • Du kan forbinde to pods i forskellige klynger vha mkfifo og kør to separate kommandoer kubectl.

Mulighederne er uendelige!

PS fra oversætteren

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar