docker_持久化存储
Docker Volumes 单机部署
要在 Docker 中使用 Volumes(卷) 来实现持久化存储,步骤非常简单。以下是具体的操作方法:
- 创建一个 Docker Volume
你可以通过 Docker CLI 来创建卷。执行以下命令创建一个名为 my_volume 的卷:
# 这将创建一个卷,Docker 会自动管理它的存储位置。
[root@localhost my-flask-app]# docker volume create my_volume
my_volume
# 可以通过这个命令查看创建的卷的信息
[root@localhost my-flask-app]# docker volume inspect my_volume
[
{
"CreatedAt": "2024-09-12T19:06:24+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/my_volume/_data",
"Name": "my_volume",
"Options": null,
"Scope": "local"
}
]
- 将 Volume 挂载到容器中
在启动容器时,可以通过 -v 选项将卷挂载到容器的指定目录。假设你要启动一个 Nginx 容器,并将卷挂载到 /usr/share/nginx/html 目录来存储网页文件:
# 这意味着容器内的 /usr/share/nginx/html 目录会与宿主机上 Docker 管理的 my_volume 挂载在一起,容器内对这个目录的写操作将会保存到卷中。
[root@localhost my-flask-app]# docker run -d --name my_nginx -v my_volume:/usr/share/nginx/html nginx
31c4848c29a99d9d60edde46772d2fc610edaa4816332320d6833e4ae4ad6606
- 在容器中操作数据
进入容器并在挂载的目录中操作数据:
# 然后进入 /usr/share/nginx/html 目录,创建文件或修改内容,这些数据都会保存在卷中。
# docker exec:用于在一个正在运行的容器中执行命令。
# -it:是两个选项的组合:
#-i:表示“interactive”(交互式),保持 STDIN(标准输入)打开,这样你可以在容器中进行交互操作。
#-t:表示“tty”(伪终端),为容器分配一个伪终端,这样你可以使用命令行界面。
#my_nginx:这是容器的名称或 ID,指定要在哪个容器中执行命令。
#/bin/bash:在容器中执行的命令,这里是启动 Bash shell。/bin/bash 是大多数 Linux 系统中 Bash shell 的路径,用于在容器内部打开一个命令行界面。
[root@localhost my-flask-app]# docker exec -it my_nginx /bin/bash
root@31c4848c29a9:/# cd /usr/
root@31c4848c29a9:/# cd /usr/share/nginx/html/
50x.html index.html
root@31c4848c29a9:/# cd /usr/share/nginx/html/
root@31c4848c29a9:/usr/share/nginx/html# echo "test Docker Volume" > index.html
- 查看卷内容
你可以通过以下命令在宿主机上查看 my_volume 中的数据路径(Docker 会将卷保存在默认存储位置,但它对用户透明):
[root@31c4848c29a9:/usr/share/nginx/html# exit
exit
[root@localhost my-flask-app]# cd /var/lib/docker/volumes/my_volume/_data
[root@localhost _data]# ls
50x.html index.html
[root@localhost _data]# cat index.html
test Docker Volume
该命令会显示卷的详细信息,包括宿主机上实际存储的路径。你也可以直接查看宿主机上的数据(卷通常存储在 /var/lib/docker/volumes/ 下)。
关闭容器后文件还是在
[root@localhost _data]# docker stop my_nginx
my_nginx
[root@localhost _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a869bd32ff54 my-flask "python3 app.py" 9 hours ago Up 9 hours 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp flamboyant_brattain
[root@localhost _data]# cat index.html
test Docker Volume
NFS 配置和 Docker 持久化存储的需求
NFS 服务端配置脚本
实现步骤:
- 安装 NFS 工具:确保服务端安装了 rpcbind 和 nfs-utils。
- 启动服务:启动并启用 rpcbind 和 NFS 服务。
- 验证服务状态:检查 NFS 服务是否启动成功。
- 创建共享目录:在服务端创建共享目录并设置权限。
- 配置共享目录:将共享目录配置添加到 /etc/exports。
- 导出目录:导出配置并重新启动 NFS 服务。
- 重新验证:确保 NFS 服务正确运行。
NFS 客户端配置脚本
实现步骤:
- 安装 NFS 客户端工具:确保客户端安装了 nfs-utils。
- 创建挂载目录:在客户端创建挂载点目录并设置权限。
- 配置挂载信息:将挂载信息添加到 /etc/fstab,避免重复添加。
- 挂载 NFS 共享:手动挂载 NFS 共享并验证挂载状态。
- 创建 Docker 卷:创建 Docker 卷并指定 NFS 驱动。
- 启动 Docker 容器:启动 Docker 容器并挂载 NFS 卷。
注意事项:
----确保 /mnt/nfs_client_share 目录在客户端存在且权限正确。
/etc/fstab 中的挂载信息应确保格式正确,避免挂载冲突。
创建 Docker 卷时确保使用正确的 NFS 配置。
检查 Docker 容器是否正确启动,并且能够访问 NFS 卷
实操:
nfs主机 这里用脚本一键部署:
#!/bin/bash
# 函数:验证 NFS 服务状态
nfs_status() {
if systemctl is-active --quiet nfs || [[ $(systemctl is-active nfs) == "exited" ]]; then
echo "NFS 服务启动成功"
else
echo "NFS 服务启动失败,请检查配置和日志"
sudo systemctl status nfs
exit 1
fi
}
# 安装 NFS 服务端工具
sudo yum -y install rpcbind nfs-utils
# 启动并启用 rpcbind 和 NFS 服务
sudo systemctl start rpcbind
sudo systemctl enable rpcbind
sudo systemctl start nfs
sudo systemctl enable nfs
# 验证 NFS 服务是否已启动
nfs_status
# 创建共享目录并设置权限
sudo mkdir -p /mnt/nfs_share
sudo chmod 777 /mnt/nfs_share # 允许所有人读写
# 配置共享目录权限到 /etc/exports
if ! grep -q "/mnt/nfs_share" /etc/exports; then
echo "/mnt/nfs_share 192.168.29.0/24(rw,sync,no_root_squash,no_subtree_check)" | sudo tee -a /etc/exports
fi
# 导出共享目录并刷新配置
sudo exportfs -r
sudo exportfs -v # 显示当前的导出配置
# 重启 NFS 服务以应用新配置
sudo systemctl restart nfs
# 验证 NFS 服务是否已启动
nfs_status
# 输出完成信息
echo "NFS 服务端配置完成,并已启动。共享目录已导出。"
docker 客户机:注意 下面脚本 包含了 客户主机的nfs挂载,不止是容器,我给总结到一起了,如果不需要可以删除
#!/bin/bash
# 安装 NFS 客户端工具
sudo yum -y install nfs-utils
# 创建客户端挂载点目录
sudo mkdir -p /mnt/nfs_client_share
sudo chmod 777 /mnt/nfs_client_share
# 确保不重复添加挂载信息到 /etc/fstab
if ! grep -q "192.168.29.188:/mnt/nfs_share" /etc/fstab; then
echo "192.168.29.188:/mnt/nfs_share /mnt/nfs_client_share nfs defaults 0 0" | sudo tee -a /etc/fstab
fi
# 手动挂载 NFS 共享
sudo mount -t nfs 192.168.29.188:/mnt/nfs_share /mnt/nfs_client_share
# 验证挂载是否成功
if mount | grep -q "/mnt/nfs_client_share"; then
echo "NFS 共享挂载成功"
else
echo "NFS 共享挂载失败"
exit 1
fi
# 创建 Docker 卷并挂载 NFS
# --driver local:使用本地驱动程序来管理卷。
# --opt type=nfs:指定该卷使用 NFS 类型。
# --opt o=addr=192.168.29.188,rw:配置 NFS 服务器的地址,并设置挂载选项(读写)。
# --opt device=:/mnt/nfs_share:指定 NFS 共享目录。
# my_nfs_volume:卷的名称。
# 检查是否已经存在 Docker 卷
if docker volume ls | grep -q "my_nfs_volume"; then
echo "Docker 卷 'my_nfs_volume' 已存在,跳过创建。"
else
# 创建 Docker 卷
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.29.188,rw \
--opt device=:/mnt/nfs_share \
my_nfs_volume
# 验证卷是否创建成功
if ! docker volume ls | grep -q "my_nfs_volume"; then
echo "Docker 卷创建失败,请检查配置和日志。"
exit 1
fi
fi
# 检查是否已经存在 Docker 容器
if docker ps -a | grep -q "my_nginx"; then
echo "Docker 容器 'my_nginx' 已存在,跳过创建。"
else
# 启动 Docker 容器
docker run -d --name my_nginx \
-v my_nfs_volume:/usr/share/nginx/html \
nginx
# 验证容器是否启动成功
if ! docker ps | grep -q "my_nginx"; then
echo "Docker 容器启动失败,请检查配置和日志。"
exit 1
fi
fi
echo "Docker 容器已启动并挂载了 NFS 卷"
验证并查看docker容器:
[root@localhost shell]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc20937da7cc nginx "/docker-entrypoint.…" 21 seconds ago Up 20 seconds 80/tcp my_nginx
[root@localhost shell]# docker exec -it my_nginx /bin/bash
root@cc20937da7cc:/# cd /usr/share/nginx/html/
root@cc20937da7cc:/usr/share/nginx/html# ls
50x.html index.html
root@cc20937da7cc:/usr/share/nginx/html# touch aa.html
root@cc20937da7cc:/usr/share/nginx/html# ls
50x.html aa.html index.html
查看nfs服务端共享目录:
[root@localhost shell]# cd /mnt/nfs_share/
[root@localhost nfs_share]# ls
50x.html aa.html index.html
done