Comment ouvrir un tunnel dans un pod ou un conteneur Kubernetes avec tcpserver et netcat

Noter. trad.: Cette note pratique du créateur de LayerCI est une excellente illustration des soi-disant trucs & astuces pour Kubernetes (et pas seulement). La solution proposée ici n'est qu'une des rares et, peut-être, pas la plus évidente (dans certains cas, la solution « native » pour les K8 déjà évoquée dans les commentaires peut convenir kubectl port-forward). Cependant, cela vous permet au moins d'examiner le problème du point de vue de l'utilisation d'utilitaires classiques et de leur combinaison ultérieure - à la fois simples, flexibles et puissants (voir « autres idées » à la fin pour vous inspirer).

Comment ouvrir un tunnel dans un pod ou un conteneur Kubernetes avec tcpserver et netcat

Imaginez une situation typique : vous souhaitez qu'un port sur votre machine locale transfère comme par magie le trafic vers un pod/conteneur (ou vice versa).

Cas d'utilisation possibles

  1. Vérifiez ce que renvoie le point de terminaison HTTP /healthz pod dans le cluster de production.
  2. Connectez un débogueur TCP au pod sur la machine locale.
  3. Accédez à la base de données de production à partir des outils de base de données locaux sans avoir à vous soucier de l'authentification (généralement localhost dispose des droits root).
  4. Exécutez un script de migration unique pour les données d'un cluster intermédiaire sans avoir à créer un conteneur pour celui-ci.
  5. Connectez une session VNC à un pod exécutant un bureau virtuel (voir XVFB).

Quelques mots sur les outils nécessaires

Serveur TCP — Un utilitaire Open Source disponible dans la plupart des référentiels de packages Linux. Il vous permet d'ouvrir un port local et de rediriger le trafic reçu via stdin/stdout depuis n'importe quelle commande spécifiée vers celui-ci :

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 fait le contraire. Il vous permet de vous connecter à un port ouvert et de transmettre les E/S reçues à 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)

Dans l'exemple ci-dessus, netcat demande la page via HTTP. Drapeau -C le fait ajouter CRLF à la fin de la ligne.

Connexion avec kubectl : écoutez sur l'hôte et connectez-vous au pod

Si nous combinons les outils ci-dessus avec kubectl, nous obtenons une commande comme celle-ci :

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

Par analogie, pour accéder au port 80 à l’intérieur du pod il suffira de faire 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)

Comment ouvrir un tunnel dans un pod ou un conteneur Kubernetes avec tcpserver et netcat
Diagramme d'interaction utilitaire

Dans le sens inverse : écoutez dans le pod et connectez-vous à l'hôte

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

Cette commande permet au pod d'accéder au port 8000 sur la machine locale.

Script bash

J'ai écrit un script spécial pour Bash qui permet de gérer un cluster de production Kubernetes CoucheCIen utilisant la méthode décrite ci-dessus :

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

Si vous ajoutez cette fonction à ~/.bashrc, vous pouvez facilement ouvrir un tunnel dans un pod avec la commande kubetunnel web-pod 8080 et fait curl localhost:6666.

  • Pour le tunnel dans Docker vous pouvez remplacer la ligne principale par :
    tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
  • pour tunnel dans K3s - changez-le en :
    tcpserver 127.0.0.1 6666 k3s kubectl exec …
  • etc.

Plus d'idées

  • Vous pouvez rediriger le trafic UDP à l'aide des commandes netcat -l -u -c au lieu de tcpserver и netcat -u au lieu de netcat respectivement.
  • Afficher les E/S via le visualiseur de tuyaux :

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

  • Vous pouvez compresser et décompresser le trafic aux deux extrémités en utilisant gzip.
  • Connectez-vous via SSH à un autre ordinateur avec le fichier correspondant kubeconfig:

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

  • Vous pouvez connecter deux pods dans des clusters différents à l'aide de mkfifo et exécutez deux commandes distinctes kubectl.

озможности езграничны!

PS du traducteur

A lire aussi sur notre blog :

Source: habr.com

Ajouter un commentaire