为什么 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"

我试着做这样的架构:

  1. docker_container_1 nginx:暴露给 public (network_mode:"bridge", port:80)
  2. docker_container_2 web_serverI: 作为内部服务 (network_mode:"host", port:8080)
  3. 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;
    }
}

如果您指定 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 选项。没有这个,容器间通信仍然有效。