概括:
我有一个 docker 容器,它正在运行 kubectl port-forward,将作为 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.
但是,当我docker exec -ti
对所述容器执行操作并运行上述 psql 命令时,我能够连接到 postgres。
Dockerfile 命令:
EXPOSE 2223
CMD ["bash", "-c", "kubectl -n namespace_test port-forward service/postgres-11-2 2223:5432"]
Docker 运行命令:
docker run -it --name=k8s-conn-12 -p 2223:2223 my_image_name:latest
docker run 命令的输出:
Forwarding from 127.0.0.1:2223 -> 5432
因此端口转发成功,我可以从 docker 容器内部连接到 postgres 实例。我无法做的是从容器外部使用公开和发布的端口进行连接
答案1
我认为有两种可能的解决方案可能会对您的情况有所帮助:
- 您可以将运行此命令的容器的 IP 地址添加到命令的
--address
参数中。默认情况下,仅绑定到 localhost,因此它不会按预期工作(请参阅:kubectl port-forward
kubectl
Kubectl 参考文档)。 bridge
除非另有指定,否则所有新启动的容器都会连接到默认网络。要解决您的问题,您可以使用host
网络而不是网络bridge
。如在Docker 主机网络文档:
如果对容器使用主机网络模式,则该容器的网络堆栈不会与 Docker 主机隔离(容器共享主机的网络命名空间),并且容器不会分配自己的 IP 地址。
我将简要描述这两种解决方案,向您展示其工作原理。
首先,我准备了postgres
:
# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/postgres 1/1 Running 0 155m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/postgres ClusterIP 10.110.151.73 <none> 5432/TCP 2s
广告 1.
这种方法与你的方法非常相似,我只是添加了参数--address
:
笔记:我使用了已安装的容器kubectl
。我只是想让你注意命令kubectl port-forward --address $(hostname -i),localhost service/postgres 2223:5432
。
root@kworker:~# docker run -it --name=k8s-conn-12 -p 2223:2223 -v /config:/config mattjcontainerregistry/forward:latest bash
root@31b05af956ab:/# kubectl port-forward --address $(hostname -i),localhost service/postgres 2223:5432 --kubeconfig=config
Forwarding from 127.0.0.1:2223 -> 5432
Forwarding from 172.17.0.2:2223 -> 5432
我们可以在另一个终端选项卡中检查它是否有效:
root@kworker:~# docker exec -it k8s-conn-12 bash
root@31b05af956ab:/# psql -U postgres -h localhost -p 2223
psql (12.7 (Ubuntu 12.7-0ubuntu0.20.04.1), server 13.3 (Debian 13.3-1.pgdg100+1))
WARNING: psql major version 12, server major version 13.
Some psql features might not work.
Type "help" for help.
postgres=#
此外,我们可以从主机(从具有暴露和发布端口的容器外部)执行相同的操作:
root@kworker:~# psql -U postgres -h localhost -p 2223
psql (11.12 (Debian 11.12-0+deb10u1), server 13.3 (Debian 13.3-1.pgdg100+1))
WARNING: psql major version 11, server major version 13.
Some psql features might not work.
Type "help" for help.
postgres=#
广告 2。
这种方法需要使用主持人网络:
主机:对于独立容器,删除容器和 Docker 主机之间的网络隔离,并直接使用主机的网络。
笔记:我只是想让你注意这个--network=host
选项(我使用了与以前相同的容器):
root@kworker:~# docker run -it --name=k8s-conn-12 --network=host -v /config:/config mattjcontainerregistry/forward:latest bash
root@kworker:/# kubectl port-forward service/postgres 2223:5432 --kubeconfig=config
Forwarding from 127.0.0.1:2223 -> 5432
Forwarding from [::1]:2223 -> 5432
再次,我们可以从容器外部检查它是否按预期工作:
root@kworker:~# psql -U postgres -h localhost -p 2223
psql (11.12 (Debian 11.12-0+deb10u1), server 13.3 (Debian 13.3-1.pgdg100+1))
WARNING: psql major version 11, server major version 13.
Some psql features might not work.
Type "help" for help.
postgres=#
此外,值得考虑的是,您是否真的需要一个docker容器来进行端口转发。也许kubectl port-forward
在后台运行会更好(参见:在后台执行 kubectl port-forward)。