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

Note de traduction.: Cette note pratique du crĂ©ateur de LayerCI est une excellente illustration des soi-disant astuces pour Kubernetes (et pas seulement). La solution proposĂ©e ici n'est qu'une des rares et, probablement, pas la plus Ă©vidente (dans certains cas, la solution « native » pour K8s mentionnĂ©e dans les commentaires pourrait convenir). kubectl port-forward). Cependant, cela permet au moins de voir le problĂšme sous l'angle de l'application des utilitaires classiques et de leur combinaison ultĂ©rieure — Ă  la fois simple, flexible et puissant (voir « autres idĂ©es » Ă  la fin pour s'inspirer).

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

Imaginez une situation typique : vous voulez que le port de votre ordinateur local redirige magiquement le trafic vers un pod/conteneur (ou vice versa).

Scénarios d'utilisation possibles

  1. Vérifiez ce que retourne le point de terminaison HTTP /healthz pod dans un cluster de production.
  2. Connectez un débogueur TCP au pod sur votre machine locale.
  3. Accédez à la base de production depuis des outils locaux de gestion de base de données sans avoir à se soucier de l'authentification (généralement, localhost a les droits de root).
  4. Exécutez un script de migration de données unique dans un cluster de staging sans avoir à créer un conteneur pour cela.
  5. Connectez une session VNC au pod avec un bureau virtuel en cours d'exécution (voir XVFB).

Quelques mots sur les outils nécessaires

Tcpserver — Un utilitaire open source, disponible dans la plupart des dĂ©pĂŽts de paquets Linux. Il permet d'ouvrir un port local et de rediriger le trafic reçu via stdin/stdout depuis n'importe quelle commande spĂ©cifiĂ©e :

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

(asciinema.org)

Netcat fait l'inverse. Il permet de se connecter à un port ouvert et de transmettre l'entrée/sortie reçue vers 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 une page via HTTP. Le drapeau -C l'oblige Ă  ajouter CRLF Ă  la fin de la ligne.

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

Si l'on combine les outils présentés 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

De la mĂȘme maniĂšre, pour accĂ©der au port 80 Ă  l'intĂ©rieur du pod, il suffit 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
Lecture des listes de paquets... Terminé
Construction de l'arbre des dépendances
Lecture des informations d'état... Terminé
netcat-openbsd est déjà la version la plus récente (1.195-2).
0 mis à jour, 0 nouvellement installé, 0 à supprimer et 10 non mis à jour.
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
Schéma d'interaction des utilitaires

Dans l'autre sens : é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 pour Bash

J'ai écrit un script spécial pour Bash permettant de gérer un cluster Kubernetes en production LayerCI, en utilisant la méthode décrite ci-dessus :

kubetunnel() {
    POD="$1"
    DESTPORT="$2"
    if [ -z "$POD" -o -z "$DESTPORT" ]; then
        echo "Usage : kubetunnel [nom du pod] [port de destination]"
        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 "Connectez-vous à 127.0.0.1:6666 pour accéder à $POD:$DESTPORT"
}

Si vous ajoutez cette fonction dans ~\/bashrc, vous pouvez facilement ouvrir un tunnel dans le pod avec la commande kubetunnel web-pod 8080 et faire 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 le tunnel dans K3s – changez-le en :
    tcpserver 127.0.0.1 6666 k3s kubectl exec 

  • etc.

Autres idées

  • Vous pouvez rediriger le trafic UDP avec les commandes netcat -l -u -c au lieu de tcpserver et netcat -u au lieu de netcat respectivement.
  • Voir l'entrĂ©e/sortie via pipe viewer :

    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 des deux cĂŽtĂ©s avec gzip.
  • Se connecter par SSH Ă  un autre ordinateur avec le fichier appropriĂ© 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 avec mkfifo et exĂ©cuter deux commandes sĂ©parĂ©es kubectl.

Les possibilités sont infinies !

P.S. de l'auteur

Lisez aussi dans notre blog :

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster