Como abrir un túnel nun pod ou contedor de Kubernetes con tcpserver e netcat

Nota. transl.: Esta nota práctica do creador de LayerCI é unha excelente ilustración dos chamados consellos e trucos para Kubernetes (e máis). A solución aquí proposta é só unha das poucas e, quizais, non a máis obvia (para algúns casos, a "nativa" para os K8 xa mencionada nos comentarios pode ser axeitada kubectl port-forward). Non obstante, permítelle, polo menos, mirar o problema desde a perspectiva de usar utilidades clásicas e combinalas aínda máis, ao mesmo tempo sinxela, flexible e poderosa (consulta "Outras ideas" ao final para obter inspiración).

Como abrir un túnel nun pod ou contedor de Kubernetes con tcpserver e netcat

Imaxina unha situación típica: queres que un porto da túa máquina local reenvíe o tráfico de xeito máxico a un pod/contedor (ou viceversa).

Posibles casos de uso

  1. Comprobe o que devolve o punto final HTTP /healthz pod no clúster de produción.
  2. Conecte un depurador TCP ao pod da máquina local.
  3. Obteña acceso á base de datos de produción desde ferramentas de base de datos locais sen ter que preocuparse coa autenticación (normalmente localhost ten dereitos de root).
  4. Executa un script de migración único para os datos nun clúster provisional sen ter que crear un contedor para iso.
  5. Conecte unha sesión VNC a un pod que executa un escritorio virtual (consulte XVFB).

Unhas palabras sobre as ferramentas necesarias

Tcpserver — Unha utilidade de código aberto dispoñible na maioría dos repositorios de paquetes de Linux. Permítelle abrir un porto local e redirixir o tráfico recibido a través de stdin/stdout desde calquera comando especificado:

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 fai o contrario. Permítelle conectarse a un porto aberto e pasar a E/S recibida del a 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)

No exemplo anterior, netcat solicita a páxina a través de HTTP. Bandeira -C fai que engada CRLF ao final da liña.

Conexión con kubectl: escoita no host e conéctate ao pod

Se combinamos as ferramentas anteriores con kubectl, obtemos un comando coma este:

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

Por analoxía, para acceder ao porto 80 dentro da vaina será suficiente facelo 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)

Como abrir un túnel nun pod ou contedor de Kubernetes con tcpserver e netcat
Diagrama de interacción da utilidade

Na dirección oposta: escoita no pod e conéctate ao host

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

Este comando permite que o pod acceda ao porto 8000 na máquina local.

Script Bash

Escribín un script especial para Bash que che permite xestionar un clúster de produción de Kubernetes Capa CIutilizando o método descrito anteriormente:

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

Se engades esta función a ~/.bashrc, pode abrir facilmente un túnel nun pod co comando kubetunnel web-pod 8080 e fai curl localhost:6666.

  • Para o túnel de entrada Estivador pode substituír a liña principal por:
    tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
  • para túnel dentro K3 - cambialo por:
    tcpserver 127.0.0.1 6666 k3s kubectl exec …
  • etc

Outras ideas

  • Podes redirixir o tráfico UDP usando os comandos netcat -l -u -c en vez de tcpserver и netcat -u en vez de netcat respectivamente.
  • Ver E/S a través do visor de tubos:

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

  • Podes comprimir e descomprimir o tráfico en ambos os extremos usando gzip.
  • Conéctate por SSH a outro ordenador co ficheiro correspondente kubeconfig:

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

  • Podes conectar dous pods en clústeres diferentes usando mkfifo e executa dous comandos separados kubectl.

As posibilidades son infinitas!

PS do tradutor

Lea tamén no noso blog:

Fonte: www.habr.com

Engadir un comentario