如何使用tcpserver和netcat在Kubernetes容器或容器中打开隧道

注意事项 佩雷夫 :LayerCI创造者的这篇实用笔记很好地说明了(不仅限于)Kubernetes的所谓技巧。 这里提出的解决方案只是少数几个,也许不是最明显的(在某些情况下,注释中提到的kubectl port-forward的“ kubectl port-forward ”可能是合适的)。 但是,它至少使您能够从使用经典实用程序及其进一步的组合-简单,灵活和强大的组合的角度来看问题(请参阅最后的“其他想法”以获取灵感)。



想象一个典型的情况:您希望本地计算机上的端口将流量神奇地重定向到Pod /容器(反之亦然)。

可能的用例


  1. 检查HTTP端点/healthz在生产集群中/healthz
  2. 将TCP调试器连接到本地计算机上的Pod。
  3. 从本地工具访问生产数据库,无需使用身份验证即可访问数据库(通常,本地主机具有root特权)。
  4. 对临时群集中的数据运行一次性迁移脚本,而不必为其创建容器。
  5. 将VNC会话连接到运行虚拟桌面的Pod(请参阅XVFB)。

关于必要工具的几句话


Tcpserver是大多数Linux软件包系统信息库中提供的开源实用程序。 它允许您打开本地端口,并将通过stdin / stdout接收的流量从任何指定命令重定向到该端口:

 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

Netcat则相反。 它允许您连接到开放端口,并将从其接收的输入/输出传输到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

在上面的示例中,netcat通过HTTP请求一个页面。 -C标志使它向行尾添加CRLF。

与kubectl链接:在主机上侦听并连接到pod


如果将上述工具与kubectl结合使用,则会得到如下命令:

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

以此类推,访问容器内部的端口80,足以使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


效用交互方案

相反的方向:在Pod中监听并连接到主机


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

此命令允许Pod访问本地计算机上的端口8000。

Bash脚本


我为Bash编写了一个特殊的脚本,该脚本允许您使用上述方法来管理Kubernetes LayerCI生产集群:

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

如果将此功能添加到~/.bashrc ,则可以使用kubetunnel web-pod 8080命令轻松地在pod中打开隧道,并执行curl localhost:6666

  • 对于Docker中的隧道您可以将主行替换为:

     tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT" 
  • 对于K3s中的隧道-将其更改为:

     tcpserver 127.0.0.1 6666 k3s kubectl exec 

其他想法


  • 您可以分别使用netcat -l -u -c代替tcpservernetcat -u代替netcat重定向UDP通信。
  • 通过管道查看器查看I / O:

    nc 127.0.0.1 8000 | pv --progress | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 cat
  • 您可以使用gzip在两端压缩和解压缩流量。
  • 通过SSH使用相应的kubeconfig文件连接到另一台计算机:

    tcpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80"
  • 您可以使用mkfifo连接不同群集中的两个Pod,并运行两个单独的kubectl

无限的可能性!

译者的PS


另请参阅我们的博客:

Source: https://habr.com/ru/post/zh-CN479910/


All Articles