为什么 docker 容器已经设置 network_mode:"host" 而 public 仍然可以从 "http://ip:port" 访问
Why docker container already set network_mode:"host" and the public still can access from "http://ip:port"
我试着做这样的架构:
- docker_container_1 nginx:暴露给 public (network_mode:"bridge", port:80)
- docker_container_2 web_serverI: 作为内部服务 (network_mode:"host", port:8080)
- docker_container_2 web_serverII: 作为内部服务 (network_mode:"host", port:8081)
upstream server-i {
server 172.17.0.1:8080;
}
upstream server-ii {
server 172.17.0.1:8081;
}
server {
listen 80;
server_name localhost;
location /service-i {
proxy_pass http://server-i;
}
location /service-ii {
proxy_pass http://server-ii;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
- 我已经设置了服务 i 和 ii network_mode:"host"
- 比起我用“docker ps”来检查,只有nginx PORTS显示
0.0.0.0:80->80/tcp,其他什么都没有。
- 而且我还使用“docker stats”来检查,所有容器的 NET I/O 只有 nginx 的值为零。
- 我发现仍然可以从外部访问 server_i server-ii:http://ip:port(8080 and 8081)
怎么办?我错过了什么吗?
如果您指定 network_mode: host
,它会禁用该容器的所有 Docker 网络功能。您不能重新映射容器端口或阻止它在主机上可见;您不能使用正常的 Docker 容器间网络在容器之间进行连接。从网络的角度来看,您的主机网络容器与直接在主机上的非 Docker 进程 运行 没有区别。
主机网络几乎从不需要。 在一些非常不寻常的情况下——如果您的服务有数千个端口,如果您已经测量了 Docker NAT 开销对于非常大的流量来说非常重要——它可以绕过 Docker 网络系统的一些限制。在几乎所有实际情况下,您都应该使用默认(桥接)网络,如果需要它们可以从外部访问,则发布特定端口 Docker space.
你应该:
- 禁用所有容器上的主机网络;请改用标准桥接网络。 (在非 Compose 上下文中,您需要
docker network create
具有默认设置的网络。)
- 更新您的 Nginx 配置以使用其他容器的名称作为主机名;
server docker_container_2 web_serverI:8080
。有关更多详细信息,请参见示例 Networking in Compose。
- 如果您不希望后端容器从 Docker space 外部可见,请移除其 Compose
ports:
配置或 docker run -p
选项。没有这个,容器间通信仍然有效。
我试着做这样的架构:
- docker_container_1 nginx:暴露给 public (network_mode:"bridge", port:80)
- docker_container_2 web_serverI: 作为内部服务 (network_mode:"host", port:8080)
- docker_container_2 web_serverII: 作为内部服务 (network_mode:"host", port:8081)
upstream server-i {
server 172.17.0.1:8080;
}
upstream server-ii {
server 172.17.0.1:8081;
}
server {
listen 80;
server_name localhost;
location /service-i {
proxy_pass http://server-i;
}
location /service-ii {
proxy_pass http://server-ii;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
- 我已经设置了服务 i 和 ii network_mode:"host"
- 比起我用“docker ps”来检查,只有nginx PORTS显示 0.0.0.0:80->80/tcp,其他什么都没有。
- 而且我还使用“docker stats”来检查,所有容器的 NET I/O 只有 nginx 的值为零。
- 我发现仍然可以从外部访问 server_i server-ii:http://ip:port(8080 and 8081) 怎么办?我错过了什么吗?
如果您指定 network_mode: host
,它会禁用该容器的所有 Docker 网络功能。您不能重新映射容器端口或阻止它在主机上可见;您不能使用正常的 Docker 容器间网络在容器之间进行连接。从网络的角度来看,您的主机网络容器与直接在主机上的非 Docker 进程 运行 没有区别。
主机网络几乎从不需要。 在一些非常不寻常的情况下——如果您的服务有数千个端口,如果您已经测量了 Docker NAT 开销对于非常大的流量来说非常重要——它可以绕过 Docker 网络系统的一些限制。在几乎所有实际情况下,您都应该使用默认(桥接)网络,如果需要它们可以从外部访问,则发布特定端口 Docker space.
你应该:
- 禁用所有容器上的主机网络;请改用标准桥接网络。 (在非 Compose 上下文中,您需要
docker network create
具有默认设置的网络。) - 更新您的 Nginx 配置以使用其他容器的名称作为主机名;
server docker_container_2 web_serverI:8080
。有关更多详细信息,请参见示例 Networking in Compose。 - 如果您不希望后端容器从 Docker space 外部可见,请移除其 Compose
ports:
配置或docker run -p
选项。没有这个,容器间通信仍然有效。