首页 > 解决方案 > 为什么 docker 容器已经设置了 network_mode:"host" 并且公众仍然可以从 "http://ip:port" 访问

问题描述

我尝试制作这样的架构:

  1. docker_container_1 nginx:公开(network_mode:“桥”,端口:80)
  2. docker_container_2 web_serverI:作为内部服务(network_mode:“主机”,端口: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;
    }
}

标签: dockernginxnetworkingdocker-composeport

解决方案


如果您指定network_mode: host,它将禁用该容器的所有 Docker 网络功能。您不能重新映射容器端口或阻止它在主机上可见;你不能使用普通的 Docker 容器间网络来连接容器。从网络的角度来看,您的主机网络容器与直接在主机上运行的非 Docker 进程没有区别。

几乎从不需要主机网络。 在一些非常不寻常的情况下——如果你的服务有数千个它监听的端口,如果你测量到 Docker NAT 开销对于非常大的流量来说很重要——它可以绕过 Docker 网络系统的一些限制. 在几乎所有实际情况下,您应该使用默认(桥接)网络,并在需要从 Docker 空间外部访问它们时发布特定端口。

你应该:

  • 禁用所有容器上的主机网络;请改用标准桥接网络。(在非 Compose 上下文中,您需要docker network create使用默认设置的网络。)
  • 更新您的 Nginx 配置以使用其他容器的名称作为主机名;server docker_container_2 web_serverI:8080. 有关更多详细信息,请参阅Compose 中的网络示例。
  • 如果您不希望后端容器在 Docker 空间之外可见,请删除它们的 Composeports:配置或docker run -p选项。没有这个,容器间通信仍然可以工作。

推荐阅读