4、Docker网络与存储:Docker网络模式(bridge/host/none/overlay)、端口映射与容器互联、数据卷(Volume)与绑定挂载(Bind Mount)、数据卷容器与备份恢复
聊到 Docker,很多人第一反应是「打包应用」。但真正用起来,你会发现网络和存储才是日常踩坑的重灾区。我刚开始带团队做容器化迁移时,就因为在 overlay 网络上配错了子网,导致跨主机容器互相找不到,排查了整整一个下午。嗯,今天咱们就把这块彻底捋清楚。
4.1 Docker 网络模式:四种核心选择
Docker 默认提供了四种网络模式。说白了,就是决定你的容器怎么「上网」、怎么「被访问」。
| 网络模式 | 特点 | 适用场景 |
|---|---|---|
| bridge | 默认模式,容器通过虚拟网桥与宿主机通信 | 单机多容器互联 |
| host | 容器直接使用宿主机网络栈,无隔离 | 性能敏感型应用(如 Nginx) |
| none | 容器无网络接口,完全隔离 | 安全沙箱、离线计算 |
| overlay | 跨主机容器通信,依赖 Swarm 或 K8s | 集群部署、微服务 |
4.1.1 bridge 模式:最常用的默认选择
每次你执行 docker run 不加 --network,Docker 就会自动把容器挂到 docker0 这个虚拟网桥上。容器之间可以通过 IP 直接通信,但默认不能通过容器名访问。
我个人习惯在单机开发时,先创建一个自定义 bridge 网络:
docker network create my-bridge
docker run -d --name web --network my-bridge nginx
docker run -d --name app --network my-bridge my-app
这样 web 和 app 就能通过容器名互相 ping 通了。为什么?因为自定义 bridge 自动提供了 DNS 解析。默认的 docker0 可没有这个能力。
4.1.2 host 模式:性能优先
host 模式直接把容器和宿主机共享网络命名空间。容器里监听 80 端口,就等于宿主机监听 80 端口。没有 NAT 转换,性能损耗几乎为零。
我在项目中遇到过,一个高并发的日志采集器,用 bridge 模式每秒只能处理 5 万条,换成 host 模式直接飙到 8 万。但代价是——端口冲突风险大增。你想想看,两个容器都想用 8080,那就炸了。
4.1.3 none 模式:完全隔离
这个模式最简单——容器里只有 loopback 接口,连不上外网,外网也连不上它。适合跑一些离线计算任务,或者安全要求极高的场景。
4.1.4 overlay 模式:跨主机通信的关键
当你需要让不同物理机上的容器互相通信时,overlay 就派上用场了。它基于 VXLAN 技术,在宿主机之间建立隧道。
使用前提是 Docker Swarm 或 Kubernetes 集群已经初始化:
docker network create -d overlay my-overlay
docker service create --network my-overlay --name web nginx
这里有个坑:overlay 网络默认只能在 Swarm 服务中使用。如果你用 docker run 启动容器,需要加 --attachable 参数。我记得第一次部署时没加这个,容器死活连不上 overlay 网络,查了半天文档才找到原因。
4.2 端口映射与容器互联
容器默认是隔离的,外部访问不到。端口映射就是给容器开个「门」。
4.2.1 端口映射:-p 的三种写法
# 随机映射宿主机端口到容器 80
docker run -p 80 nginx
# 指定宿主机 8080 映射到容器 80
docker run -p 8080:80 nginx
# 指定 IP 和端口
docker run -p 192.168.1.100:8080:80 nginx
我个人建议生产环境一定要指定宿主机端口,否则 Docker 随机分配一个端口,你连防火墙规则都没法写。
4.2.2 容器互联:--link 已过时
老版本的 Docker 用 --link 实现容器互联。但现在官方已经明确标记为遗留特性。为什么?因为 --link 是单向的,而且容器重启后 IP 会变,容易出问题。
现在推荐的做法是:
- 单机场景:使用自定义 bridge 网络 + 容器名通信
- 集群场景:使用 overlay 网络 + 服务发现
--link 别急着改。但新项目一律用网络驱动。我曾经接手过一个遗留系统,里面全是 --link,每次重启容器都要手动调整顺序,痛苦不堪。
4.3 数据卷(Volume)与绑定挂载(Bind Mount)
容器是无状态的,一重启数据就丢了。所以我们需要持久化存储。
| 方式 | 管理方式 | 适用场景 |
|---|---|---|
| Volume | 由 Docker 管理,存储在 /var/lib/docker/volumes/ | 数据库、配置文件 |
| Bind Mount | 直接映射宿主机目录 | 开发调试、日志收集 |
4.3.1 Volume:推荐的生产方式
# 创建数据卷
docker volume create my-data
# 挂载到容器
docker run -v my-data:/app/data nginx
Volume 的好处是跨平台兼容性好,而且 Docker 会帮你处理权限问题。我在项目中用 Volume 来存 MySQL 数据,备份恢复都很方便。
4.3.2 Bind Mount:开发调试利器
docker run -v /host/path:/container/path nginx
开发时我经常用 Bind Mount,把本地代码直接映射到容器里,改完代码容器自动生效,不用重新构建镜像。但生产环境慎用——宿主机目录权限问题很容易导致容器启动失败。
4.4 数据卷容器与备份恢复
有时候你需要让多个容器共享数据,或者给数据做备份。数据卷容器就是专门干这个的。
4.4.1 数据卷容器:共享数据的桥梁
# 创建一个专门存数据的数据卷容器
docker create -v /data --name data-container busybox
# 其他容器通过 --volumes-from 共享数据
docker run --volumes-from data-container nginx
说白了,数据卷容器本身不跑业务,它就是个「数据中转站」。我习惯用它来共享配置文件,比如多个 Nginx 容器共用一套 SSL 证书。
4.4.2 备份与恢复:别等出事了再想
备份数据卷其实很简单:
# 备份:将数据卷内容打包到宿主机
docker run --rm --volumes-from data-container -v $(pwd):/backup busybox tar czf /backup/data-backup.tar.gz /data
# 恢复:解压到新数据卷
docker run --rm -v new-volume:/data -v $(pwd):/backup busybox tar xzf /backup/data-backup.tar.gz -C /data
这里有个关键点:--rm 参数让备份容器运行完就自动删除,不会留下垃圾容器。我每次做备份都会加这个参数,养成习惯很重要。
好了,网络和存储这块就聊到这儿。说白了,网络选型看你的部署规模,存储选型看你的数据重要性。记住一点:生产环境优先用 Volume 和自定义网络,开发环境可以灵活用 Bind Mount 和 bridge。下一章咱们聊聊 Docker Compose,到时候这些知识点都会串起来用。