docker存储驱动之btrfs简介

styshoo styshoo     2022-08-23     248

关键词:

简介

Btrfs是下一代的copy-on-write文件系统,它支持很多高级特性,使其更加适合Docker。Btrfs合并在内核主线中,并且它的on-disk-format也逐渐稳定了。不过,它的很多特性还仍然处于开发中。
Docker的btrfs存储驱动利用了很多Btrfs特性来管理镜像和容器。这些特性中最重要的就是thin provisioning(超配)、copy-on-write和快照。

Btrfs特性

  Btrfs一直被认为是Linux文件系统的未来。在Linux内核主线的全力支持下,稳定的on-disk-format,关注于稳定性的积极开发,使得Btrfs逐渐成为现实。
  只要Docker还在Linux平台上运行,人们就会认为btrfs存储驱动会替代devicemapper存储驱动,成为潜在的长期的存储驱动。然而,在写耗时上,devicemapper被认为更安全,更稳定,更适合商品化。只有当你很了解Btrfs,并且有丰富的经验时,才可以考虑btrfs驱动商品化。

镜像分层和共享Btrfs

  Docker利用Btrfs的子卷(subvolumes)和快照来管理镜像和容器层的on-disk组件。Btrfs子卷像是一个普通的Unix文件系统。同样,当挂靠到Unix文件系统时,它们可以有自己的内部目录结构。
  子卷是原生的copy-on-write,还有着按需分配的足够的空间,这些空间来自于下层的存储池。它们也可以拥有子卷,也可以使用快照。下图显示了4个子卷,子卷2和子卷3挂靠在其他子卷之上,子卷4显示了自己内部的目录树。
  技术分享
  快照是某个时间点整个子卷的读写拷贝。它们直接位于其父-子卷之下。示例如下:
  技术分享
  Btrfs从下层的存储池中,按需地为子卷和快照分配空间。分配的单位是chunk(大块),大块的大小通常是1GB左右。
  快照是Btrfs文件系统的“一等公民”,它操作时就像普通的子卷。由于Btrfs原生的copy-on-write设计,创建快照可以直接在Btrfs文件系统中构建。这意味着Btrfs快照空间利用率很高,很少或是没有性能消耗。下图显示了子卷和它快照如何分享相同数据的。
  技术分享
  Docker的btrfs存储驱动把每个镜像层和容器都保存在它们自己的Btrfs子卷或者快照中。底部镜像保存为子卷,而他的子镜像层和容器都保存为快照。下图展示了该特性。
  技术分享
  Docker是如下使用btrfs驱动的:
  1) 镜像的底层保存为Btrfs子卷,位于/var/lib/docker/btrfs/subvolumes目录下。
  2) 随后的镜像层都保存为父层(子卷或快照)的Btrfs快照。

镜像和容器on-disk构建

  镜像层和容器可在Docker host的文件系统下直接看到,目录为/var/lib/docker/btrfs/subvolumes/。即使容器停止了,但其目录依然存在。这是因为btrfs存储驱动映射了一个默认的,最高等级的子卷在/var/lib/docker/btrfs/subvolumes/下。所有其他的子卷都作为Btrfs文件系统给的对象而存在于该卷之下,而不是各自独立的映射。
  因为Btrfs工作在文件系统级别,而不是块级别,可以通过普通的Unix命令直接浏览镜像和容器层的内容。可以通过ls -l等简单命令来显示镜像层的内容,以下为一个删节的输出:

$ ls -l /var/lib/docker/btrfs/subvolumes/0a17decee4139b0de68478f149cc16346f5e711c5ae3bb969895f22dd6723751/

total 0
drwxr-xr-x 1 root root 1372 Oct  9 08:39 bin
drwxr-xr-x 1 root root    0 Apr 10  2014 boot
drwxr-xr-x 1 root root  882 Oct  9 08:38 dev
drwxr-xr-x 1 root root 2040 Oct 12 17:27 etc
drwxr-xr-x 1 root root    0 Apr 10  2014 home
...output truncated...

容器使用Btrfs读写

  容器是镜像的一个高效利用空间的快照,快照中的元数据指向存储池中的实际数据块,这个和子卷是一致的。因此,从快照中读和从子卷中读本质上是一样的。所以,Btrfs驱动没有额外的性能损耗。
  写一个新的文件,是一个按需分配的操作,会分配新的数据块给容器快照。文件也会写到这块新的空间。按需分配操作和所有Btrfs写操作一样,和写新数据到子卷也是一样的。因此,向容器快照写文件操作和原生的Btrfs操作速度一致。
  在容器中更新一个已经存在的文件会引起copy-on-write操作(实际上是redirect-on-write),驱动不操作源数据,新分配一块空间给快照。更新的数据写在这块新空间上,然后,驱动更新快照中的文件系统系统元数据,指向这块新数据。该行为只有极小的损耗。
  使用Btfs,写和更新大量小文件时,会使得性能缓慢。

在Docker中配置Btrfs

  btrfs存储驱动只有在/var/lib/docker被映射在一个Btrfs文件系统时才能被使用。以下步骤展示如何在Ubuntu 14.04 LTS上配置Brtfs。

准备知识

  如果你已经在你的Docker host上使用了Docker daemon,还有些镜像想保存,那么在尝试Btrfs之前,你需要先把镜像推送到Docker Hub或者你的私有仓库。
  停止Docker daemon。然后,确保你在/dev/xvdb下有空闲的块设备。
  另外,还需要确定你的OS上是否已经加载了Btrfs模块。输入以下命令确认:

$ cat /proc/filesystems | grep btrfs

        btrfs

在Ubuntu 14.04 LTS上配置Btrfs

  如果你的OS满足前面的要求,那么如下操作:
  1) 安装btrfs-tools包。

$ sudo apt-get install btrfs-tools

 Reading package lists... Done
 Building dependency tree
 <output truncated>

  2) 创建Btrfs存储池。
  通过mkfs.btrfs命令创建Btrfs存储池。给mkfs.btrfs命令传递多个设备则可以创建一个使用多个设备的存储池。这里我们演示一下创建单个设备(/dev/xvdb)的池。

 $ sudo mkfs.btrfs -f /dev/xvdb

 WARNING! - Btrfs v3.12 IS EXPERIMENTAL
 WARNING! - see http://btrfs.wiki.kernel.org before using

 Turning ON incompat feature ‘extref‘: increased hardlink limit per file to 65536
 fs created label (null) on /dev/xvdb
     nodesize 16384 leafsize 16384 sectorsize 4096 size 4.00GiB
 Btrfs v3.12

  记得把/dev/xvdb替换为你系统中的实际设备名称。
  再次提醒:如前面提到的,Btrfs暂时来看,不建议作为产品来使用,除非你有着丰富的经验。
  3) 在本地存储创建 /var/lib/docker。

$ sudo mkdir /var/lib/docker

  4) 使Btrfs文件系统在系统重启时会自映射。
    a. 获取Btrfs文件系统的UUID。

$ sudo blkid /dev/xvdb

/dev/xvdb: UUID="a0ed851e-158b-4120-8416-c9b072c8cf47"
UUID_SUB="c3927a64-4454-4eef-95c2-a7d44ac0cf27" TYPE="btrfs"

    b. 在/etc/fstab中增加一行条目,使得系统启动时可以自动映射/var/lib/docker。下面两行每一行都可以生效,当然,在你实际操作中,记得替换为自己的UUID。

 /dev/xvdb /var/lib/docker btrfs defaults 0 0
 UUID="a0ed851e-158b-4120-8416-c9b072c8cf47" /var/lib/docker btrfs defaults 0 0

  5.映射新的文件系统,并确认操作是否成功。

$ sudo mount -a

$ mount

/dev/xvda1 on / type ext4 (rw,discard)
<output truncated>
/dev/xvdb on /var/lib/docker type btrfs (rw)

  6.然后,重启docker服务。

$ sudo service docker start

docker start/running, process 2315

  当然,由于你使用的Linux发行版可能不同,启动Docker Daemon的方法可能也不同。
  这里,在启动Docker Daemon之前,你可以强行指定Daemon的存储驱动为btrfs存储驱动。可以在daemon启动命令行时传递–storage-driver=btrfs 参数,也可以在Docker配置文件中修改DOCKER_OPTS参数。
  7.通过docker info命令验证。

$ sudo docker info

Containers: 0
Images: 0
Storage Driver: btrfs
[...]

btrfs和Docker性能

  在btrfs存储驱动下,有以下一些原因可以影响Docker的性能。
-   Page caching,页缓存。Btrfs不支持页缓存共享,也就是说n个容器访问同一个文件会请求n份缓存拷贝。因此,btrfs驱动可能不是Paas或者高密集容器的最优选项。
-   Small writes,小的写请求。容器执行大量写的写请求(包括Docker host启动和停止很多容器)会导致Btrfs大块只使用了很小一部分,最终会导致Docker host空间不足,停止服务。这是当前使用Btrfs的一个最重大的缺点。
  如果使用btrfs存储驱动,需要密切监视Btrfs文件系统的可用空间,可用使用btrfs filesys shwo来观察。不用相信常规的Unix命令(如df)的输出。
-   Sequential writes,顺序写。Btrfs通过日志技术写数据到磁盘,这回导致顺序写的性能减半。
-   Fragmentation。存储残片是像Btrfs这种copy-on-write文件系统的天然副产品,很多小的随机写会产生这个问题。它可以表现为使用SSD介质的Docker主机上的CPU峰值和使用旋转介质的Docker主机上的抖动(It can manifest as CPU spikes on Docker hosts using SSD media and head thrashing on Docker hosts using spinning media.不是很理解这句)。这两个都会导致性能很差。 
  Btrfs的最近版本允许你制定autodefrag作为一个映射点。这种模式下,会探测到随机写并进行碎片整理。在确定使用Btrfs之前,你应该在你的Docker host上进行测试。一些测试显示,在执行大量的samll writes操作时(包括启停很多容器),这个选项会有一些负面的性能问题。
-   Solid State Devices(SSD)。Btrfs有原生的SSD优化,可以通过映射时加上-o ssd映射选项来使能它。这些优化包括在SSD介质上避免seek之类的操作来增强SSD写性能,因为这类操作在SSD上没有任何作用。
  Btrfs也支持TRIM/Discard元操作。然而,映射时加上 -o discard 的选项会导致性能问题。因此,还是建议在使用之前做些测试。
-   Use Data Volumes。数据卷提供最优和最可预测的性能。因为它们可以绕过存储驱动,不会引起任何超配和copy-on-write可能会导致的潜在的负载。
-   Balance BTRFS。开启一个cron任务来均衡你的BTRFS设备,比如均衡地传输子卷的块给raid设备,回收未使用的块。如果不这样做,docker删除的快照和子卷会遗留分配了的块,这些块装满了BTRFS根卷的。一旦你没有执行再均衡操作,在不添加额外的存储设备情况下,会导致潜在的不可恢复的状态。如果你不愿意使用crond来自动执行,另一个方法是在非峰值时手动执行再均衡命令,因此为这种操作时磁盘I/O密集型操作。此命令按要求所有的大块使用了1%或者更少:

$ sudo btrfs filesystem balance start -dusage=1 /var/lib/docker
Dumping filters: flags 0x1, state 0x0, force is off DATA (flags 0x2): balancing, usage=1 Done, had to relocate 673 out of 842 chunks

小结

  Btrfs存储驱动的主要特性就是超配,copy-on-write和快照。与AuFS或者devmapper不同,要在Docker上使用Btrfs,要求整个/var/lib/docker所处的文件系统就是Btrfs。此外,btrfs存储驱动由于现在还在重度开发中,现在最多的就是各种性能问题。所以,官方也不建议直接在Docker生产环境中使用,除非,你在Btrfs上有着丰富的经验。






































docker存储驱动之overlayfs简介

...x内核主线;   3)可能更快一些。  因此,OverlayFS在Docker社区关注度提高很快,被很多人认为是AUFS的继承者。就像宣称的一样,OverlayFS还很年轻。所以,在生成环境使用它时,还是需要更加当心。  Doc 查看详情

docker存储驱动之zfs简介

ZFS是下一代的文件系统,支持了很多存储高级特性,如卷管理、快照、和校验、压缩和重复删除技术、拷贝等。  ZFS由Sun公司创建,现属于Oracle,ZFS是开源的,并基于CDDLlicense。因为CDDL和GPL不兼容,ZFS不能加入Linuxkernel主线。... 查看详情

有容云-原理docker存储驱动之aufs

编者按:今天聊一聊Docker的Image(镜像)与Container(容器)的存储以及存储驱动之AUFS。Docker存储驱动简介 Docker内置多种存储驱动,每种存储驱动都是基于Linux文件系统(LinuxFS)或者卷管理(Volu... 查看详情

docker存储驱动的选择(代码片段)

每个Docker容器都有一个本地存储空间,用于保存层叠的镜像层以及挂载的容器文件系统。在Linux上,Docker可选择的一些存储驱动包括AUFS、Overlay2、DeviceMapper、Btrfs和ZFS。每个Docker主机只能选择一种存储驱动,在Linux上,可以通过修... 查看详情

docker五种存储驱动原理及应用场景和性能测试对比

Docker最开始采用AUFS作为文件系统,也得益于AUFS分层的概念,实现了多个Container可以共享同一个image。但由于AUFS未并入Linux内核,且只支持Ubuntu,考虑到兼容性问题,在Docker0.7版本中引入了存储驱动,目前,Docker支持AUFS、Btrfs、De... 查看详情

docker存储驱动与套接字简介(代码片段)

文章目录一、Docker存储驱动(1)Docker的分层特性(2)容器读写层的工作原理-写时复制:-用时分配:(3)Docker存储驱动-AUFS-OverlayFS-Devicemapper-常用存储驱动对比-AUFSVSOverlayFS二、Docker套接字介绍一、... 查看详情

docker深入2-存储驱动之使用devicemapper(direct-lvm)模式

docker深入2-存储驱动之使用devicemapper(direct-lvm)模式2016/12/9一、现状1、默认使用的是 devicemapper(loop-lvm)[[email protected] lib]# docker info     (略)   & 查看详情

docker存储驱动之--overlay2

参考技术Adocker支持多种graphDriver,包括vfs、devicemapper、overlay、overlay2、aufs等等,其中最常用的就是aufs了,但随着linux内核3.18把overlay纳入其中,overlay的地位变得更重,最近也在自己的虚拟机上用overlay2作为docker存储驱动实验了一... 查看详情

虚拟化之容器docker基本操作

docker是一个开源的应用容器引擎,主要利用linux内核namespace实现沙盒隔离,用cgroup实现资源限制。Docker支持三种不同的镜像层次存储的drivers:aufs、devicemapper、btrfs;Aufs:AUFS(AnotherUnionFS)是一种UnionFS,简单来说就是支持将不同目录挂载到... 查看详情

docker镜像之存储管理(代码片段)

笔者在《Docker镜像之进阶篇》中介绍了镜像分层、写时复制以及内容寻址存储(content-addressablestorage)等技术特性,为了支持这些特性,docker设计了一套镜像元数据管理机制来管理镜像元数据。另外,为了能够让docker容器适应不同... 查看详情

centos安装docker

Linux安装docker的前提条件:必须是64位CPU架构的计算机,Docker目前不支持32位CPU;运行Linux3.8或更高版本内核,CentOS时内核必不小于3.10;内核必须支持一种合适的存储驱动,可以是DeviceManager、AUFS、vfs、btrfs、以及默认的驱动DeviceMa... 查看详情

云原生之docker实战使用docker部署minio对象存储

【云原生之Docker实战】使用Docker部署MinIO对象存储一、MinIO介绍1.MinIO简介2MinIO功能二、检查本地Docker环境1.宿主机系统版本2.检查Docker版本3.检查docker服务状态三、下载MinIO镜像四、安装MinIO1.创建MinIO容器2.查看MinIO容器状态3.查看Mi... 查看详情

docker之harbor

Docker之Harbor 接着上1、2、3、4章继续研究docker  一:简介Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器。镜像的存储harbor使用的是官方的dockerregistry(v2命名是distribution)服务去完成。harbor在dockerdistribution的基... 查看详情

centosdocker安装

一、安装docker的先决条件:1.必须是64位CPU架构的计算机,Docker目前不支持32位CPU;2.运行Linux3.8或更高版本内核,CentOS的内核版本不能低于3.10;3.内核必须支持一种合适的存储驱动,可以是DeviceManager、AUFS、vfs、btrfs、以及默认的... 查看详情

docker入门之镜像管理基础(代码片段)

docker镜像管理基础首发:arppinging一、镜像概述1.1联合挂载在之前的文章我们提到过,容器是基于镜像启动的,镜像的存储驱动是overlay2overlayFS将单个Linux主机上的两个目录合成一个目录,这些目录称为层,统一过程被称为联合挂载... 查看详情

kubernetes之存储卷(代码片段)

...简介为了保证数据的持久性,必须保证数据在外部存储在docker容器中,为了实现数据的持久性存储,在宿主机和容器内做映射,可以保证在容器的生命周期结束,数据依旧可以实现持久 查看详情

stm32cubemx之sd卡驱动

STM32CubeMx之SD卡驱动1.SD卡简介   SD存储卡(SecureDigitalMemoryCard)是一种基于半导体快闪存储器的新一代高速存储设备。SD存储卡的技术是从MMC卡(MultiMediaCard)格式上发展而来,在兼容SD存储卡基础上发展了SDIO(SDInput/Output)卡,... 查看详情

docker虚拟化技术系列之-磁盘扩容

Docker在启动容器的时候,需要创建文件系统,为rootfs提供挂载点。最初Docker仅能在支持Aufs文件系统的Linux发行版上运行,但是由于Aufs未能加入Linux内核,为了寻求兼容性、扩展性,Docker在内部通过graphdriver机制这种可扩展的方式... 查看详情