Docker Volume(存储卷)


Docker Volume(存储卷)

1.什么是存储卷?

存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着,当我们在容器中的这个目录下写入数据时,容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。

在宿主机上的这个与容器形成绑定关系的目录被称作存储卷。卷的本质是文件或者目录,它可以绕过默认的联合文件系统,直接以文件或目录的形式存在于宿主机上。

比如说宿主机的/data/web 目录与容器中的/tmp/web 目录绑定关系,然后容器中的进程向这个目录中写数据时,是直接写在宿主机的目录上的,绕过容器文件系统与宿主机的文件系统建立关联关系,使得可以在宿主机和容器内共享数据库内容,让容器直接访问宿主机中的内容,也可以宿主机向容器写入内容, 容器和宿主机的数据读写是同步的

2.为什么需要存储卷?

  1. 数据丢失问题

    容器安装业务类型,可以分为两大类:

    • 无状态的(数据不需要被持久化)

    • 有状态的(数据需要被持久化)

      显然容器更擅长无状态的应用,因为无状态的数据不能持久化存储,那么容器的根目录的生命周期就和容器的生命周期是一致的。容器文件系统的本质是在镜像层上面创建的读写层,运行中的容器对任何文件的修改都存在于该读写层,只要容器被销毁那么数据也就随之被销毁了。

      虽然容器希望所有的业务都尽量保持无状态,这样容器就可以开箱即用,并且可以任意调度,但实际业务总是有各种需要数据持久化的场景,比如 MySQL 等有状态的业务。因此为了解决有状态业务的需求, Docker 提出了卷(Volume)的概念 。

  2. 性能问题

    UnionFS 对于修改删除等,一般效率非常低,如果对一于 I/O 要求比较高的应用,如redis 在实现持化存储时,是在底层存储时的性能要求比较高。

  3. 宿主机和容器互访不方便
    宿主机访问容器,或者容器访问要通过 docker cp 来完成,应用很难操作

  4. 容器和容器共享不方便

3. 存储卷的分类

目前 Docker 提供了三种方式将数据从宿主机挂载到容器中

  • volume docker 管理卷,默认映射到宿主机的/var/lib/docker/volumes 目录
    下, 只需要在容器内指定容器的挂载点是什么,而被绑定宿主机下的那个目录,是由
    容器引擎 daemon 自行创建一个空的目录,或者使用一个已经存在的目录,与存储卷
    建立存储关系,这种方式极大解脱用户在使用卷时的耦合关系,缺陷是用户无法指定
    那些使用目录,临时存储比较适合。
  • bind mount 绑定数据卷,映射到宿主机指定路径下,在宿主机上的路径要人工的
    指定一个特定的路径, 在容器中也需要指定一个特定的路径, 两个已知的路径建立关
    联关系
  • tmpfs mount 临时数据卷,映射到于宿主机内存中,一旦容器停止运行, tmpfs
    mounts 会被移除,数据就会丢失,用于高性能的临时数据存储。

1) 管理卷Volume

存储卷可以通过命令方式创建,也可以在创建容器的时候通过 -v and --mount 指定

方式一:Volume命令操作
命令别名功能
docker volume create创建存储卷
docker volume inspect显示存储卷详细信息
docker volume lsdocker volume list列出存储卷
docker volume prune清理所有无用数据卷
docker volume rm删除卷,使用中的无法删除

docker volume create

功能:创建存储卷

docker volume create [OPTIONS] [VOLUME]

关键参数
○ -d, --driver: 指定驱动,默认是 local
○ --label: 指定元数据

docker volume inspect

功能:查看卷详细信息

docker volume inspect [OPTIONS] VOLUME [VOLUME...]

关键参数
○ -f: 指定相应个格式,如 json

docker volume ls

功能:列出卷

docker volume ls [OPTIONS]

关键参数

  • –format: 指定相应个格式,如 json,table
  • –filter,-f: 过滤
  • -q: 仅显示名称

docker volume rm

功能:删除卷,需要容器不使用

docker volume rm [OPTIONS] VOLUME [VOLUME...]

关键参数
○ -f,–force:强制删除

docker volume prune

功能:删除不使用的本地卷

docker volume prune [OPTIONS]

关键参数
○ --filter:过滤
○ -f, --force :不提示是否删除

方式二: -v 或者–mount 指定

-v 和-mount 都可以完成管理卷的创建

-v 参数
• 功能:完成目录映射

docker run -v name:directory[:options] ......

参数
○ 第一个参数:卷名称
○ 第二个参数:卷映射到容器的目录
○ 第三个参数:选项,如 ro 表示 readonly

[root@aliyun ~]# docker run -d --name test -v myvol:/app nginx:latest
[root@aliyun ~]# docker inspect myvol
[
    {
        "CreatedAt": "2023-09-14T14:55:36+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/data/var/lib/docker/volumes/myvol/_data",
        "Name": "myvol",
        "Options": null,
        "Scope": "local"
    }
]

–mount 参数

功能:完成目录映射

--mount '<key>=<value>,<key>=<value>'

关键参数
○ type : 类型表示 bind, volume, or tmpfs
○ source , src :对于命名卷,这是卷的名称。对于匿名卷,省略此字段。
○ destination, dst,target:文件或目录挂载在容器中的路径
○ ro,readonly: 只读方式挂载

[root@aliyun ~]# docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
通过命令查看信息
[root@aliyun ~]# docker inspect devtest

Docker -v 创建管理卷

1.-v 创建管理卷,并且启动容器

[root@aliyun ~]# docker container run --name nginx -d -p 80:80 -v test_volmue2:/usr/share/nginx/html:ro nginx:latest

指定 ro 的话宿主机可以修改,但是容器里面无法修改

方式三: Dockerfile 匿名卷

通过 Dockerfile 的 VOLUME 可以创建 docker 管理卷。我们也可以通过 dockerfile 的 VOLUME 指令在镜像中创建 Data Volume,这样只要通过该镜像创建的容器都会存在挂载点,但值得注意的是通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,而是由 docker 随机生成的 。

小结

宿主机和容器之间数据是同步的,无论是mount 创建的卷数据也会完成同步

Docker 卷生命周期
  1. -v创建管理卷

    [root@aliyun ~]# docker container run --name nginx -d -p 80:80 -v test_volume2:/usr/share/nginx/html nginx:latest
    
  2. j进入卷目录

    [root@aliyun ~]# cd /data/var/lib/docker/volumes/test_volume2/_data/
    [root@aliyun _data]# ls
    50x.html  index.html
    

    注意此时可以看到容器里面的内容自动的放到了宿主机里面,也就
    是说宿主机上没有容器会拷贝过去

  3. 清理释放空间

    进入卷目录查看可以看到文件并没有被删除

    [root@aliyun _data]# docker stop nginx
    nginx
    [root@aliyun _data]# docker rm nginx
    nginx
    [root@aliyun _data]# ls
    50x.html  index.html
    
    
Docker 卷共享
  1. -v 创建管理卷,并且启动 2 容器,指定同一个卷

    [root@aliyun _data]# docker container run --name nginx1 -d -p 80:80 -v test_volume:/usr/share/nginx/html nginx:latest
    [root@aliyun _data]# docker container run --name nginx_my -d -p 6060:80 -v test_volume:/usr/share/nginx/html nginx:latest
    
    
  2. 进入卷目录修改html

    [root@aliyun _data]# ls
    50x.html  index.html
    

    访问80和6060端口发现首页都被修改了

2)绑定卷 bind mount

-v 和-mount 都可以完成绑定卷的创建

-v 参数创建卷

功能:完成卷映射

docker run -v name:directory[:options] .........

参数
○ 第一个参数: 宿主机目录,这个和管理卷是不一样的
○ 第二个参数:卷映射到容器的目录
○ 第三个参数:选项,如 ro 表示 readonly

–mount 参数创建绑定卷

功能:完成目录映射

--mount '<key>=<value>,<key>=<value>'

关键参数
○ type : 类型表示 bind, volume, or tmpfs
○ source , src : 宿主机目录,这个和管理卷是不一样的。
○ destination, dst,target:文件或目录挂载在容器中的路径
○ ro,readonly: 只读方式挂载

容器该目录本身存在的文件消失不见, 这是 bind mount 模式和 volume 模式最大的不同点

  1. 使用-mount 方式创建容器: 创建 nginx 容器,并将宿主机/webapp1 目录挂载至
    容器/usr/share/nginx/html 目录,注意如果 webapp1 目录不存在会启动报错

    [root@aliyun ~]# docker run -d -p 80:80 --name bind1 --mount type=bind,source=/data/webapp1,target=/usr/share/nginx/html/ nginx:latest
    

    如果宿主机和容器的目录内容一致,会以宿主机目录为准

-v 创建绑定卷

使用-v 方式创建容器: 创建 nginx 容器,并将宿主机/webapp2 目录挂载至容器
/usr/share/nginx/html 目录,注意如果 webapp2 目录不存在,启动不会报错,这是-
v 和–mount 方式的区别
,同样内容相同是以宿主机为准。

[root@aliyun ~]# docker run -d -p 8080:80 --name bind2 -v /data/webapp4:/usr/share/nginx/html nginx:latest

绑定卷共享和管理卷类似

3)临时卷 tmpfs

临时卷数据位于内存中,在容器和宿主机之外。
tmpfs 局限性
• 不同于卷和绑定挂载,不能在容器之间共享 tmpfs 挂载。
• 这个功能只有在 Linux 上运行 Docker 时才可用

方式一:指定–tmpfs 创建

功能:完成临时卷映射

[root@aliyun ~]# docker run -d -it --name tmpfs_test --tmpfs /app nginx
方式二: --mount 指定参数创建

功能:完成目录映射

--mount '<key>=<value>,<key>=<value>'

关键参数
○ type : 类型表示 bind, volume, or tmpfs
○ destination, dst,target:挂载在容器中的路径
○ tmpfs-size: tmpfs 挂载的大小(以字节为单位)。默认无限制。
○ tmpfs-mode: tmpfs 的八进制文件模式。例如, 700 或 0770。默认为 1777
或全局可写

[root@aliyun ~]# docker container run --name tmpfs_test -d -p 80:80 --tmpfs /usr/share/nginx/html/ nginx:latest
[root@aliyun ~]# docker exec -it tmpfs_test bash
root@acba8a252814:/# ls /usr/share/nginx/html/
root@acba8a252814:/# 

进入容器可以看到 nginx 里面的文件被覆盖了,也就是说 tmpfs 也会覆盖容器里
面的文件

注意重启后mpfs 内容完全消失了,也就是说内容是存在内存里面的。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱敲代码的三毛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值