Docker 存储管理
核心知识点
1. Docker 存储概述
1.1 存储驱动类型
Docker 支持多种存储驱动,适用于不同的文件系统:
┌─────────────────────────────────────────────────────────────┐
│ Docker 存储驱动 │
├─────────────────────────────────────────────────────────────┤
│ │
│ overlay2 ──> 推荐驱动,性能好 │
│ aufs ──> 旧版驱动,逐渐淘汰 │
│ btrfs ──> 支持高级功能,需要特定文件系统 │
│ zfs ──> 企业级功能,需要特定文件系统 │
│ vfs ──> 简单但性能差,用于测试 │
│ │
└─────────────────────────────────────────────────────────────┘1.2 存储方式对比
| 存储方式 | 特点 | 适用场景 |
|---|---|---|
| 数据卷 (Volume) | 由 Docker 管理,独立于宿主机 | 持久化数据、数据共享 |
| 绑定挂载 (Bind Mount) | 直接挂载宿主机目录 | 开发环境、配置文件 |
| 临时文件系统 (tmpfs) | 存储在内存中 | 临时数据、敏感信息 |
2. 数据卷管理
2.1 创建数据卷
# 创建命名数据卷
docker volume create my-data
# 创建时指定驱动
docker volume create --driver local my-data
# 查看数据卷列表
docker volume ls
# 查看数据卷详细信息
docker volume inspect my-data
# 查看数据卷使用情况
docker volume ls -f dangling=true2.2 使用数据卷
# 运行容器并挂载数据卷
docker run -d \
--name my-app \
-v my-data:/app/data \
nginx:latest
# 挂载多个数据卷
docker run -d \
--name my-app \
-v data1:/app/data1 \
-v data2:/app/data2 \
nginx:latest
# 只读挂载数据卷
docker run -d \
--name my-app \
-v my-data:/app/data:ro \
nginx:latest
# 查看容器的挂载信息
docker inspect my-app | grep -A 20 Mounts2.3 数据卷操作
# 复制数据到数据卷
docker run --rm -v my-data:/target busybox sh -c "echo 'Hello' > /target/file.txt"
# 从数据卷复制数据
docker run --rm -v my-data:/source busybox cat /source/file.txt
# 备份数据卷
docker run --rm -v my-data:/data -v $(pwd):/backup busybox \
tar czf /backup/my-data-backup.tar.gz -C /data .
# 恢复数据卷
docker run --rm -v my-data:/data -v $(pwd):/backup busybox \
tar xzf /backup/my-data-backup.tar.gz -C /data
# 删除数据卷
docker volume rm my-data
# 删除未使用的数据卷
docker volume prune3. 绑定挂载
3.1 基本绑定挂载
# 挂载宿主机目录
docker run -d \
--name my-app \
-v /host/path:/container/path \
nginx:latest
# 挂载宿主机文件
docker run -d \
--name my-app \
-v /host/file.txt:/container/file.txt \
nginx:latest
# 只读挂载
docker run -d \
--name my-app \
-v /host/path:/container/path:ro \
nginx:latest
# 使用绝对路径
docker run -d \
--name my-app \
-v $(pwd)/html:/usr/share/nginx/html \
nginx:latest3.2 高级绑定挂载
# 挂载时指定权限
docker run -d \
--name my-app \
-v /host/path:/container/path:rw \
nginx:latest
# 挂载时指定用户和组
docker run -d \
--name my-app \
-v /host/path:/container/path:rw,Z \
nginx:latest
# 使用 --mount 语法(推荐)
docker run -d \
--name my-app \
--mount type=bind,source=/host/path,target=/container/path \
nginx:latest
# 只读绑定
docker run -d \
--name my-app \
--mount type=bind,source=/host/path,target=/container/path,readonly \
nginx:latest4. 临时文件系统
4.1 创建 tmpfs 挂载
# 使用 tmpfs 挂载
docker run -d \
--name my-app \
--tmpfs /tmp \
nginx:latest
# 指定 tmpfs 大小
docker run -d \
--name my-app \
--tmpfs /tmp:size=100m \
nginx:latest
# 指定 tmpfs 权限
docker run -d \
--name my-app \
--tmpfs /tmp:rw,exec,size=100m \
nginx:latest
# 使用 --mount 语法
docker run -d \
--name my-app \
--mount type=tmpfs,destination=/tmp,tmpfs-size=100m \
nginx:latest4.2 tmpfs 使用场景
# 存储临时文件
docker run -d \
--name cache-app \
--tmpfs /cache:size=500m \
redis:latest
# 存储敏感信息(不持久化)
docker run -d \
--name secure-app \
--tmpfs /secrets:size=10m \
nginx:latest
# 查看挂载信息
docker inspect cache-app | grep -A 10 Mounts5. 存储驱动配置
5.1 查看存储驱动
# 查看当前存储驱动
docker info | grep "Storage Driver"
# 查看存储驱动详细信息
docker info | grep -A 20 "Storage Driver"
# 查看数据目录
docker info | grep "Docker Root Dir"5.2 配置存储驱动
# 修改 Docker 配置文件
sudo vi /etc/docker/daemon.json
# 添加存储驱动配置
{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
# 重启 Docker 服务
sudo systemctl restart docker
# 验证配置
docker info | grep "Storage Driver"6. 数据备份与恢复
6.1 备份数据卷
# 方法1:使用 tar 备份
docker run --rm \
-v my-data:/data \
-v $(pwd):/backup \
busybox \
tar czf /backup/my-data-$(date +%Y%m%d).tar.gz -C /data .
# 方法2:使用 rsync 备份
docker run --rm \
-v my-data:/data \
-v $(pwd):/backup \
alpine \
sh -c "apk add --no-cache rsync && rsync -av /data/ /backup/"
# 方法3:使用 docker cp 备份
docker run -d --name temp-container -v my-data:/data busybox sleep 1000
docker cp temp-container:/data ./backup
docker rm -f temp-container6.2 恢复数据卷
# 方法1:使用 tar 恢复
docker run --rm \
-v my-data:/data \
-v $(pwd):/backup \
busybox \
tar xzf /backup/my-data-20240101.tar.gz -C /data
# 方法2:使用 rsync 恢复
docker run --rm \
-v my-data:/data \
-v $(pwd):/backup \
alpine \
sh -c "apk add --no-cache rsync && rsync -av /backup/ /data/"
# 方法3:使用 docker cp 恢复
docker run -d --name temp-container -v my-data:/data busybox sleep 1000
docker cp ./backup/. temp-container:/data/
docker rm -f temp-container7. 存储性能优化
7.1 使用 overlay2 驱动
# 检查是否使用 overlay2
docker info | grep "Storage Driver"
# 如果不是,修改配置
sudo vi /etc/docker/daemon.json
{
"storage-driver": "overlay2"
}
# 重启 Docker
sudo systemctl restart docker7.2 优化数据卷性能
# 使用本地 SSD 存储
docker volume create --opt type=tmpfs --opt device=tmpfs --opt o=size=100g my-fast-volume
# 使用特定文件系统
docker volume create --opt type=none --opt device=/dev/sdb1 --opt o=bind my-ssd-volume
# 查看数据卷详细信息
docker volume inspect my-fast-volume实用案例分析
案例 1:数据库数据持久化
场景描述
为 MySQL 数据库配置数据持久化,确保数据安全。
操作步骤
# 1. 创建数据卷
docker volume create mysql-data
# 2. 启动 MySQL 容器
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=rootpassword \
-e MYSQL_DATABASE=myapp \
-p 3306:3306 \
mysql:5.7
# 3. 等待数据库启动
sleep 20
# 4. 连接数据库并创建测试数据
docker exec -i mysql mysql -uroot -prootpassword myapp << 'EOF'
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100)
);
INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com');
INSERT INTO users (name, email) VALUES ('李四', 'lisi@example.com');
EOF
# 5. 查询数据
docker exec mysql mysql -uroot -prootpassword myapp -e "SELECT * FROM users;"
# 6. 停止并删除容器
docker stop mysql
docker rm mysql
# 7. 重新启动容器(数据仍然存在)
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=rootpassword \
-e MYSQL_DATABASE=myapp \
-p 3306:3306 \
mysql:5.7
# 8. 验证数据
docker exec mysql mysql -uroot -prootpassword myapp -e "SELECT * FROM users;"
# 9. 清理
docker stop mysql
docker rm mysql
docker volume rm mysql-data案例 2:开发环境绑定挂载
场景描述
使用绑定挂载实现代码热重载,提高开发效率。
操作步骤
# 1. 创建项目目录
mkdir ~/my-web-app
cd ~/my-web-app
# 2. 创建 HTML 文件
cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>我的 Web 应用</title>
</head>
<body>
<h1>欢迎来到我的 Web 应用</h1>
<p>这是一个测试页面。</p>
</body>
</html>
EOF
# 3. 启动 Nginx 容器并挂载本地目录
docker run -d \
--name my-web \
-p 8080:80 \
-v $(pwd):/usr/share/nginx/html \
nginx:alpine
# 4. 测试访问
curl http://localhost:8080
# 5. 修改 HTML 文件
cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>我的 Web 应用</title>
</head>
<body>
<h1>欢迎来到我的 Web 应用</h1>
<p>这是一个测试页面。</p>
<p>页面已更新!</p>
</body>
</html>
EOF
# 6. 再次测试(无需重启容器)
curl http://localhost:8080
# 7. 查看容器日志
docker logs my-web
# 8. 清理
docker stop my-web
docker rm my-web案例 3:数据卷备份与恢复
场景描述
实现数据卷的定期备份和快速恢复。
操作步骤
# 1. 创建数据卷并添加数据
docker volume create app-data
docker run --rm -v app-data:/data busybox sh -c "echo '重要数据' > /data/important.txt"
# 2. 创建备份目录
mkdir -p ~/backups
# 3. 备份数据卷
docker run --rm \
-v app-data:/data \
-v ~/backups:/backup \
busybox \
tar czf /backup/app-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
# 4. 查看备份文件
ls -lh ~/backups
# 5. 模拟数据丢失
docker volume rm app-data
# 6. 从备份恢复
docker run --rm \
-v app-data:/data \
-v ~/backups:/backup \
busybox \
tar xzf /backup/app-data-$(ls ~/backups | tail -1) -C /data
# 7. 验证恢复的数据
docker run --rm -v app-data:/data busybox cat /data/important.txt
# 8. 清理
docker volume rm app-data
rm -rf ~/backups最佳实践
使用数据卷持久化重要数据:避免容器删除后数据丢失。
合理选择存储方式:
- 数据持久化:使用数据卷
- 开发环境:使用绑定挂载
- 临时数据:使用 tmpfs
定期备份数据卷:确保数据安全。
# 创建备份脚本
cat > ~/backup-volumes.sh << 'EOF'
#!/bin/bash
BACKUP_DIR=~/backups
DATE=$(date +%Y%m%d-%H%M%S)
mkdir -p $BACKUP_DIR
for volume in $(docker volume ls -q); do
docker run --rm \
-v $volume:/data \
-v $BACKUP_DIR:/backup \
busybox \
tar czf /backup/${volume}-${DATE}.tar.gz -C /data .
done
EOF
chmod +x ~/backup-volumes.sh
# 设置定时任务
crontab -e
# 添加:0 2 * * * /home/user/backup-volumes.sh- 监控存储使用情况:及时发现存储问题。
# 查看数据卷使用情况
docker system df -v
# 查看磁盘使用情况
df -h
# 查看容器磁盘使用
docker ps -s- 清理未使用的存储资源:释放磁盘空间。
# 清理未使用的数据卷
docker volume prune -f
# 清理未使用的镜像
docker image prune -a -f
# 清理未使用的容器
docker container prune -f
# 清理所有未使用的资源
docker system prune -a -f --volumes总结
本教程详细介绍了 Docker 的存储管理方法,包括数据卷、绑定挂载、临时文件系统等存储方式。通过实际案例,我们学习了如何持久化数据库数据、实现开发环境热重载以及备份和恢复数据卷。掌握这些技能后,可以有效地管理 Docker 容器的数据存储。