Como abrir um túnel no pod ou contêiner do Kubernetes com tcpserver e netcat

Nota perev. : Esta nota prática do criador do LayerCI é uma ótima ilustração das chamadas dicas e truques para o Kubernetes (e não apenas). A solução proposta aqui é apenas uma das poucas e, talvez, não a mais óbvia (em alguns casos, o " kubectl port-forward " nativo dos K8s mencionados nos comentários pode ser adequado). No entanto, permite que você olhe pelo menos para o problema da perspectiva de usar utilitários clássicos e sua combinação adicional - simples, flexível e poderosa (consulte “outras idéias” no final para obter inspiração).



Imagine uma situação típica: você deseja que a porta do computador local redirecione magicamente o tráfego para o pod / contêiner (ou vice-versa).

Possíveis casos de uso


  1. Verifique se o terminal HTTP /healthz no cluster de produção.
  2. Conecte um depurador TCP ao pod na máquina local.
  3. Obtenha acesso ao banco de dados de produção a partir de ferramentas locais para trabalhar com o banco de dados sem precisar se preocupar com a autenticação (geralmente o host local tem privilégios de root).
  4. Execute um script de migração único para dados no cluster temporário sem precisar criar um contêiner para ele.
  5. Conecte uma sessão VNC a um pod executando uma área de trabalho virtual (consulte XVFB).

Algumas palavras sobre as ferramentas necessárias


Tcpserver é um utilitário de código aberto disponível na maioria dos repositórios de pacotes Linux. Permite abrir uma porta local e redirecionar o tráfego recebido por meio de stdin / stdout a partir de qualquer comando especificado:

 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 )

O Netcat faz o oposto. Ele permite que você se conecte a uma porta aberta e transfira a entrada / saída recebida dela para 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 acima, o netcat solicita uma página por HTTP. O sinalizador -C faz com que ele adicione CRLF ao final da linha.

Link com o kubectl: ouça no host e conecte-se ao pod


Se combinarmos as ferramentas acima com o kubectl, obteremos um comando como este:

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

Por analogia, para acessar a porta 80 dentro do pod, será suficiente fazer a 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 )


Esquema de interação de utilidade

Na direção oposta: ouça no pod e conecte-se 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 acesse a porta 8000 na máquina local.

Script para Bash


Eu escrevi um script especial para o Bash que permite gerenciar o cluster de produção Kubernetes LayerCI usando o método descrito acima:

 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 você adicionar esta função ao ~/.bashrc , poderá abrir facilmente o túnel no pod com o kubetunnel web-pod 8080 e curl localhost:6666 .

  • Para um túnel no Docker, você pode substituir a linha principal por:

     tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT" 
  • para o túnel no K3s - altere para:

     tcpserver 127.0.0.1 6666 k3s kubectl exec 
  • etc.

Outras ideias


  • Você pode redirecionar o tráfego UDP usando netcat -l -u -c vez de tcpserver e netcat -u vez de netcat respectivamente.
  • Veja E / S através do visualizador de tubos:

    nc 127.0.0.1 8000 | pv --progress | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 cat
  • Você pode compactar e descomprimir o tráfego nas duas extremidades usando o gzip .
  • Conecte-se via SSH a outro computador com o arquivo kubeconfig correspondente:

    tcpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80"
  • Você pode conectar dois pods em diferentes clusters usando o mkfifo e executar dois kubectl separados.

As possibilidades são infinitas!

PS do tradutor


Leia também em nosso blog:

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


All Articles