前面(哪一个前面我也忘了)有说过,若是咱们须要对数据进行持久化保存,不该使其存储在容器中,由于容器中的数据会随着容器的删除而丢失,而因经过将数据存储于宿主机文件系统的形式来持久化。在Docker容器中管理数据主要有数据卷、宿主机目录挂载两种方式。linux
数据卷是一个特殊的文件目录(或文件),具有以下特性:web
能够在容器之间共享和重用docker
可使用docker volume create 数据卷名称
的命令来建立一个数据卷,ubuntu
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume create volume1
volume1
建立完后,这个数据卷具体对应宿主机哪一个文件目录在上面是无法得知的,能够经过 docker volume inspect 数据卷名称
来查看,安全
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume inspect volume1 [ { "CreatedAt": "2019-08-12T19:43:47+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/volume1/_data", "Name": "volume1", "Options": {}, "Scope": "local" } ]
能够看到数据卷volume1对应的文件目录是“/var/lib/docker/volumes/volume1/_data”。
docker inspect xxx
这个命令挺有用的,不管是查看镜像相关信息(docker image inspect 镜像名/镜像ID
),仍是查看容器相关信息(docker container inspect 容器名/容器ID
),均可以使用,其中的image,container,volume是能够省略的,只要xxx部分不冲突就行。
能够经过docker volume ls
命令来查看全部数据卷,ruby
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume ls DRIVER VOLUME NAME local volume1
1.3 使用数据卷bash
能够在启动容器时经过 -v 或 –mount 的方式将一个数据卷挂载到容器的某个目录微信
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu1 -v volume1:/vol1 ubuntu:18.04 b060e793d44de2ca871da257b47598334658952943a13d1c478df5c3ae91a01c
按照 -v 数据卷名:容器目录
的格式,也可使用 –mount 按照 --mount source=数据卷名,target=容器目录
的格式,如咱们再启动一个挂载相同数据卷的容器 ubuntu2,网络
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount source=volume1,target=/vol2 ubuntu:18.04 b30971f8a4bbadee10774fce0b4568b5b7b1c9cde36f4bf84ac911a4cdaf6c8d
能够在数据卷所在目录中建立一个文件来看看效果,先建立文件 hello.txtapp
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# cd /var/lib/docker/volumes/volume1/_data [root@iZwz9dbodbaqxj1gxhpnjxZ _data]# touch hello.txt [root@iZwz9dbodbaqxj1gxhpnjxZ _data]# ls hello.txt
而后经过docker exec
来查看容器ubuntu1目录/vol1,及容器ubuntu2目录/vol2的内容
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu1 ls /vol1 hello.txt [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu2 ls /vol2 hello.txt
能够看到经过挂载目录 /vol1, /vol2 均可以访问到数据卷volume1对应目录下的内容。这就像linux的软连接同样,将容器目录连接到了数据卷目录。而且上述示例也说明,同一个数据卷是能够在被多个容器共享的。
数据卷的共享也能够经过 volumes-from 容器名称/容器ID
参数来实现,如
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu3 --volumes-from ubuntu2 ubuntu:18.04 bb5c6d61a1e6eeb18ba8c889e471b2f3215f97efca79b311eeca5968b2700df8 [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu3 ls /vol2 hello.txt
经过--volumes-from ubuntu2
来直接使用ubuntu2挂载的容器配置。
数据卷不会随着容器的删除而自动删除。若是一个数据卷还被某个容器使用,则不能删除;若是一个数据卷只被一个容器使用,则可在删除容器时经过指定 -v
参数同时删除其挂载的数据卷;
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker rm -v ubuntu3 ubuntu3
能够经过 docker volume rm 数据卷名称
来删除某个数据卷;
能够经过 docker volume prune
清理掉全部未被任何容器使用的数据卷。
在容器启动时,使用 -v 宿主机目录:容器目录
或 --mount type=bind,source=宿主机目录,target=容器目录
的参数格式指定将宿主机目录挂载到容器目录上。宿主机目录必须是绝对路径。二者之间的区别是 -v
若是在宿主机目录不存在时会自动建立目录,而--mount
不会。如,
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu1 -v /root/v1:/vol1 ubuntu:18.04 25c91911709eebc9290b47b483666f7b7be840df947117f7cad323583905b9f1 [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount type=bind,source=/root/v2,target=/vol1 ubuntu:18.04 docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /root/v2. See 'docker run --help'. [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# mkdir /root/v2 [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount type=bind,source=/root/v2,target=/vol1 ubuntu:18.04 5a57285e9261d048dc71cf0476055a290f80538afff2cefd2a24f8b4468b5171
/root/v1,/root/v2都没有事先建立,用 -v
不会报错,会自动建立; --mount
则会报错,目录必须先存在。docker不只支持目录的挂载,也支持文件的挂载,如,
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run --rm -it -v $HOME/.bash_history:/root/.bash_history ubuntu:18.04 bash root@3ae4ed4e687d:/# history 1 ll webapps/ 2 ll confluence/images/
经过将宿主机当前用户的历史操做文件挂载到容器的root用户下的历史操做文件,可在容器中经过history
命令查看到宿主机的操做历史。可经过 docker inspect
来查看容器的挂载状况
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker inspect ubuntu1 --省略了其它信息-- "Mounts": [ { "Type": "bind", "Source": "/root/v1", "Destination": "/vol1", "Mode": "", "RW": true, "Propagation": "rprivate" } ], --省略了其它信息--
可在“Mounts”部分看到挂载信息。
有时候,为了数据安全,咱们不容许容器对挂载目录的内容进行修改,即对容器来讲,挂载目录是只读的,这能够经过在挂载参数后面加限制实现。
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu3 -v /root/v1:/vol1:ro ubuntu:18.04 25eca348ed307afcbef92bc03f0a1304b31b52e6db1fa07772b5dbd1040ff7b6 [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu3 bash root@25eca348ed30:/# touch /vol1/hello.txt touch: cannot touch '/vol1/hello.txt': Read-only file system
是在后面加(read-only),则是形如的格式,可自行试验。-vro--mount--mount type=bind,source=宿主机目录,target=容器目录,read only
加了read only的挂载咱们再经过docker inspect
命令查看,可看到二者之间的差别 —— Mode与RW的值。
"Mounts": [ { "Type": "bind", "Source": "/root/v1", "Destination": "/vol1", "Mode": "ro", "RW": false, "Propagation": "rprivate" } ],
4. 总结
若是要对数据进行持久化管理或在容器之间共享数据,则须要将数据经过数据卷或宿主机目录(或文件)挂载的方式来将数据存储于宿主机上,使得数据的生命周期独立于容器的生命周期。这相似于咱们不要把重要文件放在系统盘,而应放在其它数据盘同样,由于系统盘会因为重装系统或系统故障致使文件丢失。本文对Docker的数据管理进行了整理,后续对Docker的网络配置管理部分进行整理,欢迎持续关注。
相关阅读
Docker笔记(一):什么是Docker
Docker笔记(二):Docker管理的对象
Docker笔记(三):Docker安装与配置
Docker笔记(四):Docker镜像管理
Docker笔记(五):整一个本身的镜像
Docker笔记(六):容器管理
Docker笔记(七):经常使用服务安装——Nginx、MySql、Redis
本文发表于微信公众号:“空山新雨的技术空间”
做者:空山新雨
欢迎关注,转发,推荐,你的支持是我持续创做的动力