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

笔记。 翻译。:LayerCI 创建者的这篇实用说明很好地说明了 Kubernetes(以及更多)的所谓提示和技巧。 这里提出的解决方案只是少数几个,也许不是最明显的(对于某些情况,评论中已经提到的 K8s 的“原生”解决方案可能是合适的) kubectl port-forward)。 然而,它至少允许你从使用经典实用程序并进一步结合它们的角度来看待问题——同时简单、灵活和强大(请参阅最后的“其他想法”以获得灵感)。

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

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

可能的用例

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

关于必要工具的几句话

TCP服务器 — 大多数 Linux 软件包存储库中都提供的开源实用程序。 它允许您打开本地端口并将通过 stdin/stdout 从任何指定命令接收到的流量重定向到该端口:

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 则相反。 它允许您连接到一个开放端口并将从该端口接收到的 I/O 传递到 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

以此类推,要访问 pod 内的端口 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)

如何使用 tcpserver 和 netcat 在 Kubernetes Pod 或容器中打开隧道
实用程序交互图

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

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

该命令允许 pod 访问本机的 8000 端口。

bash脚本

我为 Bash 编写了一个特殊脚本,可让您管理 Kubernetes 生产集群 层CI使用上述方法:

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,您可以使用以下命令轻松地在 Pod 中打开隧道 kubetunnel web-pod 8080 并做 curl localhost:6666.

  • 对于隧道中 码头工人 您可以将主线替换为:
    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 …
  • 等等

更多想法

  • 您可以使用以下命令重定向 UDP 流量 netcat -l -u -c 而不是 tcpserver и netcat -u 而不是 netcat 分别
  • 通过管道查看器查看 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"

  • 您可以使用以下命令连接不同集群中的两个 Pod mkfifo 并运行两个单独的命令 kubectl.

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

译者PS

另请阅读我们的博客:

来源: habr.com

添加评论