如何配置容器通信规则仅允许API容器与DB容器通信
Docker容器间细粒度网络隔离实现方法
你要的访问限制不需要额外装防火墙插件,靠Docker自带的自定义网络能力就能实现,核心逻辑是靠网络成员资格做天然隔离:不在同一个自定义bridge网络内的容器,默认无法直接通信,比配复杂规则简单可靠得多。
具体操作步骤
- 先创建两个逻辑隔离的自定义bridge网络
# 公共业务网络,放web、mq这类不需要直连DB的服务 docker network create frontend-net # 数据库专属私有网络,只放DB和需要直连DB的服务 docker network create db-net - 按最小权限原则给每个容器分配网络
网络分配是权限控制的核心,别图省事全塞一个网络里:web、mq这类不需要访问DB的容器,只加入frontend-net,绝对不要加入db-netAPI容器需要同时对接前端流量和数据库,所以同时加入frontend-net、db-net两个网络DB容器只加入db-net,不要加入任何公共网络,非必要不要把DB端口映射到宿主机公网地址
docker-compose 配置参考
如果是用compose编排服务,直接按下面的结构写就能实现需求:
version: '3.8' services: web: image: nginx:alpine networks: - frontend-net mq: image: rabbitmq:alpine networks: - frontend-net api: image: 你的自定义API镜像 networks: - frontend-net - db-net db: image: mysql:8.0 networks: - db-net # 非调试场景不要加ports映射,避免通过宿主机地址绕开隔离 environment: MYSQL_ROOT_PASSWORD: 你的数据库密码 networks: frontend-net: driver: bridge db-net: driver: bridge
避坑提示
几个容易导致隔离失效的注意点:
- 不要用Docker默认的
bridge网络,默认网络没有内置DNS解析,隔离逻辑和自定义网络不一致,不适合生产用- 如果确实需要本地调试数据库,端口映射只绑本地回环地址就行,比如写
127.0.0.1:3306:3306,不要绑0.0.0.0暴露到公网- 自定义bridge网络默认是同网络内容器全通,所以
db-net里只放必须访问DB的服务,不要乱加其他容器
如果需要更细粒度的控制(比如同属db-net的服务也只允许API访问3306端口),可以在DB容器内部配置iptables规则,或者给网络关闭容器间通信(ICC)再单独加放行规则,但绝大多数业务场景下前面的网络划分方案已经完全满足需求,维护成本最低也不容易出配置错误。
内容的提问来源于stack exchange,提问作者Chel MS
相关产品推荐
相关产品推荐

