当前位置: 首页 > news >正文

Docker存储技术全解析:分层与持久化

docker存储

docker分层结构

如图所示,容器是由最上面可读可写的容器层,以及若干个只读镜像层组成,创建容器时,容器中的 数据都来自镜像层。这样的分层机构最大的特点是写时复制:

  • 容器中新生成的数据会直接存放在容器层,也可以称之为可写层

  • 修改容器中现有的数据会先从镜像层将数据复制到容器层,修改后的数据就会直接保存在容器层,而镜像层数据不会有任何变化

  • 如果多个镜像层中有相同的命名文件,在容器层只会看到最上面镜像层的内容

在这里插入图片描述

联合挂载技术

Docke镜像采用这种分层构建设计,能使镜像结构和容器的创建,共享和分发变得非常高效,每个镜像层可以称之为layer,这些layer被存放在了/var/lib/docker/volume/<storage-driver>/目录下,这里的storage-driver可以有很多种,比如AUFS、OverlayFS、VFS、Brtfs等。可以通过dockerinfo命令查看存储驱动,通常Ubuntu类的系统默认采用的是AUFS,Centos7.1+系列采用的是OverlayFS

OverlayFS是一种堆叠文件系统,它依赖并建立在其它的文件系统之上(例如ext4fs和xfs等等),并不直接参与磁盘空间结构的划分,仅仅将原来底层文件系统中不同的目录进行合并,然后向用户呈现,这也就是联合挂载技术,如图所示。而Linux内核为Docker提供的OverlayFS驱动有两种:overlay和 overlay2。而overlay2是相对于overlay的一种改进,在inode利用率方面比overlay更有效。但是overlay 有环境需求:Docker版本17.06.02+,宿主机文件系统需要是ext4或xfs格式

在这里插入图片描述

datavolume

默认情况下,在容器内创建的所有文件都存储在可写容器层上。这意味着,当该容器不再存在时,数据将不会持久保存,并且如果另一个进程需要它,则可能很难从容器中取出数据。为了能够保存持久化数据,Docker提出了volume的概念

为了能够保存持久化数据,Docker提出了volume的概念。简单来说,volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于DockerHost文件系统上。 Docker为容器提供了两个选项来将文件存储在主机中,以便即使容器停止后文件也可以持久存储

Volume类型:
- Bind mounts宿主机——》容器
– Docker managed volume容器——》宿主机

bind mounts

Bind mounts只需要在创建容器时,使用-v参数指明Docker host目录或文件和容器目录或文件映射的对应关系, 将本地的数据映射到容器内,可以使用多个-v映射多个目录或文件,还需要注意的是目录只能映射目录,文件只能映射

文件,不然会报错。实例如下:

1、在Docker host中创建目录,与容器的/usr/share/nginx/html目录做映射,在容器中/usr/share/nginx/html 目录已经存在,如果不存在,会自动创建路径,映射时会隐藏容器中原本的数据,取而代之的是Docker host上的 /html目录中的数据

[root@docker ~] mkdir /html
[root@docker ~] vim /html/index.html
welcome to luoqi!!!
[root@docker ~] docker run --name cynginx -itd -p 80:80 -v /html:/usr/share/nginx/html nginx:latest
cc0c8d7ac53af8b29f32aae76b767e51e6c3358ed2b491bd1ef4e0b96e77f3e5
[root@docker ~] curl http://127.0.0.1
welcome to luoqi!!!

2、当Docker host上的数据发生了变化,容器中的数据也会随着发生变化,示例如下

[root@docker ~] echo hello luoqi > /html/index.html
[root@docker ~] curl http://127.0.0.1
hello huayu

3、就算是把容器删除,也不会影响到Docker host上的数据,示例如下

[root@docker ~] docker stop cynginx
cynginx
[root@docker ~] docker rm cynginx
cynginx
[root@docker ~] cat /html/index.html
hello luoqi

4、此外,Bind mounts还可以指定数据的读写权限,默认权限是可读可写,示例如下,在映射volume时,指定 容器中的文件权限只读,那么在容器内该文件只能被读取,无法修改,这样也提高了容器的安全性

[root@docker ~] docker run --name cynginx1 -itd -p 80:80 -v
/html/index.html:/usr/share/nginx/html/
index.html:ro nginx:latest
[root@docker ~] curl http://127.0.0.1
hello luoqi
[root@docker ~] docker exec -it cynginx1 /bin/bash
root@0555f35f03e8:/# echo luoqi123 > /usr/share/nginx/html/index.html
bash: /usr/share/nginx/html/index.html: Read-only file system

通过上面的示例,我们已经理解了Bind mounts的使用,但是它也有自身的不足之处,使用时需要指定Docker host上的文件或目录为源数据,这样就限制了容器的可移植性。例如,当需要把容器移动到其他的Docker host上的时候,如果对方Docker host上没有源数据库,或者路径不相同,操作会失败

docker managed volume

第二种volume类型是由Docker管理的volume,与Bind mounts相比,Docker管理的volume在使用时不需要指 定Docker host路径,Docker管理的volume具有以下几个优点:

  1. 与Bind mounts相比,Docker管理的volume更易于备份或迁移
  2. 用户可以使用Docker CLI命令或Docker API管理volume
  3. volume在Linux和Windows容器上均可工作
  4. 可以在多个容器之间更安全地共享volume,提供volume加密功能
  5. 可以通过容器预先填充新volume的内容

实例如下:

1、通过-v告诉Docker需要一个volume,并将其mount到/usr/share/nginx/html目录,那么Docker会在 /var/lib/docker/volumes/目录下创建volume

[root@docker ~] docker run --name cynginx2 -itd -p 80:80 -v /usr/share/nginx/html/ nginx
22c875d19f3f12c8528e8f5316395305c04b3f127cdb5d877e57c055d1933fa7

2、使用docker inspect查看容器的mounts部分,可以看到docker host上的 /var/lib/docker/volumes/6adbe6c8051f58c1d5cc2e8a12faaf1e6aa60b1075433b33a410a5d55cd8e69c/_data目录已经挂在到容器中 /usr/share/nginx/html目录下,但是查看Docker host的volume中内容,内容是容器中的数据。也就是说使用Docker管理的volume,在做映射时,会把容 器中的数据映射到Docker host

[root@docker ~] docker inspect cynginx2
"Mounts": [
{ "Type": "volume", "Name": "6adbe6c8051f58c1d5cc2e8a12faaf1e6aa60b1075433b33a410a5d55cd8e69c", "Source": "/var/lib/docker/volumes/6adbe6c8051f58c1d5cc2e8a12faaf1e6aa60b1075433b33a410a5d55cd8e69c/_data", "Destination": "/usr/share/nginx/html",
...... [root@docker ~] ls /var/lib/docker/volumes/6adbe6c8051f58c1d5cc2e8a12faaf1e6aa60b1075433b33a4
10a5d55cd8e69c/_data
50x.html index.html

3、我们修改volume中的数据,再访问,发现volume中修改的数据会同步到容器中的

[root@docker ~] echo luoqi1234 >
/var/lib/docker/volumes/6adbe6c8051f58c1d5cc2e8a12faaf1e6aa6
0b1075433b33a410a5d55cd8e69c/_data/index.html
[root@docker ~] curl http://127.0.0.1
luoqi1234

4、我们还可以是使用docker volume命令查看docker管理的有哪些volume,并且还可以创建volume,示例如 下,创建一个volume,名为cyhuayu。在创建新的容器时,可以直接指定使用该volume

[root@docker ~] docker volume ls
DRIVER VOLUME NAME
local 6adbe6c8051f58c1d5cc2e8a12faaf1e6aa60b1075433b33a410a5d55cd8e69c
[root@docker ~] docker volume create cyluoqi
cyluoqi
[root@docker ~] docker volume ls
DRIVER VOLUME NAME
local 6adbe6c8051f58c1d5cc2e8a12faaf1e6aa60b1075433b33a410a5d55cd8e69c
local cyluoqi
[root@docker ~] docker run --name cynginx3 -itd -p 81:80 -v cyluoqi:/usr/share/nginx/html/
nginx:latest
072c6758e9a815f2421861a54bfc8168eaf286df66f1d3187bc3c4141880e52f

两种volume不同点

在使用docker volume命令创建volume时,volume默认都是存在在本地的,实际上本地的volume 就是一个目录。除此之外Docker还支持在外部存储系统上创建volume,比如:NFS、Ceph等。 目前我们已经学习了Docker的两种volume的理论和基本操作,它们两者之间的相同点都是使用 Docker host文件系统中的某个路径。不同点如下表所示

不同点Bind mountsDocker managed volume
volume 位置可任意指定/var/lib/docker/volumes/…
对已有 mount point 影响隐藏并替换为 volume原有数据复制到 volume
是否支持单个文件支持不支持
权限控制可设置为只读,默认为读写无控制,均为读写权限
移植性移植性弱,与 host path 绑定移植性强,无需指定 host 目录

docker存储

数据共享

实现容器间数据共享的方法如下:

  1. 第一种方法是将共享数据放在volume中,然后将其mount到多个容器
  2. 第二种方法是使用volume container,volume container是用来为其他容器提供volume的容器。这样可以提高容器的可移植性
  3. 第三种方法是将数据打包到镜像中,然后通过–volumes-from共享

容器之间共享数据

第一种方法是将共享数据放在volume中,然后将其mount到多个容器。示例如下,创建由三个nginx容器组成的 web集群,使用相同的html文件。在使用-v指定volume时,可以是Docker host的路径或者是Docker创建的volume

[root@docker ~] docker run --name apache1 -itd -p 8081:80 -v /html:/usr/share/nginx/html/
nginx:latest
[root@docker ~] docker run --name apache2 -itd -p 8082:80 -v /html:/usr/share/nginx/html/
nginx:latest
[root@docker ~] docker run --name apache3 -itd -p 8083:80 -v /html:/usr/share/nginx/html/
nginx:latest
[root@docker ~] curl http://127.0.0.1:8081
hello luoqi
[root@docker ~] curl http://127.0.0.1:8082
hello luoqi
[root@docker ~] curl http://127.0.0.1:8083
hello luoqi

volume container

第二种方法是使用volume container,volume container是用来为其他容器提供volume的容器。这样可以提高容 器的可移植性

创建volume container,容器名为cy_data,使用-v指定了volume,提供html文件。需要注意的是,这里使用的 是docker create创建的容器,也就是说容器只是创建了,并未启动,因为volume container只是提供数据,自身并不 需要运行

[root@docker ~] docker create --name cy_data -v /html:/usr/share/nginx/html busybox
# 创建新的nginx容器,使用参数--volumes-from指定使用cy_data容器提供的volume
[root@docker ~] docker run --name cynginx1 -itd -p 8081:80 --volumes-from cy_data nginx
[root@docker ~] docker run --name cynginx2 -itd -p 8082:80 --volumes-from cy_data nginx
[root@docker ~] docker run --name cynginx3 -itd -p 8083:80 --volumes-from cy_data nginx

通过docker inspect查看容器信息中的Mounts部分,可以看到新创建的nginx容器已经使用了cy_data容器所提供 的volume。经过验证三个nginx容器中的html文件一样

[root@docker ~] docker inspect cynginx1
[root@docker ~] echo welcome to luoqi > /html/index.html
[root@docker ~] curl http://127.0.0.1:8081
welcome to luoqi
[root@docker ~] curl http://127.0.0.1:8082
welcome to luoqi
[root@docker ~] curl http://127.0.0.1:8083
welcome to luoqi

与第一种实现数据共享的方法相比,不必再为每个容器指定voleme,所有volume都在volume container 中定义 好了,容器只需与volume container关联,实现了容器与Docker host的解耦

data-packed volume container

volume container的数据归根到底还是在Docker host里,对容器的可移植性有一定的限制。这里可以使用data- packed volume container。其原理是将数据打包到镜像中,然后通过–volumes-from共享。 示例如下,使用Dockerfile构建镜像,将Docker host中的数据进行打包。ADD指令是将html目录中的数据添加到 容器目录/usr/share/nginx/html中。VOLUME指令的作用与-v效果相同,用来创建volume,并且会把 /usr/share/nginx/html目录中的数据复制到volume中

[root@docker ~] mkdir html/
[root@docker ~] echo luoqi > index.html
[root@docker ~] vim Dockerfile
FROM busybox:latest
ADD html /usr/share/nginx/html
VOLUME /usr/share/nginx/html
CMD [“/bin/bash”]
[root@docker ~] docker build -t cy_hy /root

使用新构建的镜像创建data-packed volume container,创建新的nginx容器,使用参数–volumes-from 指定使用cy_data123容器提供的volume

[root@docker ~] docker create --name cy_data123 cy_hy
[root@docker ~] docker run --name cynginx7 -itd -p 8087:80 --volumes-from cy_data123 nginx
[root@docker ~] docker inspect cynginx7
[root@docker ~] curl http://127.0.0.1:8087
luoqi

容器能够正确读取volume中的数据。data-packed volume container是自包含的,不依赖Docker host提供数据,具有很强的移植性,非常适合只使用静态数据的场景,比如应用的配置信息、web server的静 态文件等

总结

  1. 实现数据共享的方法有:容器指定同一个volume、volume contauner和data-packed volume contauner
  2. volume分为两类:Bind mounts和Docker managed volume
    据。data-packed volume container是自包含的,不依赖Docker host提供数据,具有很强的移植性,非常适合只使用静态数据的场景,比如应用的配置信息、web server的静 态文件等

总结

  1. 实现数据共享的方法有:容器指定同一个volume、volume contauner和data-packed volume contauner
  2. volume分为两类:Bind mounts和Docker managed volume
  3. 创建容器时,使用-v参数可以实现容器数据持久化存储,volume分为两类:Bind mounts类型是将volume中的数据复制到容器中,Docker managed volume是将容器中的数据复制到volume中
http://www.dtcms.com/a/469245.html

相关文章:

  • 分布式专题——39 RocketMQ客户端编程模型
  • 物联网二级平台设计与实现:从Home Assistant到JetLinks的设备协同架构实践
  • 分布式文件存储 RPC 服务实现
  • 在哪些软件上建设网站市场营销方案怎么做
  • 《小小梦魇3》今日发售!用UU远程手机躺玩通关
  • Jenkins Pipeline post指令详解
  • 系列文章<一>(从LED显示问题到非LED领域影像画质优化:揭秘跨领域的核心技术):从LED冬奥会、奥运会及春晚等大屏,到手机小屏,快来挖一挖里面都有什么
  • 泊松分布解题步骤
  • Postman API 测试使用指南:从入门到精通
  • VisualSVN-Server-2.5.26 TortoiseSVN-1.7.21
  • SVN 检出操作
  • 深度相机初探:立体视觉(Stereo Vision)、结构光(Structured Light)、TOF(Time of Flight,飞行时间)
  • SVN 生命周期
  • 武昌做网站公司互联网营销顾问是做什么的
  • 辉视融合服务器:强劲驱动电视信息发布,直播点播流畅运行,赋能高效传播
  • MyBatis-Spring-Boot快速上手指南
  • Linux运维实战:系统及服务管理(视频教程)
  • 服务器运维(四)服务器漏洞扫描工具与审查——东方仙化神期
  • SolidWorks服务器多人使用方案
  • 安卓手机app开发软件下载网站关键词优化效果
  • Redis中的RPOP、BRPOP、LPOP 和 BLPOP
  • R语言学习
  • 【C++】C++11 新特性详解(下)
  • 成都市公园城市建设管理局网站济南百度推广开户
  • 网站的技术建设公司网站建设 wordpress
  • 联想小新平板Pro GT/Y700四代平板无需解锁BL获取root权限方法
  • Linux系统安装PGSQL实现向量存储
  • 跨语言协作新范式:阿里云Qwen-MT与DooTask的翻译技术突破
  • LLM 笔记 —— 04 为什么语言模型用文字接龙,图片模型不用像素接龙呢?
  • ubuntu-20.04.6升级OpenSSH_10.2p1