docker-compose: 在容器中打开端口但不从主机绑定它
docker-compose: open port in container but not bind it from host
(注意:整个问题是因为我读错了docker网络的IP地址。my-network
是172.22.0.0/16
127.22.0.0/16
。我稍微修改了 OP 以反映我遇到的原始问题)
我使用 docker-compose
创建了一个服务(一个小型网络服务器)。网络部分定义为
services:
service:
image: ... (this image uses port 9000)
ports:
- 9000:9000
networks:
default:
name: my-network
在 docker-compose up
之后,我观察到:
- 主机获得 IP 地址
172.22.0.1
,客户端获得 172.22.0.2
。
- 我可以从主机
ping 127.22.0.2
. 成功 ping 客户端
- 从主机:可以使用以下方式访问网络服务器
127.22.0.1:9000
127.22.0.2:9000
localhost:9000
192.168.0.10:9000
(这是主机在局域网中的IP地址)
现在我想仅使用 172.22.0.2:9000
来限制来自主机的访问。我觉得如果我不将容器的 9000 端口绑定到主机的 9000 端口,这应该是可能的。然后我从 docker-compose.yml
中删除了 ports: 9000:9000
部分。现在我观察:
- 以上四种方法现在都不行了,包括
127.22.0.2:9000
- 仍然可以使用
127.22.0.2
从主机 ping 客户端
我想:因为宿主机和容器都在一个桥接网络中my-network
并且已经获得了它们的IP地址。 Web 服务器应该仍然可以从 127.22.0.2:9000
访问。但事实并非如此。
我的问题:
- 为什么会这样?同一个子网
127.22.0.0/16
里的host/container不应该可以自由通话吗?
- 如何实现我想要的:不将端口 9000 从主机转发到容器,只允许使用其子网 IP 地址访问容器。
您对网络的理解是正确的。从 docker-compose.yml
中删除端口绑定将从主机中删除暴露的端口。由于主机也是虚拟网络的一部分 my-network
,其 IP 与容器位于同一子网中,因此您的服务应该可以直接使用容器 IP 从主机访问。
但我认为,这实际上是一个简单的错字,而不是
127.22.0.0/16
你居然有
172.22.0.0/16
作为 my-network
的子网!这是默认配置中 docker
使用的典型子网,而 127.0.0.0/8
is always bound to the loopback device!
所以连接到 127.22.0.2
实际上会将你连接到 localhost
- 这与你遇到的症状一致:
- 连接到
127.22.0.2:9000
仅当端口在主机上公开时才有效
- 你总是可以打印
127.22.0.2
因为它是环回地址
(注意:整个问题是因为我读错了docker网络的IP地址。my-network
是172.22.0.0/16
127.22.0.0/16
。我稍微修改了 OP 以反映我遇到的原始问题)
我使用 docker-compose
创建了一个服务(一个小型网络服务器)。网络部分定义为
services:
service:
image: ... (this image uses port 9000)
ports:
- 9000:9000
networks:
default:
name: my-network
在 docker-compose up
之后,我观察到:
- 主机获得 IP 地址
172.22.0.1
,客户端获得172.22.0.2
。 - 我可以从主机
ping 127.22.0.2
. 成功 ping 客户端
- 从主机:可以使用以下方式访问网络服务器
127.22.0.1:9000
127.22.0.2:9000
localhost:9000
192.168.0.10:9000
(这是主机在局域网中的IP地址)
现在我想仅使用 172.22.0.2:9000
来限制来自主机的访问。我觉得如果我不将容器的 9000 端口绑定到主机的 9000 端口,这应该是可能的。然后我从 docker-compose.yml
中删除了 ports: 9000:9000
部分。现在我观察:
- 以上四种方法现在都不行了,包括
127.22.0.2:9000
- 仍然可以使用
127.22.0.2
从主机 ping 客户端
我想:因为宿主机和容器都在一个桥接网络中my-network
并且已经获得了它们的IP地址。 Web 服务器应该仍然可以从 127.22.0.2:9000
访问。但事实并非如此。
我的问题:
- 为什么会这样?同一个子网
127.22.0.0/16
里的host/container不应该可以自由通话吗? - 如何实现我想要的:不将端口 9000 从主机转发到容器,只允许使用其子网 IP 地址访问容器。
您对网络的理解是正确的。从 docker-compose.yml
中删除端口绑定将从主机中删除暴露的端口。由于主机也是虚拟网络的一部分 my-network
,其 IP 与容器位于同一子网中,因此您的服务应该可以直接使用容器 IP 从主机访问。
但我认为,这实际上是一个简单的错字,而不是
127.22.0.0/16
你居然有
172.22.0.0/16
作为 my-network
的子网!这是默认配置中 docker
使用的典型子网,而 127.0.0.0/8
is always bound to the loopback device!
所以连接到 127.22.0.2
实际上会将你连接到 localhost
- 这与你遇到的症状一致:
- 连接到
127.22.0.2:9000
仅当端口在主机上公开时才有效 - 你总是可以打印
127.22.0.2
因为它是环回地址