首页 > 技术文章 > volume--持久化

wang-yy 2020-05-12 10:38 原文

数据卷的特性

Docker 镜像由多个只读层叠加而成,启动容器时,Docker 会加载只读镜像层并在镜像栈顶部添加一个读写层
如果运行中的容器修改了现有的一个已经存在的文件,那么该文件将会从读写层下面的的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,次即“写时复制”机制
只读层--读写层--用户展现层

image-20210311194332914

数据卷 是一个可供一个或多个容器使用的特殊目录,实现让容器中的一个目录和宿主机中的一个文件或者目录进行绑定。数据卷 是被设计用来持久化数据的。
关闭并重启容器,其数据不受影响;但删除 Docker 容器,则其改变将会全部丢失

Bind mount volume

image-20210311183717606
# (绑定卷)基于本地目录提供volume
1)创建本地目录
	$ mkdir /webroom
	$ echo “123” > /webroom/index.html
2)绑定本地目录,运行容器
	$ docker run -v # 绑定一个数据卷 Bind mount a volume
	$ docker run -v /webroom:/usr/share/nginx/html -d -P nginx
	$ docker ps -q
   		 553d7e454376
3)查看bind 和ip
	$ docker inspect 553d7e454376|grep “Mounts” -A7
“Mounts”: [
{
“Type”: “bind”,
“Source”: “/webroom”,
“Destination”: “/usr/share/nginx/html”,
“Mode”: “”,
“RW”: true,
“Propagation”: “rprivate”

docker inspect 553d7e454376|grep IPAddress
“SecondaryIPAddresses”: null,
“IPAddress”: “172.17.0.3”,
“IPAddress”: “172.17.0.3”,
4)验证
	$ curl 172.17.0.3
		123

指定宿主机与容器内部目录共享

1、命令

docker run -it -v /宿主机绝对路劲目录:/容器内目录   镜像名
 -v:会创建不存在的目录
docker run -it -v /myname:/dockername centos

2、查看是否挂载成功

docker inspect 76881873958c 

#docker inspect 容器ID号

3、在容器和宿主机内互写数据,查看是否共享v

4、容器停止退出后,主机修改数据是否同步

5、命令(带权限)

docker run -it -v /宿主机绝对路劲目录:/容器内目录:ro 镜像名

#只读,不可写
# 宿主机创建、修改的文件会同步到容器内,容器内部不能创建、修改文件

Docker-managed volume(docker管理卷)基于目录持久化管理

image-20210311194412951

# 制作nginx:new镜像
$ vim Dockerfile
	FROM wyylinux/nginx:v1
	VOLUME /usr/local/nginx/html
	WORKDIR /usr/local/nginx
$ docker build -t nginx:new .
# 启动
$ docker run --name nginx -d nginx:new
$ docker exec -it nginx /bin/bash
# 创建文件
$ pwd
$ cd html
$ touch wyy
$ exit
$ docker rm -f $(docker ps -a -q)
# 查看本机目录
$ cd /var/lib/docker/volumes/
$ ls
$ find .-name wyy
$ cd 7edce0620df41b6e7bfaa66eeabe7163579d48b566f5c81dfe0d4452f4a6373f
$ ls
$ cd _data/
$ ls
	wyy
# 结果可以看出,本机目录与容器内目录相对应,持久化目录。
# docker rm -f nginx:new # 会删除持久化

docker volume 命令

$ docker volume --help # 查看帮助信息 
$ docker volume create v1 # 创建一个volume
$ docker volume ls # 查看volume列表
$ docker volume inspect  v1 # 查看volume的详细信息
$ docker volume rm $(docker volume ls -qf dangling=true)# 批量删除未被使用的volumes

容器中的数据卷

数据卷可以带来以下好处:
	数据卷可在容器之间共享或重用数据。
	数据卷的更改可以直接生效。
	数据卷的生命周期一直持续到没有容器使用它为止。
	对数据卷操作不会影响到镜像本身。
	数据卷可以完成容器到宿主机、宿主机到容器以及容器到容器之间的数据共享。

Docker-managed Volume(管理卷)

# docker run -it --name roc -v MOUNTDIR roc/lamp:v1.0
# docker inspect -f {{.Mounts}}  roc # 查看持久化目录

Bind-mount Volume(绑定卷)

# docker run -it --name roc -v HOSTDIR:VOLUMEDIR  roc/lamp:v1.0

Union Volume(联合卷)

# docker run -it --name roc --volumes-from ContainerName roc/lamp:v1.0
	# --volumes-from 多容器之间数据一致
# 利用前面实验的镜像,启动实例容器
$ docker run --name test1 -d nginx:new
$ docker run --name test2 --volumes-from -d test1
$ docker run --name test3 --volumes-from -d test1
$ docker ps -a
# 进入test1容器内部,创建新文件
$ docker exec -it test1 /bin/bash
$ touch {1..10}
$ ls
$ exit
#  进入test2容器内部,查看,并创建新文件
$ docker exec -it test2 /bin/bash
$ ls 
$ touch {11..20}
$ exit
#  进入test1容器内部,查看
$ ls

存储驱动

存储驱动种类

Docker 存储驱动 ( storage driver ) 是 Docker 的核心组件,它是 Docker 实现分成镜像的基础

    1、device mapper ( DM ):性能和稳定性存在问题,不推荐生产环境使用
    2、btrfs:社区实现了 btrfs driver,稳定性和性能存在问题
    3、overlayfs:内核 3.18 overlayfs 进入主线,性能和稳定性优异,第一选择

Overlayfs(联合文件系统)

image-20210311203536002

# 三个层级
	用户展现层 Container mount
	可写层:Container layer # 写入记录
	镜像层:lmage layer # 可挂载多个目录
$ mount -t overlay overlay -olowerdir=./low,upperdir=./upper,workdir=./work ./merged

# 实验:overlayfs文件系统
# 创建目录
$ cd /var
$ makdir overlay
$ cd overlay
$ mkdir low upper work merged
# overlay文件系统挂载
$ mount -t overlay overlay -olowerdir=./low,upperdir=./upper,workdir=./work ./merged
# 查看挂载层级
$ mount
# 在镜像层添加数据
$ echo "1" >> low/1.txt
# 在可写层添加数据
$ echo "2" >> upper/2.txt
# 安装树文件系统
$ yum -y install tree
$ tree
# 进入用户展现层目录下,修改文件
$ cd merged
$ vim 1.txt
	# 添加2
$ tree
# 证明写实复制,将镜像层文件拷贝至可写层实现的。
$ cat low/1.txt ==>1
$ cat upper/1.txt ==>1,2
# 证明所有修改记录可写层
$ rm -rf 1.txt
$ cat low/1.txt ==>1 # 镜像层只读
$ cat merged/1.txt ==> 无 # 被删除
$ cd ../upper
$ ll
	# 文件出现 C 标记,代表文件被删除
$ rm -rf 1.txt # 将带有C标记的文件删除,用户展现层,就又可以访问到
$ cd ../merged
$ cat 1.txt ==> 1
# docker就是基于此原理实现持久化

推荐阅读