无法在 docker 容器内访问 kubectl port-forward

Ben*_*han 8 macos networking docker kubernetes docker-for-mac

假设有一个 pod(例如 postgres)在 kubernetes 中运行,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验证消息。

但是,无论是否使用该标志,都无法使用容器内的127.0.0.1/访问端口转发的 Pod。它只能通过172.17.0.1--network=hosthost.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:
Run Code Online (Sandbox Code Playgroud)

以下是一些可能有用的 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)
Run Code Online (Sandbox Code Playgroud)

为什么 docker 容器和主机之间的连接存在差异?host.docker.internal 如何解决底层问题?是否有其他方法通过提供 docker run 标志来解决问题?

Tho*_*mas 7

在 Mac 或 Windows 上使用 Docker 时,虚拟机用于运行容器。即使有了--net=host容器,也不会直接在桌面上运行,而是在虚拟机上运行。因此,127.0.0.1 是虚拟机 IP,而不是主机 IP。如你所说,在Mac/Windows上可以使用host.docker.internal来获取真机的IP。在 Linux 上,容器在没有虚拟机的情况下运行,因此直接在真实主机上运行。

您可能想调查网真是否可以以更通用和更强大的方式解决您的用例: https: //www.telepresence.io/