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

Opmerking. vert.: Deze praktische notitie van de maker van LayerCI is een uitstekende illustratie van de zogenaamde tips & tricks voor Kubernetes (en meer). De hier voorgestelde oplossing is slechts een van de weinige en misschien niet de meest voor de hand liggende (in sommige gevallen kan de β€˜native’ oplossing voor K8’s die al in de opmerkingen wordt genoemd, geschikt zijn kubectl port-forward). Het stelt je echter in staat om op zijn minst naar het probleem te kijken vanuit het perspectief van het gebruik van klassieke hulpprogramma's en het verder combineren ervan - tegelijkertijd eenvoudig, flexibel en krachtig (zie 'andere ideeΓ«n' aan het einde voor inspiratie).

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

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

Mogelijke gebruiksscenario's

  1. Controleer wat het HTTP-eindpunt retourneert /healthz pod in het productiecluster.
  2. Sluit een TCP-foutopsporingsprogramma aan op de pod op de lokale machine.
  3. Krijg toegang tot de productiedatabase vanuit lokale databasetools zonder dat u zich zorgen hoeft te maken over authenticatie (meestal heeft localhost rootrechten).
  4. Voer een eenmalig migratiescript uit voor gegevens in een stagingcluster zonder dat u daarvoor een container hoeft te maken.
  5. Verbind een VNC-sessie met een pod waarop een virtueel bureaublad draait (zie XVFB).

Een paar woorden over de benodigde hulpmiddelen

Tcpserver β€” Een Open Source-hulpprogramma dat beschikbaar is in de meeste Linux-pakketbronnen. Hiermee kunt u een lokale poort openen en verkeer ontvangen via stdin/stdout van elk opgegeven commando ernaar omleiden:

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 doet het tegenovergestelde. Hiermee kunt u verbinding maken met een open poort en de ontvangen I/O doorgeven aan 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)

In het bovenstaande voorbeeld vraagt ​​netcat de pagina op via HTTP. Vlag -C zorgt ervoor dat CRLF aan het einde van de regel wordt toegevoegd.

Verbinding met kubectl: luister op de host en maak verbinding met de pod

Als we de bovenstaande tools combineren met kubectl, krijgen we een opdracht als deze:

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

Naar analogie is het voldoende om toegang te krijgen tot poort 80 in de pod 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)

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

In de tegenovergestelde richting: luister in de pod en maak verbinding met de host

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

Met deze opdracht krijgt de pod toegang tot poort 8000 op de lokale machine.

Bash-script

Voor Bash heb ik een speciaal script geschreven waarmee je een Kubernetes-productiecluster kunt beheren LaagCImet behulp van de hierboven beschreven methode:

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

Als u deze functie toevoegt aan ~/.bashrckunt u eenvoudig een tunnel in een pod openen met het commando kubetunnel web-pod 8080 en doe curl localhost:6666.

  • Voor de tunnel erin havenarbeider je kunt de hoofdlijn vervangen door:
    tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
  • voor tunnel-in K3s - verander het in:
    tcpserver 127.0.0.1 6666 k3s kubectl exec …
  • etc.

Andere ideeΓ«n

  • U kunt UDP-verkeer omleiden met behulp van de opdrachten netcat -l -u -c in plaats van tcpserver ΠΈ netcat -u in plaats van netcat respectievelijk.
  • Bekijk I/O via pipeviewer:

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

  • U kunt verkeer aan beide kanten comprimeren en decomprimeren met behulp van gzip.
  • Maak via SSH verbinding met een andere computer met het bijbehorende bestand kubeconfig:

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

  • U kunt twee pods in verschillende clusters verbinden met behulp van mkfifo en voer twee afzonderlijke opdrachten uit kubectl.

De mogelijkheden zijn eindeloos!

PS van vertaler

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie