一、Docker网络那些事儿
刚开始用Docker的时候,总觉得容器之间通信特别玄学——明明在本地跑得好好的服务,一放进容器就互相找不着北。后来才发现,这锅得Docker的默认网络设置来背。今天咱们就来聊聊怎么优化这个默认配置,让容器们愉快地聊天。
Docker安装后会默认创建三种网络:bridge(默认)、host和none。大多数情况下,你的容器都跑在bridge网络上,但这个默认桥接网络有个致命伤:容器间只能用IP地址通信,而且每次重启容器IP都可能变。想象一下,你每次叫同事都得先问他今天坐哪个工位,这谁受得了?
# 查看Docker现有网络(技术栈:Docker CLI)
docker network ls
# 输出示例:
# NETWORK ID NAME DRIVER SCOPE
# a1b2c3d4e5f6 bridge bridge local
# d7e8f9g0h1i2 host host local
# j3k4l5m6n7o8 none null local
二、手动创建自定义桥接网络
解决上述问题最直接的办法就是自定义桥接网络。和默认桥接网络不同,自定义网络中的容器既可以用IP通信,也能直接用容器名互相访问。下面我们动手创建一个:
# 创建名为my_net的自定义网络(技术栈:Docker CLI)
docker network create --driver bridge my_net
# 运行两个容器并加入该网络
docker run -d --name web --network my_net nginx
docker run -d --name db --network my_net redis
# 进入web容器测试能否ping通db
docker exec -it web ping db
# 成功输出表示容器间通过主机名通信正常
关键优势:
- DNS自动解析:容器名直接当域名用
- 隔离性:不同项目的容器可以用不同网络
- 稳定性:容器重启后IP可能变化,但名字始终有效
三、高级网络参数调优
对于生产环境,我们还需要关注这些参数:
# 创建带高级配置的网络(技术栈:Docker CLI)
docker network create \
--subnet=172.20.0.0/16 \ # 指定子网范围
--gateway=172.20.0.1 \ # 设置网关
--opt "com.docker.network.bridge.name"="mybridge" \ # 自定义网桥名
my_advanced_net
# 验证网络配置
docker network inspect my_advanced_net
# 输出中会显示详细的IPAM配置和选项
注意事项:
- 子网不要和宿主机或其他网络冲突
- 对延迟敏感的应用可以添加
--internal禁止外网访问 - 大数据量传输时考虑调整MTU(默认1500可能不适合云环境)
四、容器通信的典型问题解决方案
场景1:跨主机容器互联
当容器分布在多台宿主机时,默认的桥接网络就不够用了。这时候可以用Overlay网络(需要Swarm模式):
# 初始化Swarm集群(技术栈:Docker Swarm)
docker swarm init
# 创建跨主机的Overlay网络
docker network create --driver overlay --attachable my_overlay
# 在不同主机运行的容器都能加入此网络
docker service create --network my_overlay --name demo nginx
场景2:容器访问宿主机服务
当容器需要访问宿主机上的MySQL等服务时,直接用localhost会指向容器自己。这时候有两种方案:
# 方案1:使用host.docker.internal(Mac/Windows版Docker默认支持)
ping host.docker.internal
# 方案2:启动时添加--add-host参数(Linux通用方案)
docker run --add-host host.docker.internal:host-gateway your_image
五、安全加固与监控
网络通了之后,别忘了安全问题:
# 限制容器网络权限(技术栈:Docker安全)
docker run \
--network my_net \
--cap-drop NET_RAW \ # 禁止RAW套接字
--read-only \ # 只读文件系统
nginx
# 查看容器网络流量
docker stats --format "table {{.Name}}\t{{.NetIO}}"
推荐的安全实践:
- 非必要不暴露端口(避免使用
-p 80:80) - 为每个微服务创建独立网络
- 定期检查
iptables规则(Docker会动态修改)
六、实战案例:微服务网络规划
假设我们有一个电商系统,包含以下服务:
- 前端(Vue.js)
- 订单服务(Spring Boot)
- 支付服务(Go)
- MySQL数据库
- Redis缓存
合理的网络架构应该是:
# 创建业务网络
docker network create --driver bridge ecommerce
# 启动数据库服务(隔离在后端子网)
docker run -d --name mysql --network ecommerce -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
# 启动应用服务(可互相通信但隔离数据库)
docker run -d --name order-service --network ecommerce -p 8080:8080 spring-boot-app
docker run -d --name payment-service --network ecommerce -p 8081:8081 go-app
七、总结与建议
经过这些优化,你的Docker网络应该已经告别了"失联"状态。最后给三个黄金建议:
- 永远不要用默认的bridge网络,就像不要用root用户跑应用一样
- 网络划分要遵循最小权限原则
- 复杂环境考虑上Kubernetes的CNI插件
记住,好的网络设计应该是:让该通的流量畅通无阻,不该通的流量寸步难行。
评论