在容器中管理数据主要有两种方式:
- 数据卷(volumes)
- 挂载主机目录(bind mounts)
1、数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据库的更新,不会影响镜像
- 数据卷默认会一直存在,即使容器被删除
注意:数据卷的使用,类似于linux下对目录或文件进行mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷
1.1、创建一个数据卷
[root@hackerlin ~]# docker volume create my-vol my-vol #创建成功之后,可以看到宿主机的/var/lib/docker/volumes/下多了一个my-vol的文件夹 [root@hackerlin ~]# ll /var/lib/docker/volumes/ total 24 -rw-------. 1 root root 32768 Apr 14 01:59 metadata.db drwxr-xr-x. 3 root root 19 Apr 14 01:59 my-vol
查看所有的数据卷
[root@hackerlin ~]# docker volume ls DRIVER VOLUME NAME local my-vol
在宿主机里使用以下命令可以查看指定数据卷的信息
[root@hackerlin ~]# docker volume inspect my-vol [ { "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/my-vol/_data", "Name": "my-vol", "Options": {}, "Scope": "local" } ]
1.2、启动一个挂载数据卷的容器
在用docker run命令的时候,使用--mount标记来讲数据卷挂载到容器里,在一次docker run中可以挂载多个数据卷
下面创建一个名为web的容器,并加装一个数据卷到容器的/webapp目录
挂载方法有如下两种
docker run --name 容器名 -it --mount source=卷名,target=容器内绝对路径(挂载点) 镜像名 bash
或者docker run --name 容器名 -it -v 卷名:容器内绝对路径(挂载点) 镜像名 bash
[root@hackerlin my-vol]# docker run -d --name web -v my-vol:/webapp docker.io/nginx:1.14-alpine WARNING: IPv4 forwarding is disabled. Networking will not work. 5df58e337a192f753d7e4ef5d96b78713e91fb33fb4a2a44498b5b4e1fd0c019
查看数据卷的具体的使用信息
[root@hackerlin my-vol]# docker inspect web "Mounts": [ { "Type": "volume", "Name": "my-vol", "Source": "/var/lib/docker/volumes/my-vol/_data", "Destination": "/webapp", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ],
1.3、删除数据卷
[root@hackerlin my-vol]# docker volume rm my-vol my-vol
数据卷是被设计用来持久化数据的,他的生命周期独立于容器,docker不会再容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要再删除容器的同时移除数据卷。可以在删除容器的时候使用docker rm -v 这个命令
无主的数据卷可能会占据很多空间,要清理使用以下命令
[root@hackerlin my-vol]# docker volume prune shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory WARNING! This will remove all volumes not used by at least one container. Are you sure you want to continue? [y/N] y Total reclaimed space: 0 B
2、挂载书记目录
使用--mount标记可以指定挂载一个本地主机的命令道容器中去
挂载的方法有如下两种:
docker run -it -v 宿主机目录:容器目录 镜像名 命令
或者docker run -it --mount type=bind,source=宿主目录,target=容器目录[,readonly] 镜像 命令
[root@hackerlin my-vol]# docker run -d --name web -v /data:/webapp docker.io/nginx:1.14-alpine shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory WARNING: IPv4 forwarding is disabled. Networking will not work. e249275ffd877b7d6ceeaf67d8b01e0843ac03409dfff97eff07422f1afa286a
上面的命令加装主机的/data目录到容器的/webapp目录。这个功能在进行测试的时候十分方便,比如用户可以设置一些程序到本地目录中。来查看容器是否正常工作。本地目录的路径必须是绝对路径,以前使用-v参数时如果本地目录不存在docker会自动为你创建一个文件夹,现在使用--mount 参数时如果本地目录不存在,docker会报错
docker挂载主机目录的默认权限是读写,用户也可以通过增加readonly指定为只读
2.1 查看数据卷的具体信息
在主机里使用以下命令可以查看 web 容器的信息
docker inspect web
挂载主机目录 的配置信息在 "Mounts" Key 下面
"Mounts": [ { "Type": "bind", "Source": "/src/webapp", "Destination": "/opt/webapp", "Mode": "", "RW": true, "Propagation": "rprivate" } ],
2.2 挂载一个本地主机文件作为数据卷
--mount 标记也可以从主机挂载单个文件到容器中
docker run --rm -it --mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history ubuntu:18.04 bash
root@2affd44b4667:/# history 1 ls 2 diskutil list
这样就可以记录在容器输入过的命令了