Cum să deschizi un tunel în Kubernetes pod sau container cu tcpserver și netcat

Nota traducătorului.: Această notă practică de la creatorul LayerCI este o excelentă ilustrare a așa-numitelor tips & tricks pentru Kubernetes (și nu numai). Soluția propusă aici este doar una dintre puținele și, probabil, nu cea mai evidentă (pentru unele cazuri ar putea fi potrivită deja menționata în comentarii "nativă" pentru K8s kubectl port-forward). Cu toate acestea, permite cel puțin o privire asupra problemei din perspectiva aplicării utilitarelor clasice și a combinării lor ulterioare — simultan simplu, flexibil și puternic (vezi "alte idei" la sfârșit pentru inspirație).

Cum să deschizi un tunel în Kubernetes pod sau container cu tcpserver și netcat

Imaginați-vă o situație tipică: doriți ca un port de pe computerul local să redirecționeze magic traficul către un pod/contenitor (sau invers).

Scenarii posibile de utilizare

  1. Verificați ce returnează endpoint-ul HTTP /healthz pod-ului în clusterul de producție.
  2. Conectați un debugger TCP la pod de pe mașina locală.
  3. Accesați baza de date de producție din instrumentele locale pentru lucrul cu DB fără a fi nevoie să vă ocupați de autentificare (de obicei, localhost-ul are drepturi de root).
  4. Rulați un script temporar de migrare a datelor în clusterul de staging fără a fi nevoie să creați un container pentru el.
  5. Conectați o sesiune VNC la pod cu biroul virtual activat (vezi XVFB).

Câteva cuvinte despre instrumentele necesare

Tcpserver — Un utilitar Open Source, disponibil în cele mai multe repozitorii de pachete Linux. Permite deschiderea unui port local și redirecționarea traficului primit prin stdin/stdout de la orice comandă specificată:

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

(asciinema.org)

Netcat face opusul. Permite conectarea la un port deschis și transmiterea input/output-ului primit pe 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)

În exemplul de mai sus, netcat solicită o pagină prin HTTP. Flagul -C îl face să adauge CRLF la sfârșitul liniei.

Legătura cu kubectl: ascultați pe gazdă și conectați-vă la pod

Dacă combinăm instrumentele prezentate mai sus cu kubectl, obținem o comandă de genul:

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

În mod similar, pentru a accesa portul 80 în interiorul pod-ului, va fi suficient să faceți 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)

Cum să deschizi un tunel în Kubernetes pod sau container cu tcpserver și netcat
Schema de interacțiune a utilitarelor

În sens invers: ascultați în pod și conectați-vă la gazdă

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

Această comandă permite pod-ului să acceseze portul 8000 de pe mașina locală.

Script pentru Bash

Am scris un script special pentru Bash, care permite gestionarea clusterului de producție Kubernetes LayerCI, folosind metoda descrisă mai sus:

kubetunnel() {
    POD="$1"
    DESTPORT="$2"
    if [ -z "$POD" -o -z "$DESTPORT" ]; then
        echo "Utilizare: kubetunnel [nume pod] [port destinație]"
        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 "Conectați-vă la 127.0.0.1:6666 pentru a accesa $POD:$DESTPORT"
}

Dacă adăugați această funcție în ~/bashrc, puteți deschide cu ușurință un tunel în pod cu comanda kubetunnel web-pod 8080 și efectuați curl localhost:6666.

  • Pentru tunelul în Docker puteți schimba linia principală în:
    tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
  • pentru tunelul în K3s — schimbați-o în:
    tcpserver 127.0.0.1 6666 k3s kubectl exec …
  • etc.

Alte idei

  • Redirecționarea traficului UDP se poate realiza cu comenzile netcat -l -u -c în loc de tcpserver și netcat -u în loc de netcat corespunzător.
  • Visualizați intrarea/ieșirea prin pipe viewer:

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

  • Puteți comprima și decomprima traficul pe ambele capete folosind gzip.
  • Conectați-vă prin SSH la un alt computer cu fișierul corespunzător kubeconfig:

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

  • Puteți conecta două pod-uri din clustere diferite folosind mkfifo și rulați două comenzi separate kubectl.

Posibilitățile sunt nelimitate!

P.S. de la traducător

Citiți și în blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster