如果正在运行中的容器 成了新的数据 或者 修改了现有的一个已经存在的文件内容,那么新产生的数据将会被复制到读写层进行持久化保存,这个读写层也就是容器的工作目录,此即“写时复制(COW) copy on write”机制。
如下图是将对根的数据写入到了容器的可写层,但是把/data中的数据写入到了一个另外的volume中用于数据持久化。
目录的含义
- Lower Dir:image镜像层(镜像本身,只读)
- Upper Dir:容器的上层(读写)
- Merged Dir:容器的文件系统,使用Union FS(联合文件系统)将lowerdir和upper Dir:合并给容器使用。
- Work Dir:容器在 宿主机的工作目录
Docker的镜像是分层设计的,镜像层是只读的,通过镜像启动的容器添加了一层可读写的文件系统,用户写入的数据都保存在这一层当中。
如果要将写入到容器的数据永久保存,则需要将容器中的数据保存到宿主机的指定目录,目前Docker的数据类型分为两种
- 数据卷(data volume)
- 数据卷容器(Data volume container)
数据卷(data volume)
数据卷实际上就是宿主机上的目录或者是文件,可以被直接mount到容器当中作为容器的本地文件系统使 用,实际生产环境中,需要针对不同类型的服务、不同类型的数据存储要求做相应的规划,最终保证服务的可扩展性、稳定性以及数据的 安全性。基于数据卷通过将宿主机的文件或目录挂载到容器的指定目录,当容器中的挂载目录产生的新数据即可间接的保存到宿主机以实 现持久化的目的
数据卷容器(Data volume container)
数据卷容器是将宿主机的目录挂载至一个专用的数据卷容器,然后让其他容器通过数据卷容器 继承挂载的目录或文件,以实现将新产生的数据持久化到宿主机的目的。
创建数据卷
# docker volume create nginx-data
# docker volume ls
DRIVER VOLUME NAME
local nginx-data
# docker run -it -d -p 80:80 -v nginx-data:/data nginx:1.20.2
4445e4640c74e1c503a7f8c704270abd58c5bc70aacf600e39945f7fd74ac810
# docker exec -it 4445e4640c74 bash
root@4445e4640c74:/# echo "nginx web" > /data/index.html
root@4445e4640c74:/# exit
exit
root@docker-server1:~# ls /var/lib/docker/volumes/nginx-data/_data/index.html
/var/lib/docker/volumes/nginx-data/_data/index.html
数据目录挂载
以数据卷的方式,将自定义的宿主机目录或文件提供给容器使用,比如容器可以直接挂载宿主机本地的数据目录(如mysql容器的数据持久化)、 配置文件(如nginx的配置文件)、静态文件(如web服务的图片或js文件)等,只需要在创建容器的时候指定挂载即可
# mkdir /data/testapp –p
# echo "testapp web page" > /data/testapp/index.html
# cat /data/testapp/index.html
testapp web page
启动两个测试容器,web1容器和web2容器,分别测试能否访问到宿主机的数据,注意使用-v参数,将宿主机目录映射到容器内部,web2的ro 表示在容器内对该目录只读,默认的权限是可读写的
# docker run -d --name web1 -v /data/testapp:/usr/share/nginx/html/testapp -p 80:80 nginx:1.20.2
# docker run -d --name web2 -v /data/testapp:/usr/share/nginx/html/testapp:ro -p 81:80 nginx:1.20.2
数据目录及配置多卷挂载
# mkdir /data/nginx/conf -p
# docker cp web1:/etc/nginx/nginx.conf /data/nginx/conf/
# docker run -d --name web3 -v /data/testapp:/usr/share/nginx/html/testapp -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro -p 83:80 nginx:1.20.2
删除容器
创建容器的时候指定参数会删除/var/lib/docker/containers/的容器数据目录,但是不会删除数据卷的内容,如下
# docker rm -f web3
# ls /data/testapp/index.html
/data/testapp/index.html #挂载的数据卷不会被删除
数据卷的特点及使用:
- 据卷是宿主机的目录或者文件,并且可以在多个容器之间共同使用。
- 宿主机对数据卷更改数据后会在所有容器里面会立即更新。
- 据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。
- 容器里面的写入数据不会影响到镜像本身
数据卷使用场景
- 容器数据持久化(mysql数据、nginx日志等类型)
- 静态web页面挂载
- 应用配置文件挂载
- 多容器间的目录或文件共享
数据卷容器
数据卷容器功能是可以让数据在多个docker容器之间共享,即先要创建一个后台运行的A容器作为Server,之后创建的B容器、C容 器等都可以同时访问A容器的内容,因此数据卷容器用于为其它容器提供卷的挂载继承服务,数据卷为其它容器提供数据读写服务, A容器称为server端、其它容器成为client端
step1 卷容器Server
# docker run -d --name volume-server -v /data/testapp:/usr/share/nginx/html/testapp -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro registry.cn-hangzhou.aliyuncs.com/zhangshijie/pause:3.8
step2 创建client容器 数据卷指向 容器server
## client1
# docker run -d --name web1 --volumes-from volume-server -p80:80 nginx:1.20.2
## client2:
# docker run -d --name web2 --volumes-from volume-server -p81:80 nginx:1.20.2
特点:
- 适用于同类服务的数据卷共享
- client会继承卷server挂载和挂载权限
- 停止卷server,也不影响已经运行的容器、甚至也不影响新建容器
- 删除卷server,不影响已经运行的容器,但是不能新建容器