无法在 docker 容器内访问 kubectl port-forward
kubectl port-forward cannot be accessed inside docker container
假设在 kubernetes 中有一个 pod(例如 postgres)运行ning,kubectl port-forward pod 15432:5432
被用来将 pod 暴露给主机。
正常情况下,可以通过运行在主机上访问postgres客户端:psql -h 127.0.0.1 -p 15432
,或者通过访问http://127.0.0.1:15432
,或者直接建立TCP连接:echo > /dev/tcp/127.0.0.1/15432 && echo yes
。如果连接建立成功,kubectl 会提示消息Handling connection for 15432
进行验证。
然而,无论是否使用标志 --network=host
,在容器内使用 127.0.0.1
/172.17.0.1
访问端口转发的 pod 是不可能的。只能通过 host.docker.internal
访问
这可能是 docker for mac 独有的问题。我还没有验证 linux。
这是我在 docker 中 运行 进行连接测试时的日志。明明是TCP连接无法建立
$ docker run --network=host -it --rm postgres:12.4 /bin/bash
# inside container
# unsuccessful for establishing TCP connection to 127.0.0.1:15432
root@docker-desktop:/# echo > /dev/tcp/127.0.0.1/15432 && echo yes
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/15432: Connection refused
# unsuccessful for establishing TCP connection to 172.17.0.1:15432
[root@docker-desktop /]# echo > /dev/tcp/172.17.0.1/15432 && echo yes
bash: connect: Connection refused
bash: /dev/tcp/172.17.0.1/15432: Connection refused
# no surprise: unsuccessful for psql 127.0.0.1
root@docker-desktop:/# psql -h 127.0.0.1 -p 15432
psql: error: could not connect to server: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 15432?
# successful for host.docker.internal
root@docker-desktop:/# psql -h host.docker.internal -p 15432
Password for user root:
以下是一些可能有用的 nslookup/ifconfig 日志:
Server: 192.168.65.1
Address: 192.168.65.1#53
Non-authoritative answer:
Name: host.docker.internal
Address: 192.168.65.2
bash-5.0# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:984 (984.0 B) TX bytes:202 (202.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:29 (29.0 B) TX bytes:29 (29.0 B)
为什么 docker 容器和主机之间的连接存在差异? host.docker.internal 如何解决底层问题?是否有其他方法通过提供 docker 运行 标志来解决问题?
当为 Mac 或 Windows 使用 Docker 时,虚拟机用于 运行 您的容器。
即使使用 --net=host
,容器也不会直接 运行 在您的桌面上,而是在 VM 上。因此 127.0.0.1 是 VM IP,而不是主机 IP。你可以像你说的那样,在Mac/Windows上使用host.docker.internal
来获取真机的IP。
在 Linux 容器 运行 上没有 VM,因此直接在真实主机上。
您可能想要调查远程呈现是否可以以更通用和更稳健的方式解决您的用例:https://www.telepresence.io/
假设在 kubernetes 中有一个 pod(例如 postgres)运行ning,kubectl port-forward pod 15432:5432
被用来将 pod 暴露给主机。
正常情况下,可以通过运行在主机上访问postgres客户端:psql -h 127.0.0.1 -p 15432
,或者通过访问http://127.0.0.1:15432
,或者直接建立TCP连接:echo > /dev/tcp/127.0.0.1/15432 && echo yes
。如果连接建立成功,kubectl 会提示消息Handling connection for 15432
进行验证。
然而,无论是否使用标志 --network=host
,在容器内使用 127.0.0.1
/172.17.0.1
访问端口转发的 pod 是不可能的。只能通过 host.docker.internal
这可能是 docker for mac 独有的问题。我还没有验证 linux。
这是我在 docker 中 运行 进行连接测试时的日志。明明是TCP连接无法建立
$ docker run --network=host -it --rm postgres:12.4 /bin/bash
# inside container
# unsuccessful for establishing TCP connection to 127.0.0.1:15432
root@docker-desktop:/# echo > /dev/tcp/127.0.0.1/15432 && echo yes
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/15432: Connection refused
# unsuccessful for establishing TCP connection to 172.17.0.1:15432
[root@docker-desktop /]# echo > /dev/tcp/172.17.0.1/15432 && echo yes
bash: connect: Connection refused
bash: /dev/tcp/172.17.0.1/15432: Connection refused
# no surprise: unsuccessful for psql 127.0.0.1
root@docker-desktop:/# psql -h 127.0.0.1 -p 15432
psql: error: could not connect to server: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 15432?
# successful for host.docker.internal
root@docker-desktop:/# psql -h host.docker.internal -p 15432
Password for user root:
以下是一些可能有用的 nslookup/ifconfig 日志:
Server: 192.168.65.1
Address: 192.168.65.1#53
Non-authoritative answer:
Name: host.docker.internal
Address: 192.168.65.2
bash-5.0# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:984 (984.0 B) TX bytes:202 (202.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:29 (29.0 B) TX bytes:29 (29.0 B)
为什么 docker 容器和主机之间的连接存在差异? host.docker.internal 如何解决底层问题?是否有其他方法通过提供 docker 运行 标志来解决问题?
当为 Mac 或 Windows 使用 Docker 时,虚拟机用于 运行 您的容器。
即使使用 --net=host
,容器也不会直接 运行 在您的桌面上,而是在 VM 上。因此 127.0.0.1 是 VM IP,而不是主机 IP。你可以像你说的那样,在Mac/Windows上使用host.docker.internal
来获取真机的IP。
在 Linux 容器 运行 上没有 VM,因此直接在真实主机上。
您可能想要调查远程呈现是否可以以更通用和更稳健的方式解决您的用例:https://www.telepresence.io/