一、什么是数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它将主机操作系统目录直接映射进容器。在容器中修改的内容可以在宿主机对应的目录下看到,比如:重要日志 、配置文件等。
因为镜像层是只读的,修改也只是在最上层添加一层读写层,读写层的文件会隐藏掉只读的那些同名文件,这些只读的文件在容器被删除时也会被删除,所以需要持久化。
二、Docker数据卷操作
2.1 查看当前数据卷
docker volume ls # 删除已经退出的docker进程 docker rm `docker ps -f status=exited -q` # 注意不是单引号是 `飘号 docker rm `docker ps -f status=created -q`
2.2 创建(具名)数据卷
具名就是有名子的数据卷,比如这里我们创建的就是名为vol_test的具名数据卷。有具名就有匿名数据卷,匿名数据的名字是一个随机字符串,两个的删除逻辑可能会不一样,这个我们后面会再提到。
docker volume create vol_test
2.3 查看当前数据卷列表
docker volume ls
2.4 查看指定数据卷信息
Mountpoint 字段就是该数据卷挂载的宿主机的目录,当容器运行是,数据就会保存到该目录下。
docker volume inspect vol_test
2.5 挂载数据卷
有了数据卷后,我们来看看是如何挂载(也可以叫:映射)的。我们需要先运行一个容器,这里我们以ubuntu为例。
# 将数据卷vol_test 挂载到容器的/data目录下 docker run -dit -v vol_test:/data ubuntu docker ps # 查看容器名
查看是否挂载成功。
docker inspect unruffled_noyce # 注意:这里写你自己的容器名
2.6 挂载验证
我们在进入到容器,在容器的data目录下写点东西,
docker exec -it unruffled_noyce bash echo 2023-02-20 volume test >> /data/volume_info.txt
然后在宿主机的对应的目录下查看,可以看到容器中修改的信息,在宿主机是可以看到的。
我们再停止并删除容器,刚才写的信息还是在的,这就是docker 的持久化的一种场景。
docker stop unruffled_noyce docker rm unruffled_noyce
2.7 目录挂载的不同方式及权限设置(只读、可读写)
docker run -dit -v vol_test:/data_ro_test:ro -v /no_name -v /tmp/data:/data_tmp --name myubuntu ubuntu
可以看到容器下多了我们挂载或绑定的三个目录。
说明:
- -v vol_test:/data_ro_test:ro 将具名数据卷vol_test 挂载到容器的data_ro_test目录,ro的作用是以只读的方式挂载,只有具名数据卷可以指定权限;
- -v /no_name 是将宿主机的匿名数据卷,挂载到容器的no_name目录下。注意:匿名数据卷不能分配权限没比如:-v /no_name:ro 会报错
- 将宿主机/tmp/data目录,绑定(注意不是挂载)到容器的data_tmp目录,的区别。
使用docker inspect 命令查看详细的挂载信息。
docker inspect myubuntu # 找到Mounts 查看具体的目录挂载信息,如下图
验证挂载及其权限
小结:
有时候我们需要从宿主机传输文件到容器,有时候又需要从容器传文件到宿主机。
ls -al /tmp/data sudo chown ns:ns /tmp/data # ns
2.8 Dockerfile 挂载数据卷
Dockerfile挂载的数据卷通常情况下是匿名数据卷,为什么不是具名数据卷或者绑定某个目录呢?因为如果是具名或者绑定,就会导致Dockerfile的移植性变差,要求宿主机必须存在那个数据卷或者目录。
宿主机
创建Dockerfile文件
vi Dockerfile FROM ubuntu RUN mkdir /data_vol RUN echo hello,world >> /data_vol/hello.txt VOLUME /data_vol
构建及运行镜像
docker build -t myubuntu:1.0.1 . docker run -dit myubuntu:1.0.1 docker ps # 获取容器ID docker inspect 容器ID # 查看对应目录下的文件及内容即可
容器内验证
docker ps # 获取容器ID docker exec -it 容器ID bash cat data_vol/hello.txt
2.9 共享数据卷
使用 --volumse-from 指定从哪个容器(可以指定多个容器)分享数据卷。
docker ps docker run -dit --volumes-from myubuntu ubuntu
此时启动的容器我们没有通过 - v 去指定任何数据卷,通过inspect 命令可以看到跟 --volumes-from 指定的 myubuntu 容器的数据卷一致。
共享数据卷验证
就算 --volumes-from 指定的容器 myubuntu 停掉,也不会对已经共享数据卷有什么影响。
2.10 数据卷删除
绑定的方式:通过手动删除绑定的目录 rm /tmp/data/*
具名和匿名数据卷
docker volume ls # 查看当前所有数据卷 docker volume create vol_nouse # 创建匿名数据卷 vol_nouse docker volume prune # 删除掉没有使用的数据卷 vol_nouse
区别:
如果一个容器同时挂载了具名和匿名数据卷,并使用了 --rm 启动容器,容器在停止的时候,会自动删除匿名数据卷,不会删除具名数据卷。
使用 rm -v 在删除容器的同时也只会删除匿名数据卷。具名数据卷只能通过docker volume rm + vol_simple
docker rm -v -f CONTAINER_NAME