Docker ZFS 存储驱动

ZFS 是(伟大的)Sun Microsystems创建并在CDDL许可下开源的下一代(超越同时代)文件系统( ZFS历史 )。在ZFS首次发布就支持众多高级 ZFS特性 ,并且不断持续开发,已经成为现有本地文件系统中最强大的一种。

Docker使用ZFS的先决条件

要求:

  • Docker需要一个或多个 专用 块设备,建议使用固态存储器(SSD)

  • Docker所使用的ZFS必须是独立的ZFS文件系统: /var/lib/docker/ 目录是ZFS的zpool存储池

  • 警告 : 更改 Docker存储驱动 会导致已经创建的任何容器都无法在本地系统访问。所以在执行本文实践前,务必将本地现有镜像保存备份(推送到镜像库)!!!

备注

挂在磁盘参数不需要使用 MountFlags=slave ,原因是 dockerdcontainerd运行时(runtime) 位于不同的挂载namespace。

部署

备注

X86移动云ZFS 是我在X86_64 的 Macbook Pro 2013笔记本上部署,分区和挂载略有差异

  • 停止Docker:

停止Docker服务,为存储驱动修改做准备
sudo systemctl stop docker
sudo systemctl stop docker.socket
  • /var/lib/docker 备份并清理该目录下所有内容:

备份/var/lib/docker目录
sudo cp -au /var/lib/docker /var/lib/docker.bk
sudo rm -rf /var/lib/docker
  • ZFS管理准备 好的分区 /dev/nvme0n1p8 上构建 zpool 并挂载到 /var/lib/docker/ 目录(开启 ZFS压缩 ):

zpool create创建名为zpool-docker存储池
# 在NVMe 分区8创建zpool
sudo zpool create -f zpool-docker -m /var/lib/docker /dev/nvme0n1p9

# 存储池开启压缩,2015年后openzfs默认压缩算法LZ4,这里明确设置lz4
sudo zfs set compression=lz4 zpool-docker
  • 此时检查zfs存储可以看到上述名为 zpool-docker 的存储池:

zfs list检查存储
sudo zfs list

输出显示如下:

zfs list检查存储显示zpool-docker
NAME           USED  AVAIL     REFER  MOUNTPOINT
zpool-docker   432K   103G       96K  /var/lib/docker
  • 修改 /etc/docker/daemon.json 添加zfs配置项(如果该配置文件不存在则创建并添加如下内容):

/etc/docker/daemon.json 添加ZFS存储引擎配置
{
  "storage-driver": "zfs"
}
  • 启动Docker并检查Docker配置:

启动Docker并检查 docker info
sudo systemctl start docker
sudo docker info

docker info 输出显示如下:

docker info显示使用了ZFS存储(启用压缩)
Client:
 Context:    default
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 20.10.21
 Storage Driver: zfs
  Zpool: zpool-docker
  Zpool Health: ONLINE
  Parent Dataset: zpool-docker
  Space Used By Parent: 544768
  Space Available: 110292873216
  Parent Quota: no
  Compression: lz4
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1c90a442489720eec95342e1789ee8a5e1b9536f.m
 runc version: 
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.19.0-asahi-5-1-ARCH
 Operating System: Arch Linux ARM
 OSType: linux
 Architecture: aarch64
 CPUs: 10
 Total Memory: 31.17GiB
 Name: alarm
 ID: ILQJ:JYNV:6QP7:FTWB:VABD:2ZBQ:HWBA:PDDT:PXL3:GUX5:V3MO:OKV5
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

备注

这里我遇到一个问题,主机断电后重启zfs没有恢复。解决方法: 配置ZFS自动启动

维护

  • 增加ZFS存储池容量(案例参考):

    sudo zpool add zpool-docker /dev/xvdh
    
  • 限制容器可写入存储quota(限制每个容器能够占用的写入层容量),修订 /etc/docker/daemon.json 配置:

/etc/docker/daemon.json 配置ZFS存储引擎允许容器写入层大小
{
  "storage-driver": "zfs",
  "storage-opts": ["size=256M"]
}

zfs 存储驱动工作原理

待续...

参考