前言
前面我们学习了 Docker 三大核心组件与基础操作命令,本文重点讲解 Docker 两大核心进阶知识点 :数据持久化方案 和容器网络互联。解决容器删除数据丢失、外部访问容器、多容器通信等实际生产问题,包含数据卷、宿主机目录挂载、端口映射、自定义网络完整实操,可直接落地使用。
一、Docker 数据持久化
1.1 为什么需要数据持久化
默认情况下,容器的数据全部保存在可读写容器层 ,容器删除 → 容器层销毁 → 数据直接丢失。为了实现数据永久保存,Docker 提供两种主流持久化方案:
- 数据卷(Volumes):Docker 官方推荐,由 Docker 统一管理
- 挂载宿主机目录(Bind mounts):直接映射宿主机目录 / 文件
1.2 两种持久化方案对比
| 方式 | 存储位置 | 管理权限 | 安全性 | 适用场景 |
|---|---|---|---|---|
| 数据卷 Volumes | 宿主机固定目录/var/lib/docker/volumes/ |
仅 Docker 进程管理 | 高,隔离系统文件 | 容器数据持久化、生产环境首选 |
| 挂载目录 Bind mounts | 宿主机任意目录 / 文件 | 宿主机进程可修改 | 低,可篡改系统文件 | 配置文件共享、代码热更新 |
2、数据卷(Volumes)实操
2.1 数据卷核心特性
- 数据修改实时生效
- 数据更新不影响镜像
- 生命周期独立于容器,容器删除数据卷默认保留
2.2 数据卷基础命令
# 1. 创建数据卷
docker volume create my-vol
# 2. 查看所有数据卷
docker volume ls
# 3. 查看数据卷详细信息(存储路径、挂载点)
docker volume inspect my-vol
# 4. 清理无主数据卷(无容器引用)
docker volume prune
2.3 挂载数据卷到容器(-v 与 --mount)
Docker 提供两种挂载参数,推荐使用--mount,语义清晰、易维护。
两种参数区别
-v / --volume:用:分隔,顺序固定,适用于简单场景- 格式:
卷名:容器内路径:权限
- 格式:
--mount:键值对格式,支持详细配置,Docker17.06 + 通用- 常用参数:
type=volume、source=卷名、target=容器路径、readonly
- 常用参数:
实操示例
# 方式1:--mount 挂载数据卷(推荐)
docker run -d -P \
--name web \
--mount source=my-vol,target=/opt/webapp \
training/webapp python app.py
# 方式2:-v 挂载数据卷
docker run -d -P --name web -v my-vol:/opt/webapp training/webapp python app.py
# 查看容器挂载信息
docker inspect web
2.4 删除容器时同步删除数据卷
数据卷默认不会随容器删除,如需同步清理:
docker rm -v 容器ID
3、挂载宿主机目录(Bind mounts)
3.1 核心特点
- 直接将宿主机目录 / 文件映射到容器内
- 宿主机进程可直接修改容器内数据,存在安全风险
- 挂载规则:宿主机目录永远覆盖容器内目录
3.2 实操命令
# --mount 挂载宿主机目录
docker run -d -P \
--name web1 \
--mount type=bind,source=/src/webapp1,target=/opt/webapp \
training/webapp python app.py
# -v 简写方式
docker run -d -P --name web1 -v /src/webapp1:/opt/webapp training/webapp python app.py
3.3 只读挂载 + 挂载单个文件
1)只读挂载
容器内无法修改挂载目录数据,防止误操作:
docker run -d -P \
--mount type=bind,source=/data/dockershell/pydata,target=/opt/webapp,readonly \
training/webapp python app.py
2)挂载单个文件
常用于同步配置文件、命令历史等:
# 同步宿主机bash历史到容器
docker run --rm -it \
--mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
centos:7.9.2009 bash
3.4 数据覆盖规则(避坑重点)
- 数据卷
- 空数据卷挂载到容器非空目录:容器内文件复制到数据卷
- 非空数据卷挂载:数据卷内容覆盖容器内原有数据
- Bind 挂载
- 宿主机目录永远直接覆盖容器内对应目录数据
3.5 生产案例:Prometheus 挂载
方案 1:挂载宿主机目录(配置文件持久化)
docker run --name prometheus -d -p 9090:9090 \
-v /data/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml \
-v /data/prometheus/data:/prometheus \
prom/prometheus:v2.53.4
方案 2:使用数据卷(数据持久化)
docker run --name prometheus -d -p 9090:9090 \
-v /data/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml \
-v prometheus1:/prometheus \
prom/prometheus:v2.53.4
二、Docker 容器网络与互联
Docker 网络解决两个核心问题:外部访问容器 、容器之间互相通信。
4.1 外部访问容器:端口映射
容器默认隔离网络,外部无法访问,通过-P/-p实现端口映射。
1)-P:随机端口映射
Docker 自动随机分配宿主机端口,映射容器开放端口:
# 后台运行web容器,随机端口映射
docker run -d -P training/webapp python app.py
# 查看端口映射
docker ps -l
# 查看详细端口
docker port 容器ID
2)-p:指定端口映射(生产常用)
支持 4 种格式:
-
hostPort:containerPort:宿主机端口:容器端口 -
ip:hostPort:containerPort:指定 IP + 端口映射 -
ip::containerPort:指定 IP,随机宿主机端口 -
支持 UDP 协议、多端口映射
宿主机5000 → 容器5000
docker run -d -p 5000:5000 training/webapp python app.py
绑定指定IP
docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
UDP端口映射
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
多端口映射
docker run -d -p 6000:5000 -p 3000:80 training/webapp python app.py
4.2 容器互联:自定义网桥网络(推荐)
废弃旧的--link参数,生产环境统一使用自定义 bridge 网络,实现 DNS 自动解析、容器名称互通。
创建自定义网桥
# 创建桥接网络 mynet
docker network create -d bridge mynet
容器加入自定义网络
# 终端1:运行busybox1,加入mynet网络
docker run -it --rm --name busybox1 --network mynet busybox sh
# 终端2:运行busybox2,加入mynet网络
docker run -it --rm --name busybox2 --network mynet busybox sh
容器互相通信 在busybox1内直接 ping 容器名busybox2,可直接连通,实现容器互联。
多容器复杂互联场景,推荐使用 Docker Compose 一键编排。
三、总结
- 数据持久化
- 容器默认数据在可读写层,删除即丢失;
- 生产首选数据卷 Volumes ,安全隔离;简单配置共享用Bind 挂载;
- 挂载核心坑:宿主机目录会覆盖容器内目录,注意文件丢失。
- 网络互联
- 外部访问:
-p指定端口映射,优先固定端口; - 容器互通:自定义 bridge 网络 ,替代
--link,支持容器名 DNS 解析; - 多容器编排:使用 Docker Compose 统一管理。
- 外部访问: