Hoe een tunnel te openen in een Kubernetes pod of container met tcpserver en netcat

Opmerking vertaler.: Deze praktische notitie van de oprichter van LayerCI is een uitstekende illustratie van de zogenaamde tips & tricks voor Kubernetes (en meer). De oplossing die hier wordt aangeboden, is slechts een van de weinige en waarschijnlijk de minst voor de hand liggende (voor sommige gevallen kan de eerder in de opmerkingen genoemde 'native' oplossing voor K8s geschikt zijn). kubectl port-forward). Het stelt je echter in staat om tenminste het probleem te bekijken vanuit het perspectief van het gebruik van klassieke hulpmiddelen en hun verdere combinatie - tegelijkertijd eenvoudig, flexibel en krachtig (zie 'andere ideeën' aan het einde voor inspiratie).

Hoe een tunnel te openen in een Kubernetes pod of container met tcpserver en netcat

Stel je een typische situatie voor: je wilt dat een poort op je lokale computer op magische wijze verkeer omleidt naar een pod/container (of omgekeerd).

Mogelijke gebruiksscenario's

  1. Controleren wat de HTTP-endpoint retourneert /healthz pod in de productiecluster.
  2. Verbind een TCP-debugger met de pod op de lokale machine.
  3. Toegang krijgen tot de productie-database vanuit lokale tools voor databasebeheer zonder te hoeven rommelen met authenticatie (meestal heeft localhost root-rechten).
  4. Voer eenmalig een migratiescript voor gegevens in de staging-cluster uit zonder een container voor te hoeven maken.
  5. Verbind een VNC-sessie met de pod waarin een virtuele desktop draait (zie XVFB).

Enkele woorden over de benodigde tools

Tcpserver — Open Source-hulpmiddel, beschikbaar in de meeste Linux-pakketrepositories. Het maakt het mogelijk om een lokale poort te openen en het verkeer dat via stdin/stdout van een opgegeven commando wordt ontvangen, door te sturen:

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

(asciinema.org)

Netcat doet het omgekeerde. Het maakt het mogelijk om verbinding te maken met een open poort en de invoer/uitvoer van die poort naar stdin/stdout door te geven:

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)

In het bovenstaande voorbeeld vraagt netcat om een pagina via HTTP. De vlag -C dwingt het om CRLF aan het einde van de regel toe te voegen.

Integratie met kubectl: luister op de host en verbind met de pod

Als we de bovenstaande hulpmiddelen combineren met kubectl, krijgen we een opdracht die eruitziet als deze:

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

Evenzo, om toegang te krijgen tot poort 80 binnen de pod, volstaat het om te doen 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
Pakketlijsten worden gelezen... Klaar
Afhankelijkheidsboom wordt opgebouwd
Informatie over status wordt gelezen... Klaar
netcat-openbsd is al de nieuwste versie (1.195-2).
0 bijgewerkt, 0 nieuw geïnstalleerd, 0 te verwijderen en 10 niet bijgewerkt.
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)

Hoe een tunnel te openen in een Kubernetes pod of container met tcpserver en netcat
Schema voor interactie met hulpprogramma's

In de andere richting: luister in de pod en verbind met de host

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

Deze opdracht stelt de pod in staat om toegang te krijgen tot poort 8000 op de lokale machine.

Script voor Bash

Ik heb een speciaal Bash-script geschreven voor het beheren van een productiecluster van Kubernetes LayerCI, met behulp van de hierboven beschreven methode:

kubetunnel() {
    POD="$1"
    DESTPORT="$2"
    als [ -z "$POD" -o -z "$DESTPORT" ]; dan
        echo "Gebruik: kubetunnel [pod naam] [doelpoort]"
        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 "Verbind met 127.0.0.1:6666 om toegang te krijgen tot $POD:$DESTPORT"
}

Als je deze functie toevoegt aan ~/\.bashrc, kun je gemakkelijk een tunnel in de pod openen met de opdracht kubetunnel web-pod 8080 en doen curl localhost:6666.

  • Voor de tunnel in Docker kun je de basisregel vervangen door:
    tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
  • voor de tunnel in K3s — vervang het door:
    tcpserver 127.0.0.1 6666 k3s kubectl exec …
  • enzovoorts.

Andere ideeën

  • UDP-verkeer kan worden omgeleid met de commando's netcat -l -u -c in plaats van tcpserver en netcat -u in plaats van netcat respectievelijk.
  • Bekijk de invoer\/uitvoer via pipe viewer:

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

  • Je kunt verkeer aan beide uiteinden comprimeren en decomprimeren met gzip.
  • Verbind via SSH met een andere computer met het juiste bestand kubeconfig:

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

  • Je kunt twee pods in verschillende clusters verbinden met mkfifo en twee aparte commando's uitvoeren kubectl.

De mogelijkheden zijn eindeloos!

P.S. van de vertaler

Lees ook op onze blog:

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster