Docker插件,用于管理Docker卷作为BTRFS子卷
项目描述
BTRFS卷插件用于Docker
Buttervolume能为您做什么?
在您的网站或应用程序遭到攻击或失败后,快速恢复最近的数据
在升级失败后,快速将数据回滚到之前的版本
无需担忧,自动升级您的应用程序
保留您数据的历史记录
创建大量备份,而不会占用比所需更多的磁盘空间
构建具有数据复制的弹性托管集群
快速在不同节点之间移动您的应用程序
创建预配置或模板化应用程序,可在几秒钟内部署
Buttervolume能做什么?
快照您的Docker卷
将快照恢复到其原始卷或新的卷下
列出并删除您卷的现有快照
克隆您的Docker卷
将您的卷复制或同步到另一台主机
计划定期快照、同步或复制您的卷
计划定期删除您的旧快照
它是如何工作的?
Buttervolume是一个Docker卷插件,位于BTRFS分区之上,可以管理和复制Docker卷的BTRFS快照。
简介
BTRFS 是一个下一代写时复制文件系统,具有子卷和快照支持。BTRFS 子卷 可以被视为一个独立的文件命名空间,它可以存在于一个目录中,并且可以作为一个独立的文件系统进行挂载,还可以单独进行快照。
另一方面,Docker卷 通常用于存储有状态容器的持久数据,如MySQL/PostgreSQL数据库或CMS的上传目录。默认情况下,Docker卷只是主机文件系统中的本地目录。已经存在许多 卷插件,用于各种存储后端,包括分布式文件系统,但小型集群通常负担不起部署分布式文件系统。
我们认为BTRFS子卷是Docker卷的一个强大且轻量级的存储解决方案,允许在小集群的多个节点之间快速轻松地进行复制(和备份)。
先决条件
请确保目录 /var/lib/buttervolume/ 位于一个BTRFS文件系统中。它可以是BTRFS挂载点或BTRFS子卷,也可以两者都是。
您还应该在主机上创建配置和ssh目录
sudo mkdir /var/lib/buttervolume sudo mkdir /var/lib/buttervolume/config sudo mkdir /var/lib/buttervolume/ssh
作为贡献者构建和运行
如果您想成为贡献者,请阅读本章。否则,跳到下一节。
您首先需要使用提供的Dockerfile为插件创建一个根文件系统
git clone https://github.com/anybox/buttervolume ./build.sh
默认情况下,插件是为最新提交(HEAD)构建的。您可以通过指定如下来构建另一个版本
./build.sh 3.7
在此阶段,您可以通过运行以下命令为插件设置SSH_PORT选项
docker plugin set anybox/buttervolume SSH_PORT=1122
请注意,此选项仅在使用两个节点之间的复制功能时相关。
现在您可以启用插件,它应该在插件容器中启动buttervolume
docker plugin enable anybox/buttervolume:HEAD
您可以通过运行buttervolume命令来检查它是否响应
export RUNCROOT=/run/docker/runtime-runc/plugins.moby/ # or /run/docker/plugins/runtime-root/plugins.moby/ alias drunc="sudo runc --root $RUNCROOT" alias buttervolume="drunc exec -t $(drunc list|tail -n+2|awk '{print $1}') buttervolume" sudo buttervolume scheduled
通过编写一个 /var/lib/buttervolume/config/config.ini 文件来增加日志级别
[DEFAULT] TIMER = 120
然后通过以下命令检查日志
sudo journalctl -f -u docker.service
您还可以使用以下命令在本地以守护进程模式安装和运行插件
python3 -m venv venv ./venv/bin/python setup.py develop sudo ./venv/bin/buttervolume run
然后您可以使用在venv中以开发者模式安装的buttervolume CLI
./venv/bin/buttervolume --version
作为用户安装和运行
如果插件已经推送到镜像仓库,您可以使用以下命令安装它
docker plugin install anybox/buttervolume
检查它是否正在运行
docker plugin ls
找到您的runc根,然后定义有用的别名
export RUNCROOT=/run/docker/runtime-runc/plugins.moby/ # or /run/docker/plugins/runtime-root/plugins.moby/ alias drunc="sudo runc --root $RUNCROOT" alias buttervolume="drunc exec -t $(drunc list|tail -n+2|awk '{print $1}') buttervolume"
然后尝试一个buttervolume命令
buttervolume scheduled
或使用驱动程序创建卷。注意,驱动程序的名称就是插件的名称
docker volume create -d anybox/buttervolume:latest myvolume
请注意,您也可以定义函数而不是使用别名,并将这些函数放在您的 .bash_profile 或 .bash_aliases 中
function drunc () { RUNCROOT=/run/docker/runtime-runc/plugins.moby/ # or /run/docker/plugins/runtime-root/plugins.moby/ sudo runc --root $RUNCROOT $@ } function buttervolume () { drunc exec -t $(docker plugin ls --no-trunc | grep 'anybox/buttervolume:latest' | awk '{print $1}') buttervolume $@ }
升级
在重新安装之前,您必须强制禁用它(如docker文档中所述)
docker plugin disable -f anybox/buttervolume docker plugin rm -f anybox/buttervolume docker plugin install anybox/buttervolume
配置
您可以配置以下变量
DRIVERNAME:驱动程序的全名(带有标签)
VOLUMES_PATH:BTRFS卷所在的路径
SNAPSHOTS_PATH:BTRFS快照所在的路径
TEST_REMOTE_PATH:单元测试期间远程BTRFS快照所在的路径
SCHEDULE:调度器配置的路径
RUNPATH:docker run目录的路径 (/run/docker)
SOCKET:buttervolume 监听的 UNIX 套接字路径
TIMER:调度器两次运行之间的秒数
DTFORMAT:日志中日期时间的格式
LOGLEVEL:Python 日志级别(INFO、DEBUG 等)
配置可以按照以下优先级顺序进行
从以 BUTTERVOLUME_ 为前缀的环境变量(例如:BUTTERVOLUME_TIMER=120)
从容器内部的 /etc/buttervolume/config.ini 文件中的 [DEFAULT] 部分,或主机上的 /var/lib/buttervolume/config/config.ini
config.ini 文件示例
[DEFAULT] TIMER = 120
如果没有配置上述任何内容,则使用以下默认值
DRIVERNAME = anybox/buttervolume:latest
VOLUMES_PATH = /var/lib/buttervolume/volumes/
SNAPSHOTS_PATH = /var/lib/buttervolume/snapshots/
TEST_REMOTE_PATH = /var/lib/buttervolume/received/
SCHEDULE = /etc/buttervolume/schedule.csv
RUNPATH = /run/docker
SOCKET = $RUNPATH/plugins/btrfs.sock # 仅当手动运行时
TIMER = 60
DTFORMAT = %Y-%m-%dT%H:%M:%S.%f
LOGLEVEL = INFO
使用
运行插件
正常运行方式是将它作为上述“安装和运行”部分中描述的新式 Docker 插件运行,这将自动启动它。这将创建一个 /run/docker/plugins/<uuid>/btrfs.sock 文件,由 Docker 守护进程使用。其中 <uuid> 是运行它的 runc/OCI 容器的唯一标识符。这意味着您可能可以同时运行该插件的多个版本,但目前不建议这样做,除非您记住不同版本的卷和快照位于同一位置。否则,您可以使用 config.ini 文件为每个不同版本的卷和快照配置不同的路径。
卷驱动程序的名称是插件的名称
docker volume create -d anybox/buttervolume:latest myvolume
或
docker volume create --volume-driver=anybox/buttervolume:latest
在创建卷时,您可以选择按卷禁用写时复制。只需使用 -o 或 –opt 选项,如 Docker 文档 中定义的那样
docker volume create -d anybox/buttervolume -o copyonwrite=false myvolume
在本地或旧模式运行插件
如果您将其作为 Python 发行版本地安装,也可以使用以下命令手动启动:
sudo buttervolume run
在这种情况下,它将在 /run/docker/plugins/btrfs.sock 中创建一个 UNIX 套接字,供 Docker 使用传统的插件系统。然后,卷驱动程序的名称是套接字文件的名称
docker volume create -d btrfs myvolume
或
docker create --volume-driver=btrfs
启动时,插件还将启动自己的调度器以运行定期作业(如快照、复制、清理或同步)
创建和删除卷
一旦插件开始运行,您就可以在创建容器时指定卷驱动程序,使用 docker create --volume-driver=btrfs --name <name> <image>。您也可以使用 docker volume create -d btrfs 手动创建 BTRFS 卷。它也适用于 docker-compose,通过在 compose 文件的 volumes 部分指定 btrfs 驱动程序
当您使用 docker rm -v <container> 或 docker volume rm <volume> 删除卷时,BTRFS 子卷将被删除。如果在同时期间在卷的其他位置进行了快照,快照不会被删除。
管理卷和快照
当安装 buttervolume 时,它提供了一个命令行工具 buttervolume,以下为子命令
run Run the plugin in foreground snapshot Snapshot a volume snapshots List snapshots schedule (un)Schedule a snapshot, replication or purge scheduled List scheduled actions restore Restore a snapshot (optionally to a different volume) clone Clone a volume as new volume send Send a snapshot to another host sync Synchronise a volume from a remote host volume rm Delete a snapshot purge Purge old snapshot using a purge pattern
创建快照
您可以使用以下命令为卷创建只读快照
buttervolume snapshot <volume>
卷当前预计位于 /var/lib/buttervolume/volumes,快照将在 /var/lib/buttervolume/snapshots 创建,通过将日期时间附加到卷名,并用 @ 分隔。
列出快照
您可以列出所有快照
buttervolume snapshots
或只列出与某个卷对应的快照
buttervolume snapshots <volume>
<volume> 是卷名,不是完整路径。它预期位于 /var/lib/buttervolume/volumes。
恢复快照
您可以将快照恢复为卷。首先快照当前卷,然后删除,最后用快照替换。如果您提供的是卷名而不是快照,则将恢复最新的快照。因此,如果您操作错误,不会丢失数据。请在恢复快照之前停止容器
buttervolume restore <snapshot>
<snapshot> 是快照名,不是完整路径。它预期位于 /var/lib/buttervolume/snapshots。
默认情况下,卷名与创建快照的卷对应。但您可以通过添加目标作为第二个参数,选择性地将快照恢复到不同的卷名
buttervolume restore <snapshot> <volume>
克隆卷
您可以将卷克隆为新的卷。当前卷将被克隆为作为参数给出的新卷名。请在克隆卷之前停止容器
buttervolume clone <volume> <new_volume>
<volume> 是要克隆的卷名,不是完整路径。它预期位于 /var/lib/buttervolume/volumes。 <new_volume> 是新卷的名称,它将作为前一个卷的克隆创建,不是完整路径。它预期在 /var/lib/buttervolume/volumes 中创建。
删除快照
您可以使用以下命令删除快照
buttervolume rm <snapshot>
<snapshot> 是快照名,不是完整路径。它预期位于 /var/lib/buttervolume/snapshots。
将快照复制到另一个主机
您可以将快照增量发送到另一台主机,这样数据就会被复制到多台机器上,允许快速将有状态的Docker容器移动到另一台主机。第一个快照首先整体发送,然后使用后续的快照仅发送当前快照与上一个快照之间的差异。这允许频繁复制快照而不会消耗大量的带宽或磁盘空间
buttervolume send <host> <snapshot>
<snapshot> 是快照名,不是完整路径。它预期位于 /var/lib/buttervolume/snapshots 并在远程主机上的相同路径进行复制。
<host> 是远程主机的计算机名或IP地址。快照当前使用通过ssh的BTRFS send/receive发送,插件中直接包含ssh服务器。这要求目标主机上存在ssh密钥,并且已在 /var/lib/buttervolume/ssh 下授权,并且本地主机上的 /var/lib/buttervolume/ssh/config 中启用了 StrictHostKeyChecking no 选项。
请注意,每次您更改ssh配置时,都必须重新启动您的docker守护进程。
插件中包含的ssh服务器的默认SSH_PORT是 1122。您可以在启用插件之前使用 docker plugin set anybox/buttervolume SSH_PORT=<PORT> 来更改它。
从另一个主机的卷同步卷
您可以从远程卷接收数据,因此在远程主机上存在具有相同名称的卷时,它将从远程卷获取最新和最新的数据,并将其替换为本地卷中的数据。在运行 rsync 命令之前,将在本地机器上创建快照以进行恢复管理
buttervolume sync <volume> <host1> [<host2>][...]
目的是在运行容器之间的多主机之间同步卷,因此您应该在所有远程主机上的每个节点上安排此操作。
清除旧快照
您可以使用保留模式删除与指定卷对应的旧快照。
buttervolume purge <pattern> <volume>
如果您不确定保留模式是否正确,可以使用--dryrun选项运行清除,以检查将删除哪些快照,而不删除它们。
buttervolume purge --dryrun <pattern> <volume>
<volume> 是卷名,不是完整路径。它预期位于 /var/lib/buttervolume/volumes。
<pattern>是快照保留模式。它是一个由分号分隔的时间长度指定器的列表,带有单位。单位可以是m(分钟)、h(小时)、d(天)、w(周)、y(年)。模式应至少包含2项。
以下是一些保留模式的示例
- 4h:1d:2w:2y
保留最后四小时内的所有快照,然后在第一天每小时保留一个快照,然后在前两周每天保留一个快照,然后在第一年每两周保留一个快照,两年后删除所有内容。
- 4h:1w
保留最后四小时内的所有快照,然后在第一周每小时保留一个快照,然后删除较旧的快照。
- 2h:2h
保留最后两小时内的所有快照,然后删除较旧的快照。
安排作业
您可以安排定期任务,如快照、复制、同步或清除。计划本身存储在/etc/buttervolume/schedule.csv中。
每60分钟安排卷的快照
buttervolume schedule snapshot 60 <volume>
通过指定0分钟的时间器来删除相同的计划
buttervolume schedule snapshot 0 <volume>
安排将卷foovolume复制到remote_host
buttervolume schedule replicate:remote_host 3600 foovolume
删除相同的计划
buttervolume schedule replicate:remote_host 0 foovolume
每小时安排清除卷foovolume的快照,但保留最后4小时内的所有快照,然后在前一周每小时保留一个快照,然后在一年内每周保留一个快照,一年后删除所有快照
buttervolume schedule purge:4h:1w:1y 60 foovolume
删除相同的计划
buttervolume schedule purge:4h:1w:1y 0 foovolume
通过使用快照计划计时器、清除计划计时器和清除保留模式的正确组合,您可以创建自己的备份策略,从最简单的到更复杂的。一个常见的是以下内容
buttervolume schedule snapshot 1440 <volume> buttervolume schedule purge:1d:4w:1y 1440 <volume>
它应该每天创建一个快照,然后每天清除快照,同时保留最后24小时内的所有快照,然后在一个月内每天保留一个快照,然后在一年内每月保留一个快照。
安排从remote_host1和remote_host2同步卷foovolume
buttervolume schedule synchronize:remote_host1,remote_host2 60 foovolume
删除相同的计划
buttervolume schedule synchronize:remote_host1,remote_host2 0 foovolume
列出安排的作业
您可以使用以下命令列出所有计划的任务
buttervolume scheduled
它将以添加计划时使用的相同格式显示计划,这便于删除现有计划或添加类似的新计划。
写时复制
默认启用Copy-On-Write。如果您真的想禁用它,可以禁用它。
为什么要禁用Copy-On-Write?如果您存储数据库的Docker卷,例如PostgreSQL或MariaDB,Copy-On-Write功能可能会影响性能,尽管最新的内核已经做了很多改进。好消息是禁用Copy-On-Write不会阻止创建快照。
测试
如果您的卷目录是BTRFS分区或卷,可以使用以下命令进行测试
./test.sh
在没有BTRFS分区的情况下工作
如果您没有BTRFS分区或卷,您可以按照以下方式设置文件中的虚拟分区(在Debian 8上进行了测试)
设置BTRFS虚拟分区
sudo qemu-img create /var/lib/docker/btrfs.img 10G sudo mkfs.btrfs /var/lib/docker/btrfs.img
将分区临时挂载到某个位置以创建3个新的BTRFS子卷
sudo -s mkdir /tmp/btrfs_mount_point mount -o loop /var/lib/docker/btrfs.img /tmp/btrfs_mount_point/ btrfs subvolume create /tmp/btrfs_mount_point/snapshots btrfs subvolume create /tmp/btrfs_mount_point/volumes btrfs subvolume create /tmp/btrfs_mount_point/received umount /tmp/btrfs_mount_point/ rm -r /tmp/btrfs_mount_point/
停止docker,创建所需的挂载点并重新启动docker
systemctl stop docker mkdir -p /var/lib/buttervolume/volumes mkdir -p /var/lib/buttervolume/snapshots mkdir -p /var/lib/buttervolume/received mount -o loop,subvol=volumes /var/lib/docker/btrfs.img /var/lib/buttervolume/volumes mount -o loop,subvol=snapshots /var/lib/docker/btrfs.img /var/lib/buttervolume/snapshots mount -o loop,subvol=received /var/lib/docker/btrfs.img /var/lib/buttervolume/received systemctl start docker
完成测试后,您可以卸载这些卷,您将找到之前的docker卷
systemctl stop docker umount /var/lib/buttervolume/volumes umount /var/lib/buttervolume/snapshots umount /var/lib/buttervolume/received systemctl start docker rm /var/lib/docker/btrfs.img
迁移到版本3
如果您目前在生产中使用Buttervolume 1.x或2.0,您必须仔细遵循以下指南以迁移到版本3。
首先复制ssh和配置文件,并禁用调度器
sudo -s docker cp buttervolume_plugin_1:/etc/buttervolume /var/lib/buttervolume/config docker cp buttervolume_plugin_1:/root/.ssh /var/lib/buttervolume/ssh mv /var/lib/buttervolume/config/schedule.csv /var/lib/buttervolume/config/schedule.csv.disabled
然后停止所有容器,除了buttervolume
现在快照并删除所有卷
volumes=$(docker volume ls -f driver=btrfs --format "{{.Name}}") # or: # volumes=$(docker volume ls -f driver=btrfs|tail -n+2|awk '{print $2}') echo $volumes for v in $volumes; do docker exec buttervolume_plugin_1 buttervolume snapshot $v; done for v in $volumes; do docker volume rm $v; done
然后停止buttervolume容器,删除旧的btrfs.sock文件,并重新启动docker
docker stop buttervolume_plugin_1 docker rm -v buttervolume_plugin_1 rm /run/docker/plugins/btrfs.sock systemctl stop docker
如果您之前使用的是Buttervolume 1.x,您必须将快照移动到新位置
mkdir /var/lib/buttervolume/snapshots cd /var/lib/docker/snapshots for i in *; do btrfs subvolume snapshot -r $i /var/lib/buttervolume/snapshots/$i; done
将/var/lib/docker/volumes恢复为原始文件夹
cd /var/lib/docker mkdir volumes.new mv volumes/* volumes.new/ umount volumes # if this was a mounted btrfs subvolume mv volumes.new/* volumes/ rmdir volumes.new systemctl start docker
将您的卷配置(在您的compose文件中)更改为使用新的anybox/buttervolume:latest驱动程序名称,而不是btrfs
然后以管理插件的形式启动新的buttervolume 3.x并检查它是否已启动
docker plugin install anybox/buttervolume:latest docker plugin ls
然后使用新驱动程序重新创建所有卷并从快照中恢复它们
for v in $volumes; do docker volume create -d anybox/buttervolume:latest $v; done export RUNCROOT=/run/docker/runtime-runc/plugins.moby/ # or /run/docker/plugins/runtime-root/plugins.moby/ alias drunc="sudo runc --root $RUNCROOT" alias buttervolume="drunc exec -t $(drunc list|tail -n+2|awk '{print $1}') buttervolume" # WARNING : check the the volume you will restore are the correct ones for v in $volumes; do buttervolume restore $v; done
然后重新启动您的容器,检查它们是否具有正确的数据
重新启用调度器
mv /var/lib/buttervolume/config/schedule.csv.disabled /var/lib/buttervolume/config/schedule.csv
鸣谢
感谢
Christophe Combelles
Pierre Verkest
Marcelo Ochoa
Christoph Rist
Philip Nagler-Frank
Yoann MOUGNIBAS
变更日志
3.10 (2023-04-09)
更新依赖项
修复bug #45
3.9 (2022-10-11)
修复了未设置option_copyonwrite时的崩溃问题
恢复了测试套件
改进并简化了构建脚本和测试脚本
3.8 (2022-10-07)
默认使用copy-on-write
允许选择为每个卷启用/禁用copy-on-write
允许在插件配置中更改默认的SSH_PORT
更新了基本docker镜像和依赖项
添加了显示版本号的选项
改进了文档
3.7 (2018-12-13)
取消固定urllib3
3.6 (2018-12-11)
修复了插件内的僵尸sshd进程
较小的文档更改
3.5 (2018-06-07)
改进了文档
3.4 (2018-04-27)
在启动时修复权限,以便ssh可以工作
3.3 (2018-04-27)
修复了防止在某些条件下启动的bug
3.2 (2018-04-27)
修复了启动时的套接字路径
3.1 (2018-04-27)
修复了Python 3.6中的声明问题
自动检测btrfs.sock路径
使runpath和drivername可配置
3.0 (2018-04-24)
现在使用docker managed plugin系统
在关闭前停止调度器以避免5秒超时
改进了日志记录
改进了从版本1或2迁移的文档
2.0 (2018-03-24)
- 重大更改:请阅读从版本1到版本2的迁移路径
BTRFS卷和快照现在默认存储在/var/lib/buttervolume下的不同目录中
配置可以通过环境变量或config.ini文件进行
实现了VolumeDriver.Capabilities并仅返回'local'
其他一些小修复和改进
1.4 (2018-02-01)
添加克隆命令
用btrfs filesystem sync替换sync
1.3.1 (2017-10-22)
修复了打包(缺少README)
1.3 (2017-07-30)
修复了恢复命令的cli
1.2 (2017-07-16)
修复了清除算法
1.1 (2017-07-13)
允许将快照恢复到不同的卷名称
1.0 (2017-05-24)
初始发布,用于生产
项目详情
下载文件
下载适用于您平台的自定义文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源码分发
构建分发
buttervolume-3.10.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d6529b4060cb331846081c89f7e455fc7452e466253480f065c21e7e3024595d |
|
MD5 | 4ada1f0bd5c6dc72cb1cffd66ab8de8b |
|
BLAKE2b-256 | ba3644ba9f9b3853ffceb43736d85da7e7f375f72362e8579f9893cb4a7d104a |
buttervolume-3.10-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 43ee2b5c6a43a658f34559c2ab4be4dd745b2028f5e9d01739306b56fb0eac70 |
|
MD5 | e85d076520b5addf93ecb64a8e403858 |
|
BLAKE2b-256 | eb545406e85cfc3bb0c9e737ad3cbfc0e5d9c4e188ab535d567981c660d0b080 |