使用BTRFS存储驱动程序

预计阅读时间:11分钟

Btrfs是下一代写时复制文件系统,它支持许多高级存储技术,使其非常适合Docker。Btrfs包含在主线Linux内核中。

Docker的btrfs存储驱动程序利用许多Btrfs功能进行图像和容器管理。这些功能包括块级操作,自动精简配置,写时复制快照和易于管理。您可以轻松地将多个物理块设备组合到一个Btrfs文件系统中。

本文将Docker的Btrfs存储驱动程序称为btrfsBtrfs,将整个Btrfs文件系统称为Btrfs。

注意btrfs仅Docker Engine-Ubuntu或Debian上的Community支持存储驱动程序。

先决条件

btrfs 如果满足以下先决条件,则支持此功能:

  • Docker Engine-Communitybtrfs仅在Ubuntu或Debian上建议使用Docker Engine-Community 。

  • 更改存储驱动程序将使您已经创建的所有容器在本地系统上均不可访问。使用docker save保存的容器,并推动现有图像多克尔集线器或私人仓库,让你不必再后来创建它们。

  • btrfs需要专用的块存储设备,例如物理磁盘。必须将此块设备格式化为Btrfs并安装到中/var/lib/docker/。下面的配置说明将指导您完成此过程。默认情况下,SLES/文件系统是使用BTRFS格式化的,因此对于SLES,您不需要使用单独的块设备,但是出于性能方面的考虑,您可以选择这样做。

  • btrfs支持必须存在于您的内核中。要检查这一点,请运行以下命令:

    $ grep btrfs /proc/filesystems
    
    btrfs
    
  • 要在操作系统级别管理BTRFS文件系统,您需要 btrfs命令。如果没有此命令,请安装btrfsprogs 软件包(SLES)或btrfs-tools软件包(Ubuntu)。

配置Docker以使用btrfs存储驱动程序

在SLES和Ubuntu上,此过程本质上是相同的。

  1. 停止Docker。

  2. 将的内容复制/var/lib/docker/到备份位置,然后清空的内容/var/lib/docker/

    $ sudo cp -au /var/lib/docker /var/lib/docker.bk
    $ sudo rm -rf /var/lib/docker/*
    
  3. 将一个或多个专用块设备格式化为Btrfs文件系统。本示例假设您正在使用两个名为/dev/xvdf和的 块设备/dev/xvdg。仔细检查块设备名称,因为这是破坏性操作。

    $ sudo mkfs.btrfs -f /dev/xvdf /dev/xvdg
    

    Btrfs还有更多选项,包括条带化和RAID。请参阅 Btrfs文档

  4. /var/lib/docker/挂载点上挂载新的Btrfs文件系统。您可以指定用于创建Btrfs文件系统的任何块设备。

    $ sudo mount -t btrfs /dev/xvdf /var/lib/docker
    

    别忘了通过向添加条目来使更改在重新启动后永久生效/etc/fstab

  5. 将的内容复制/var/lib/docker.bk/var/lib/docker/

    $ sudo cp -au /var/lib/docker.bk/* /var/lib/docker/
    
  6. 配置Docker以使用btrfs存储驱动程序。即使/var/lib/docker/现在正在使用Btrfs文件系统,这也是必需的。编辑或创建文件/etc/docker/daemon.json。如果是新文件,请添加以下内容。如果它是现有文件,则仅添加键和值,如果它不是结束大括号(})之前的最后一行,请小心以逗号结束。

    {
      "storage-driver": "btrfs"
    }
    

    守护程序参考文档中查看每个存储驱动程序的所有存储选项

  7. 启动Docker。运行后,确认btrfs已被用作存储驱动程序。

    $ docker info
    
    Containers: 0
     Running: 0
     Paused: 0
     Stopped: 0
    Images: 0
    Server Version: 17.03.1-ce
    Storage Driver: btrfs
     Build Version: Btrfs v4.4
     Library Version: 101
    <...>
    
  8. 准备好后,删除/var/lib/docker.bk目录。

管理Btrfs卷

Btrfs的好处之一是易于管理Btrfs文件系统,而无需卸载文件系统或重新启动Docker。

当空间变小时,Btrfs会自动将卷扩展为大约1 GB的

要将块设备添加到Btrfs卷,请使用btrfs device addbtrfs filesystem balance命令。

$ sudo btrfs device add /dev/svdh /var/lib/docker

$ sudo btrfs filesystem balance /var/lib/docker

注意:虽然您可以在Docker运行时执行这些操作,但性能会受到影响。最好计划一个中断窗口以平衡Btrfs文件系统。

btrfs存储驱动程序如何工作

btrfs存储驱动器的工作方式不同devicemapper或在您的整个其他存储驱动程序/var/lib/docker/目录存储在增加了Btrfs卷上。

磁盘上的图像和容器层

有关图像层和可写容器层的信息存储在中 /var/lib/docker/btrfs/subvolumes/。该子目录每个图像或容器层包含一个目录,该统一目录由一个层及其所有父层构建而成。子卷本身是写时复制的,并根据需要从基础存储池中分配了空间。它们也可以嵌套和快照。下图显示了4个子卷。“子卷2”和“子卷3”是嵌套的,而“子卷4”则显示其自己的内部目录树。

子卷示例

仅图像的基础层存储为真实的子体积。所有其他层都存储为快照,其中仅包含该层中引入的差异。您可以创建快照的快照,如下图所示。

快照图

在磁盘上,快照的外观和感觉就像子卷一样,但实际上它们更小且更节省空间。写入时复制用于最大化存储效率和最小化层大小,并且在块级别管理容器可写层中的写入。下图显示了一个子卷及其快照共享数据。

快照和子卷共享数据

为了获得最大效率,当一个容器需要更多空间时,将以大约1 GB的为单位进行分配 。

Docker的btrfs存储驱动程序将每个图像层和容器存储在其自己的Btrfs子卷或快照中。图像的基础层存储为子卷,而子图像层和容器存储为快照。如下图所示。

Btrfs容器层

在运行btrfs驱动程序的Docker主机上创建映像和容器的高级过程如下:

  1. 图像的基本层被存储在一增加了Btrfs子体积/var/lib/docker/btrfs/subvolumes

  2. 随后的图像层被存储为增加了Btrfs快照父层的子体积或快照的,但与此层中引入的变化。这些差异存储在块级别。

  3. 容器的可写层是最终图像层的Btrfs快照,其中差异由运行中的容器引入。这些差异存储在块级别。

容器如何读写 btrfs

读取文件

容器是图像的节省空间的快照。快照中的元数据指向存储池中的实际数据块。这与子卷相同。因此,对快照执行的读取与对子卷执行的读取基本相同。

写文件

  • 写入新文件将新文件写入容器会调用按需分配操作,以将新数据块分配给容器的快照。然后将文件写入此新空间。按需分配操作是使用Btrfs进行的所有写入所固有的,并且与将新数据写入子卷相同。结果,将新文件写入容器的快照以本机Btrfs速度运行。

  • 修改现有文件:更新容器中的现有文件是写时复制操作(写时重定向是Btrfs术语)。从文件当前所在的层读取原始数据,并且仅将修改后的块写入容器的可写层。接下来,Btrfs驱动程序更新快照中的文件系统元数据以指向此新数据。此行为产生很少的开销。

  • 删除文件或目录:如果容器删除了下层中存在的文件或目录,则Btrfs将掩盖下层中文件或目录的存在。如果容器创建了一个文件然后将其删除,则在Btrfs文件系统本身中执行此操作,并回收空间。

使用Btrfs,写入和更新许多小文件可能会导致性能降低。

Btrfs和Docker性能

btrfs 存储驱动程序下,有几个因素会影响Docker的性能。

注意:通过将Docker卷用于繁重的写工作负载,而不是依赖于将数据存储在容器的可写层中,可以缓解许多因素。然而,在增加了Btrfs的情况下,多克尔卷仍从这些画中后卫吃亏,除非/var/lib/docker/volumes/通过增加了Btrfs支持。

  • 页面缓存。Btrfs不支持页面缓存共享。这意味着访问同一文件的每个进程都会将该文件复制到Docker主机的内存中。结果,btrfs驱动程序可能不是诸如PaaS之类的高密度用例的最佳选择。

  • 小写。容器执行大量小写操作(此使用模式与您在短时间内启动和停止许多容器时发生的情况相匹配)也会导致Btrfs块的使用不佳。这可能会过早填充Btrfs文件系统,并导致Docker主机空间不足。使用btrfs filesys show您必须密切监控增加了Btrfs设备上的可用空间量。

  • 顺序写入。Btrfs在写入磁盘时使用日记技术。这可能会影响顺序写入的性能,从而使性能降低多达50%。

  • 碎片化。碎片是Btrfs等写时复制文件系统的自然副产品。许多小的随机写操作可能会使这个问题复杂化。使用SSD时,碎片可能表现为CPU峰值,而使用旋转磁盘时,则表现为磁头抖动。这些问题中的任何一个都可能损害性能。

    如果您的Linux内核版本是3.9或更高版本,则autodefrag 在安装Btrfs卷时可以启用该功能。在将该功能部署到生产中之前,请先对您的工作负载进行测试,因为某些测试显示了对性能的负面影响。

  • SSD性能:Btrfs包括针对SSD介质的本机优化。要启用这些功能,请使用-o ssdmount选项安装Btrfs文件系统。这些优化通过避免优化(例如不适用于固态介质的寻道优化)来增强SSD的写入性能。

  • 经常平衡Btrfs文件系统cron在非高峰时段,使用操作系统实用程序(例如 作业)定期平衡Btrfs文件系统。这样可以回收未分配的块,并有助于防止文件系统不必要地填满。除非您向文件系统中添加其他物理块设备,否则您无法重新平衡完全完整的Btrfs文件系统。请参阅 BTRFS Wiki

  • 使用快速存储:固态驱动器(SSD)提供比旋转磁盘更快的读写速度。

  • 将卷用于繁重的写工作负载:卷可为繁重的写工作负载提供最佳和最可预测的性能。这是因为它们绕过了存储驱动程序,并且不会产生任何精简配置和写时复制所带来的潜在开销。卷还有其他好处,例如,允许您在容器之间共享数据,并且即使没有正在运行的容器正在使用它们也可以持久保存数据。

集装箱仓储驱动Btrfs