Docker Compose网络隔离失效:前端与后端违规连通问题排查
问题
我有三个Docker Compose文件,每个文件对应单个服务,各自创建独立网络,仅通过external引用必要的其他网络。
架构通信要求
- Frontend ↔ Service
- Service ↔ Backend
- 禁止 Frontend ↔ Backend
异常现象
执行docker exec frontend ping backend和docker exec backend ping frontend均能成功连通。
当前配置文件
Frontend的docker-compose.yaml
services: frontend: image: alpine container_name: frontend networks: - frontend_net - service_net entrypoint: "/bin/sh -c 'trap exit TERM; while :; do echo alive; sleep 10m & wait $${!}; done;'" networks: frontend_net: name: frontend_net attachable: true #internal: true service_net: external: true
Service的docker-compose.yaml
services: service: image: alpine container_name: service networks: - service_net entrypoint: "/bin/sh -c 'trap exit TERM; while :; do echo alive; sleep 10m & wait $${!}; done;'" networks: service_net: name: service_net #internal: true
Backend的docker-compose.yaml
services: backend: image: alpine container_name: backend networks: - backend_net - service_net entrypoint: "/bin/sh -c 'trap exit TERM; while :; do echo alive; sleep 10m & wait $${!}; done;'" networks: backend_net: name: backend_net attachable: true #internal: true service_net: external: true
已创建的网络列表
# docker network list NETWORK ID NAME DRIVER SCOPE 4b162b628e76 backend_net bridge local f118e228948d bridge bridge local b3bf160b09a3 frontend_net bridge local 45ff3d4f66d0 host host local 8eedcf91c792 none null local a745922e2eea service_net bridge local
问题分析与修复方案
问题根源
Docker自定义bridge网络(比如你创建的service_net)会默认允许所有连接到该网络的容器互相通信,同时自动配置DNS解析让容器能直接访问彼此。现在Frontend和Backend都连接到了service_net,属于同一网络环境,自然能互相ping通,完全违反了禁止二者直接通信的架构要求。
修复步骤
要实现隔离,必须让Frontend和Backend不共享任何直接的网络连接,仅通过Service作为中转节点。正确的配置逻辑是:
- 为Service创建两个独立的专用网络:一个用于和Frontend通信(如
frontend_service_net),另一个用于和Backend通信(如backend_service_net) - Frontend仅连接自身的
frontend_net和frontend_service_net - Service同时连接
frontend_service_net和backend_service_net,作为通信中转 - Backend仅连接自身的
backend_net和backend_service_net
修正后的配置示例
Frontend的docker-compose.yaml
services: frontend: image: alpine container_name: frontend networks: - frontend_net - frontend_service_net entrypoint: "/bin/sh -c 'trap exit TERM; while :; do echo alive; sleep 10m & wait $${!}; done;'" networks: frontend_net: name: frontend_net attachable: true frontend_service_net: external: true
Service的docker-compose.yaml
services: service: image: alpine container_name: service networks: - frontend_service_net - backend_service_net entrypoint: "/bin/sh -c 'trap exit TERM; while :; do echo alive; sleep 10m & wait $${!}; done;'" networks: frontend_service_net: name: frontend_service_net backend_service_net: name: backend_service_net
Backend的docker-compose.yaml
services: backend: image: alpine container_name: backend networks: - backend_net - backend_service_net entrypoint: "/bin/sh -c 'trap exit TERM; while :; do echo alive; sleep 10m & wait $${!}; done;'" networks: backend_net: name: backend_net attachable: true backend_service_net: external: true
调整后,Frontend和Backend没有共同的网络连接,只能通过Service间接通信,完全符合架构要求。
内容的提问来源于stack exchange,提问作者gerry
相关产品推荐
相关产品推荐

