So öffnen Sie einen Tunnel in Kubernetes Pod oder Container mit tcpserver und netcat

Hinweis perev. : Dieser praktische Hinweis vom Schöpfer von LayerCI ist eine großartige Illustration der sogenannten Tipps und Tricks für Kubernetes (und nicht nur). Die hier vorgeschlagene Lösung ist nur eine der wenigen und möglicherweise nicht die offensichtlichste (in einigen Fällen kann die in den Kommentaren erwähnte " kubectl port-forward " -Eigenschaft der K8 geeignet sein). Es ermöglicht Ihnen jedoch, das Problem zumindest aus der Perspektive der Verwendung klassischer Dienstprogramme und ihrer weiteren Kombination zu betrachten - sowohl einfach als auch flexibel und leistungsstark (Inspiration finden Sie unter „Andere Ideen“ am Ende).



Stellen Sie sich eine typische Situation vor: Sie möchten, dass der Port auf dem lokalen Computer den Datenverkehr auf magische Weise zum Pod / Container umleitet (oder umgekehrt).

Mögliche Anwendungsfälle


  1. Überprüfen Sie, ob der HTTP-Endpunkt /healthz im Produktionscluster zurückgegeben wird.
  2. Verbinden Sie einen TCP-Debugger mit dem Pod auf dem lokalen Computer.
  3. Erhalten Sie von lokalen Tools aus Zugriff auf die Produktionsdatenbank, um mit der Datenbank zu arbeiten, ohne sich um die Authentifizierung kümmern zu müssen (in der Regel verfügt localhost über Root-Berechtigungen).
  4. Führen Sie ein einmaliges Migrationsskript für Daten im Staging-Cluster aus, ohne dafür einen Container erstellen zu müssen.
  5. Verbinden Sie eine VNC-Sitzung mit einem Pod, auf dem ein virtueller Desktop ausgeführt wird (siehe XVFB).

Ein paar Worte zu den notwendigen Werkzeugen


Tcpserver ist ein Open Source-Dienstprogramm, das in den meisten Linux-Paket-Repositorys verfügbar ist. Sie können einen lokalen Port öffnen und den über stdin / stdout empfangenen Datenverkehr von einem angegebenen Befehl an diesen umleiten:

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

( asciinema.org )

Netcat macht das Gegenteil. Hiermit können Sie eine Verbindung zu einem offenen Port herstellen und die von ihm empfangenen Ein- / Ausgaben an stdin / stdout übertragen:

 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 )

Im obigen Beispiel fordert netcat eine Seite über HTTP an. Das Flag -C bewirkt, dass CRLF am Ende der Zeile eingefügt wird.

Mit kubectl verknüpfen: Hören Sie auf den Host und stellen Sie eine Verbindung zum Pod her


Wenn wir die obigen Tools mit kubectl kombinieren, erhalten wir einen Befehl wie diesen:

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

Um auf den Port 80 im Pod zuzugreifen, reicht es analog aus, curl "127.0.0.1:80" zu 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 )


Utility Interaction Scheme

In die entgegengesetzte Richtung: Hören Sie im Pod zu und stellen Sie eine Verbindung zum Host her


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

Mit diesem Befehl kann der Pod auf Port 8000 auf dem lokalen Computer zugreifen.

Skript für Bash


Ich habe ein spezielles Skript für Bash geschrieben, mit dem Sie den Kubernetes LayerCI- Produktionscluster mit der oben beschriebenen Methode verwalten können:

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

Wenn Sie diese Funktion zu ~/.bashrc , können Sie den Tunnel im Pod einfach kubetunnel web-pod 8080 öffnen und curl localhost:6666 .

  • Für einen Tunnel in Docker können Sie die Hauptleitung ersetzen durch:

     tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT" 
  • für den Tunnel in K3s - ändere ihn in:

     tcpserver 127.0.0.1 6666 k3s kubectl exec 
  • usw.

Andere Ideen


  • Sie können den UDP-Verkehr mit den Befehlen netcat -l -u -c anstelle von tcpserver bzw. netcat -u anstelle von netcat tcpserver .
  • Anzeigen von E / A über den Pipe Viewer:

    nc 127.0.0.1 8000 | pv --progress | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 cat
  • Sie können den Datenverkehr an beiden Enden mit gzip komprimieren und dekomprimieren.
  • kubeconfig über SSH eine Verbindung zu einem anderen Computer mit der entsprechenden kubeconfig Datei her:

    tcpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80"
  • Sie können mit mkfifo zwei Pods in verschiedenen Clustern mkfifo und zwei separate kubectl .

Die Möglichkeiten sind endlos!

PS vom Übersetzer


Lesen Sie auch in unserem Blog:

Source: https://habr.com/ru/post/de479910/


All Articles