双端口转发 kubernetes + docker

Cha*_*osh 3 port-forwarding psql docker kubernetes kubectl

概括:

我有一个运行 kubectl port-forward 的 docker 容器,将作为 k8s 服务运行的 postgres 服务的端口 (5432) 转发到本地端口 (2223)。在 Dockerfile 中,我暴露了相关端口 2223。然后我通过发布该端口来运行容器 ( -p 2223:2223)

现在,当我尝试通过访问 postgres 时psql -h localhost -p 2223,出现以下错误:

psql: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
Run Code Online (Sandbox Code Playgroud)

但是,当我docker exec -ti对上述容器执行操作并运行上述 psql 命令时,我能够连接到 postgres。

Dockerfile 命令:

EXPOSE 2223
CMD ["bash", "-c", "kubectl -n namespace_test port-forward service/postgres-11-2 2223:5432"]
Run Code Online (Sandbox Code Playgroud)

Docker 运行命令:

docker run -it --name=k8s-conn-12 -p 2223:2223 my_image_name:latest
Run Code Online (Sandbox Code Playgroud)

docker run 命令的输出:

Forwarding from 127.0.0.1:2223 -> 5432
Run Code Online (Sandbox Code Playgroud)

因此端口转发成功,我可以从 docker 容器内部连接到 postgres 实例。我无法做的是从容器外部与公开和发布的端口进行连接

mat*_*t_j 8

我认为有两种可能的解决方案可能对您的情况有所帮助:

\n
    \n
  1. 您可以使用运行此命令的容器的 IP 地址将--address参数添加到命令中。kubectl port-forward默认情况下,kubectl仅绑定到 localhost,因此它不会按您的预期工作(请参阅:Kubectl 参考文档)。
  2. \n
  3. bridge除非另有说明,所有新启动的容器都连接到默认网络。为了解决您的问题,您可以使用host网络来代替bridge网络。在Docker 主机网络文档中可以找到:
  4. \n
\n
\n

如果容器使用主机网络模式,则该容器\xe2\x80\x99s网络堆栈不会与Docker主机隔离(容器共享主机\xe2\x80\x99s网络命名空间),并且容器不会获取分配了自己的IP地址。

\n
\n

我将简要描述这两种解决方案,以向您展示其工作原理。

\n
\n

首先,我准备了postgres

\n
# kubectl get pod,svc\nNAME           READY   STATUS    RESTARTS   AGE\npod/postgres   1/1     Running   0          155m\n\nNAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE\nservice/postgres     ClusterIP   10.110.151.73   <none>        5432/TCP   2s\n
Run Code Online (Sandbox Code Playgroud)\n

广告 1。

\n

这种方法与你的方法非常相似,我只是添加了参数--address
\n注意:我使用了已经安装的容器kubectl。我只是想让你注意指挥kubectl port-forward --address $(hostname -i),localhost service/postgres 2223:5432

\n
root@kworker:~# docker run -it --name=k8s-conn-12 -p 2223:2223 -v /config:/config mattjcontainerregistry/forward:latest bash\nroot@31b05af956ab:/# kubectl port-forward --address $(hostname -i),localhost service/postgres 2223:5432 --kubeconfig=config\nForwarding from 127.0.0.1:2223 -> 5432\nForwarding from 172.17.0.2:2223 -> 5432\n
Run Code Online (Sandbox Code Playgroud)\n

从另一个终端选项卡我们可以检查它是否有效:

\n
root@kworker:~# docker exec -it k8s-conn-12 bash\nroot@31b05af956ab:/# psql -U postgres -h localhost -p 2223\npsql (12.7 (Ubuntu 12.7-0ubuntu0.20.04.1), server 13.3 (Debian 13.3-1.pgdg100+1))\nWARNING: psql major version 12, server major version 13.\n         Some psql features might not work.\nType "help" for help.\n\npostgres=# \n
Run Code Online (Sandbox Code Playgroud)\n

此外,我们可以从主机(从具有公开和发布端口的容器外部)执行相同的操作:

\n
root@kworker:~# psql -U postgres -h localhost -p 2223\npsql (11.12 (Debian 11.12-0+deb10u1), server 13.3 (Debian 13.3-1.pgdg100+1))\nWARNING: psql major version 11, server major version 13.\n         Some psql features might not work.\nType "help" for help.\n\npostgres=# \n
Run Code Online (Sandbox Code Playgroud)\n

广告 2。

\n

这种方法需要使用主机网络:

\n
\n

host:对于独立容器,取消容器与Docker主机之间的网络隔离,直接使用host\xe2\x80\x99s网络。

\n
\n

注意:我只是想让你注意这个--network=host选项(我使用了与之前相同的容器):

\n
root@kworker:~# docker run -it --name=k8s-conn-12 --network=host  -v /config:/config mattjcontainerregistry/forward:latest bash\nroot@kworker:/# kubectl port-forward service/postgres 2223:5432 --kubeconfig=config\nForwarding from 127.0.0.1:2223 -> 5432\nForwarding from [::1]:2223 -> 5432\n
Run Code Online (Sandbox Code Playgroud)\n

同样,我们可以从容器外部检查它是否按预期工作:

\n
root@kworker:~# psql -U postgres -h localhost -p 2223\npsql (11.12 (Debian 11.12-0+deb10u1), server 13.3 (Debian 13.3-1.pgdg100+1))\nWARNING: psql major version 11, server major version 13.\n         Some psql features might not work.\nType "help" for help.\n\npostgres=# \n
Run Code Online (Sandbox Code Playgroud)\n
\n

此外,如果您确实需要 docker 容器来进行端口转发,则值得考虑。kubectl port-forward也许在后台运行会更好(请参阅:在后台执行 kubectl port-forward)。

\n