Docker Volume(存储卷)

2023-09-14 16:11:56


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 内容完全消失了,也就是说内容是存在内存里面的。


更多推荐

在c#中使用CancellationToken取消任务

目录🚀介绍:🐤简单举例🚀IsCancellationRequested🚀ThrowIfCancellationRequested🐤在控制器中使用🚀通过异步方法的参数使用cancellationToken🚀api结合ThrowIfCancellationRequested()🚀介绍:Cancellatio

POJ 3185 The Water Bowls 反转+点灯游戏

一、题目大意有20盏灯(其实20盏灯数据量太少了,1e7我觉得差不多都可以过)放在同一行,点亮某一盏灯,它左右两边的灯也会亮,然后边缘特殊考虑,电亮两端的灯,只会照亮它相邻的那一个。二、解题思路这其实就是一个反转问题,我们从第二盏灯开始循环到第20盏灯,对于每一次循环的i,我们计算出i-1的灯是否亮着,如果i-1亮着,

Golang 中的匿名变量详解

在Golang中,可以使用匿名变量来忽略不需要的返回值或占位符。匿名变量是一种特殊类型的变量,可以简化代码并提高可读性。本文将详细介绍匿名变量的定义、特性和使用方法。什么是匿名变量?在Golang中,匿名变量是一种没有显式声明名称的变量,通常用于在需要临时存储值但不需要在后续代码中使用该值的情况。匿名变量的声明方式是使

吃瓜教程第一二章学习记录

当大多数人听到"机器学习"时,他们会联想到机器人:一个可靠的管家或一个致命的终结者,这取决于你问谁。但是,机器学习并不只是未来主义的幻想,它已经存在了。事实上,在一些特殊的应用中,如光学字符识别(OCR)等,已经有了几十年的历史。但是第一个真正主流的ML应用是在20世纪90年代:垃圾邮件过滤器,它改善了数亿人的生活,并

【GPU编程】Visual Studio创建基于GPU编程的项目

vs创建基于GPU编程的项目🍊前言🐸方法一-CUDARuntime生成😝debug设置🍅方法二-空项目配置🍉🍉🍉代码验证🍊前言cuda以及cudnn的安装以及系统环境变量的配置默认已经做完。如果没有安装好配置好的,可以参考其他的博客。本博客只为记录在完成以上配置后,如何在vs端创建GPU编程的项目。🐸

多线程中的Semaphore信号量

在Java多线程编程中,Semaphore是一种用于控制资源访问的机制。Semaphore允许您限制同时访问某个资源的线程数量。这在需要限制并发访问的情况下非常有用,例如数据库连接池或有限数量的线程池。创建Semaphore要使用Semaphore,首先需要创建一个Semaphore对象并指定许可证数量。许可证数量表示

提升群辉AudioStation音乐体验,实现公网音乐播放

文章目录本教程解决的问题是:按照本教程方法操作后,达到的效果是本教程使用环境:1群晖系统安装audiostation套件2下载移动端app3内网穿透,映射至公网很多老铁想在上班路上听点喜欢的歌或者相声解解闷儿,于是打开手机上的某雅软件和某音乐软件点进去一看:奈何目前移动端的娱乐软件广告很烦人,不知不觉就会点进去而且不好

vue基础知识十一:Vue组件之间的通信方式都有哪些?

一、组件间通信的概念开始之前,我们把组件间通信这个词进行拆分组件通信都知道组件是vue最强大的功能之一,vue中每一个.vue我们都可以视之为一个组件通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的。广义上,任何信息的交通都是通信组件间通信即指组件(.vue)通过某种方式来传递信息以达到某个目的举

动漫ip受著作权法保护吗?

受保护的,不过你得申请版权保护,不然,你难以说明这个作品的所有者是你啊,你可以了解一下可信时间戳,他能起到版权保护的作用。版权保护的重点是证明:什么人在什么时间拥有什么作品,只要原创作者能提供这样的证据就能保护自己的版权。现在每个地级城市基本上都有版权局,你可以通过版权局对你的作品进行版权登记证书的申请来保护自己的版权

【实训项目】智联校友会小程序

1.项目背景作为某某省唯一一所中医药高等院校,××大学已经走过了30个春秋,截止到现在,我校已有近十万名校友遍布全国各地,校友在社会各界享有良好声誉,校友与学校相互成为密不可分的无形资源。然而,在广大在校学生中,还有很多校友意识薄弱,对和自己息息相关的校友工作并不了解。校友会管理系统是代表学校联系和服务校友的职能系统,

半导体产品使用高温老化测试技术

主要功能:为了达到满意的合格率,几乎所有产品在出厂前都必须经过老化处理。制造商如何在不缩短老化时间的情况下提高效率?本文介绍了一种在老化过程中进行功能测试的新方法,以减少和缩短与老化过程相关的成本和时间问题。在半导体行业,关于器件老化存在着各种争论。与其他产品一样,半导体随时可能因各种原因而失效。老化是通过使半导体超载

热文推荐