docker配置devicemapper存储驱动

#查看当前使用的存储驱动,默认为overlay
docker info | grep -i storage

#停止docker
systemctl stop docker
#移除原存储配置文件
rm /etc/sysconfig/docker-storage #使用vdb磁盘创建pv
pvcreate /dev/vdb #使用vdb磁盘创建dockercg
vgcreate dockervg /dev/vdb #配置docker pool为dockervg
cat <<EOF > /etc/sysconfig/docker-storage-setup
VG=dockervg
EOF #配置存储
docker-storage-setup #重启docker
systemctl restart docker

devicemapper存储驱动下镜像的存储

docker数据存储的目录为/var/lib/docker,可以通过docker info | grep -i "Docker Root Dir" 查看

以下通过构建一个镜像来观察镜像的存储方式,Dockerfile如下

#创建测试目录
mkdir -p /tmp/docker-test && cd /tmp/docker-test #创建Dockerfile和测试文件
echo <<EOF > Dockerfile
FROM docker.io/resouer/guestbook:v1 (该镜像已存在节点)
COPY 1 /tmp/1.txt
COPY 2 /tmp/2.txt
COPY 3 /tmp/3.txt
EOF
echo 111 > 1
echo 222 > 2
echo 333 > 3 #构建镜像前/var/lib/docker/devicemapper两个目录文件数量如下

#构建镜像

docker build -t docker-test01 . --no-cache

#构建镜像后/var/lib/docker/devicemapper两个目录文件数量如下

#通过ls -lrt在metadate目录查看最新生成的文件,如图新增了3个文件与Dockerfile中的3个COPY层对应

#每层分别有一个device_id,如下图

使用device_id创建dm设备并挂载到文件系统

如上,每个镜像层都会对应一个device_id

#查看docker为其管理的容器所创建的dm设备
dmsetup ls
dmsetup table
其中dmsetup table输出结果的格式如下
logical_start_sector num_sectors target_type target_args
开始扇区 扇区数 设备类型 设备参数 如docker-253:1-1447237-b4b4ee02b3171ce0d9c9c39012b87dfe69c72fee4ab2a004bf03983ea00b612c: 0 20971520 thin 252:2 141 docker-253:1-1447237-b4b4ee02b3171ce0d9c9c39012b87dfe69c72fee4ab2a004bf03983ea00b612c为在/dm设备名称
0为起始扇区
20971520 为扇区数,一个扇区大小为512kb,总共为10g
thin为{未知,dm设备所使用的存储块按需分配?}
252:2为dockervg-docker--pool的dm编号,可通过dmsetup ls查看
141为device_id #为每个镜像层依次创建dm设备
dmsetup create myimage-dm1 --table "0 20971520 thin 252:2 186"
dmsetup create myimage-dm2 --table "0 20971520 thin 252:2 189"
dmsetup create myimage-dm3 --table "0 20971520 thin 252:2 192"
#查看/dev/mapper目录,发现新增了3个链接文件,链接到不同dm设备

#创建测试挂载点,并挂载dm设备

mkdir -p /tmp/mp1

mkdir -p /tmp/mp2

mkdir -p /tmp/mp3

mount /dev/dm-19 /tmp/mp1/

查看/tmp/mp1中的rootfs/tmp目录,如下,tmp目录只有一个1.txt文件,与Dockerfile中的第一个COPY层吻合

继续通过mount /dev/dm-20 /tmp/mp2/  mount /dev/dm-21 /tmp/mp3/挂载第二层和第三层,均报Filesystem has duplicate UUID 040571c8-2123-4c9b-ab15-a77f69626835 - can't mount,如下

#卸载dm-19,再挂载dm-20,可以看到tmp目录下对应Dockerfile中的第一个COPY和第二个COPY的内容

umount /dev/dm-19 && mount /dev/dm-20 /tmp/mp2

#再次dm-20,再挂载dm-21,可以发现tmp目录是对应的全部的三个测试文件

以上说明,镜像的每一个层是根据Dockerfile中的顺序依次叠加的

应用

每个镜像层是上一个镜像层的一个快照,容器层则是顶层镜像的快照,每一个容器也会对应一个DeviceId。当容器死掉之后,docker会默认移除这个容器对应的dm设备,那么这个死掉的容器的rootfs就没有挂载到文件系统上,可以通过docker inspect {containerId} | grep -i deviceid获取到DeviceId之后,使用上文提到的方法创建dm设备并挂载到文件系统,这样就可以取出死掉的容器中的内容。

参考:

https://www.cnblogs.com/xuxinkun/p/10643840.html

https://blog.csdn.net/felix_yujing/article/details/54344251

摘抄至上述链接:

关于读
官网上读操作的说明图如下:

1)应用请求读取容器中的0x44f块区
因为容器是镜像的一个简单快照,并没有数据只有一个指针,指向镜像层存储数据的地方。
2)存储驱动根据指针,到镜像快照的a005e镜像层寻找0xf33块区
3)devicemapper从镜像快照拷贝0xf33的内容到容器的内存中
4)存储驱动最后将数据返回给请求的应用

关于写
当对容器中的大文件做一个小的改动的时候,devicemapper不会复制这整个文件,而是只拷贝被修改的块区。每个块区的大小为64KB。

写新数据的情况
例如,写56KB大小的新数据到一个容器:
1)应用发出一个要写56KB的新数据到容器的请求
2)根据按需分配,将分配一个新的64KB的块区给容器的快照
如果写操作的数据大于64KB的话,将分配多个块区
3)之后,数据将被写入到新分配的块区中

覆写已有的数据
每当容器第一次更新已有的数据时:
1)应用发出一个修改容器中数据的请求
2)copy-on-write操作将定位到需要更新的块区
3)然后分配新的空块区给容器快照,并复制数据到新分配的块区
4)接着,在有复制数据的新块区中进行数据修改
容器中的应用对发生的allocate-on-demand操作和copy-on-write操作是无感的

关于devicemapper的性能
allocate-on-demand的性能影响
每当应用有新数据要写入容器时,都要从pool中去定位空的块区并映射给容器。因为所有块区都是64KB的,小于64KB的数据也会分配一个块区;大于64B的数据则会分配多个块区。所以,特别是当发生很多小的写操作时,就会比较影响容器的性能。

copy-on-write的性能影响
每当容器第一次更新已有的数据时,devicemapper存储驱动都要执行copy-on-write操作。这个操作是从镜像快照复制数据到容器快照,这对容器性能还是有比较明显的性能影响的。当容器发生很多小64KB的写操作时,devicemapper的性能会比AUFS要差。

其它方面
1)所使用的mode
默认情况下,devicemapper使用的是loop-lvm模式,这种模式使用的是sparse files,性能比较低。生产环境建议使用direct-lvm模式,这种模式存储驱动直接写数据到块设备。
2)使用高速存储
如果希望更好的性能,可以将Data file和Metadata file放到SSD这样的高速存储上。
3)内存使用
devicemapper并不是一个有效使用内存的存储驱动。当一个容器运行n个时,它的文件也会被拷贝n份到内存中,这对docker宿主机的内存使用会造成明显影响。因此,devicemapper存储驱动可能并不是PaaS和其它高密度使用型的最好选择。

对于写操作较大的,可以采用挂载data volumes。使用data volumes可以绕过存储驱动,从而不受thin provisioning和copy-on-write产生的负责影响。

devicemapper存储驱动下镜像的存储的更多相关文章

  1. Docker存储驱动之Btrfs简介

    简介 Btrfs是下一代的copy-on-write文件系统,它支持很多高级特性,使其更加适合Docker.Btrfs合并在内核主线中,并且它的on-disk-format也逐渐稳定了.不过,它的很多 ...

  2. Docker的OverlayFS存储驱动

    OverlayFS存储驱动 OverlayFS是一个现代的Union Filesystem,类似于AUFS,但速度更快,实现更简单.Docker为OverlayFS提供了两个存储驱动程序:overla ...

  3. Docker存储驱动之ZFS简介

    ZFS是下一代的文件系统,支持了很多存储高级特性,如卷管理.快照.和校验.压缩和重复删除技术.拷贝等. ZFS由Sun公司创建,现属于Oracle,ZFS是开源的,并基于CDDL license.因为 ...

  4. 有容云-【原理】Docker存储驱动之AUFS

    编者按:今天聊一聊Docker的Image(镜像)与Container(容器)的存储以及存储驱动之AUFS.   Docker存储驱动简介 Docker内置多种存储驱动,每种存储驱动都是基于Linux ...

  5. Docker镜像文件存储结构

    docker相关文件存放在:/var/lib/docker目录下 镜像的存储结构主要分两部分,一是镜像ID之间的关联,一是镜像ID与镜像名称之间的关联,前者的结构体叫Graph,后者叫TagStore ...

  6. Docker存储驱动之OverlayFS简介

    简介 OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性: 1) 更简单地设计: 2) 从3.18开始,就进入了Linux内核主线: 3) 可能更快一些. ...

  7. Docker存储驱动之Device Mapper简介

    Device Mapper是一个基于kernel的框架,它增强了很多Linux上的高级卷管理技术.Docker的devicemapper驱动在镜像和容器管理上,利用了该框架的超配和快照功能.为了区别, ...

  8. Docker存储驱动之总览

    简介 本文会介绍Docker存储驱动的特性,别列出现在已经支持的存储驱动,最后,会介绍如果选型适合你的存储驱动. 可插拔的存储驱动架构 Docker的存储驱动架构是可插拔的,可以让你很方便的将适合你环 ...

  9. 聊一聊docker存储驱动

    目录 镜像的分层特性 容器读写层的工作原理 写时复制 用时配置 Docker存储驱动 AUFS OverlayFS Devicemapper 常用存储驱动对比 AUFS VS OverlayFS Ov ...

随机推荐

  1. 百万年薪python之路 -- 函数初始

    1.函数 1.1 认识函数 定义一个事情或者是功能,等到需要的时候直接去用就好了.那么这里定义东西就是一个函数 函数:对代码块和功能的封装和定义 函数的好处: 减少代码的重复性 代码可读性高 将功能进 ...

  2. maven的相关操作及常见问题

    mvn本地服务nexus3的搭建 下载 下载nexus 官网速度极慢,下面是我下好上传的大家可以下载使用链接:https://pan.baidu.com/s/1Ji5Orv3moXc60HRQ39y6 ...

  3. Mutex vs Semaphore vs Monitor vs SemaphoreSlim

    C#开发者(面试者)都会遇到Mutex,Semaphore,Monitor,SemaphoreSlim这四个与锁相关的C#类型,本文期望以最简洁明了的方式阐述四种对象的区别. 线程安全 教条式理解 如 ...

  4. JdbcTemplate增删改

    (1)Accountsdao层 //删除单个账户 int delaccount(Integer accountid); //添加单个用户 int addaccount(Accounts account ...

  5. vue事件双向绑定

    事件 案例: vue的事件绑定原理:改变图片的背景颜色问题来实现这个框架的使用方法, new Vue({ el:"", data:{}, methord:{}, computed: ...

  6. fenby C语言 P17

    for姐姐 dowhile妹妹 while for(循环变量赋初值,循环条件,循环变量自加) #include <stdio.h> int main(){ int sum=0,i; for ...

  7. vue进入新页面,与原页面滚动到相同高度的解决方案

    可以在vue路由新增scrollBehavior,控制跳转页面高度 import Router from 'vue-router' new Router({ scrollBehavior (to, f ...

  8. URL百分号编码

    百分号编码是什么! 百分号编码(Percent-Encoding)也被称为 URL 编码,是一种编码机制.该机制主要应用于 URI 编码中,URI 包含 URL 和 URN,所以它们也同样适用.除此之 ...

  9. Modbus协议笔记

    读线圈:就是说读开关量输出的状态,看看开关量输出的到底是开着的还是关着的,这样说有点不专业,但是好明白.比如要在上位机显示开关量输出的当状态,就得用这个功能码. 写线圈:就是说读开关量输入的状态,开关 ...

  10. windows下搭建开发环境

    PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发 ...