Docker Compose启动容器未加入docker0网桥及生产环境疑问
一、为什么docker-compose启动的容器不在docker0网桥?
这不是你的操作错误,而是Docker Compose的默认行为!
Docker Compose默认会为你的项目创建一个专属的自定义网桥(而非使用默认的docker0网桥),这个网桥的名字通常是你的项目名_default(比如你的项目是meanchat,对应的网络名就是meanchat_default)。你可以通过以下命令查看这个网络里的容器:
docker network inspect meanchat_default
执行后就能看到所有通过docker-compose启动的容器(meanchat_client_1、meanchat_myserver_1等)都在这个自定义网桥上。
而你用docker run meanchat_myserver启动容器时,因为没有指定网络,Docker会默认把容器加入默认的bridge网络(也就是docker0),所以你在docker network inspect bridge里能看到它。
为什么Docker Compose要用自定义网桥?
自定义网桥相比docker0有个核心优势:支持容器名/服务名的DNS解析。也就是说,在你的compose网络里,myserver容器可以直接用mongo这个名字访问MongoDB服务,nginx也可以用client和myserver来访问对应的容器,完全不需要依赖IP地址——这比docker0的IP访问方便太多,也是Docker官方推荐的服务发现方式。
如果你确实想让compose容器强制加入docker0网桥,可以在docker-compose.yml里显式指定使用默认bridge网络,但非常不推荐这么做(会失去DNS解析能力):
version: '3' services: client: build: ./ volumes: - ./:/usr/src/app networks: - default myserver: build: ./express-server volumes: - ./:/usr/src/app depends_on: - mongo networks: - default nginx: build: ./nginx ports: - "80:80" networks: - default mongo: environment: - AUTH=yes - MONGO_INITDB_ROOT_USERNAME=superAdmin - MONGO_INITDB_ROOT_PASSWORD=admin123 - MONGO_INITDB_DATABASE=d0c4ae452a5c image: mongo volumes: - /var/mongodata/data:/data/db networks: - default networks: default: external: name: bridge
二、生产环境依赖docker0网桥的固定IP访问可行吗?
绝对不推荐,哪怕你假设容器IP不会变化,也存在诸多风险:
- IP动态变化的必然性:Docker默认给容器动态分配IP,容器重启、网络IP池变动时,IP都可能改变。即使手动指定IP,也会增加运维复杂度,一旦出现IP冲突,直接导致容器启动失败。
- 服务发现能力缺失:生产环境中容器经常会扩容、重启、替换,依赖固定IP会让服务耦合度极高,IP变动后所有依赖该IP的服务都要修改配置,完全不符合微服务的运维理念。
- 安全隔离性差:docker0是所有默认容器共享的网络,不同项目的容器可以互相访问,存在安全隐患;而自定义网桥是项目隔离的,只有同一项目的容器能互通。
生产环境的正确做法
就用Docker Compose默认创建的自定义网桥,服务之间通过服务名(比如myserver、mongo)互相访问。如果是跨compose项目的服务,可以创建共享的自定义网桥,让多个项目的容器加入同一网络,依然用服务名访问。
另外你的nginx服务,因为和client、myserver在同一个自定义网桥上,所以nginx配置里可以直接用client:4200和myserver:3000作为上游地址,完全不需要依赖IP。
内容的提问来源于stack exchange,提问作者oudekaas

