- 云原生
- 存储
- 高可用
- 容器编排
【免费下载链接】longhorn
Cloud-Native distributed storage built on and for Kubernetes
导读
本文围绕 Longhorn 的 BackingImage 增强特性展开,聚焦三项核心能力:通过副本数(HA)避免 BackingImage 数据丢失、通过nodeSelector与diskSelector将 BackingImage 精准调度到指定节点与磁盘、以及通过驱逐(Eviction)机制在节点或磁盘下线前主动迁移 BackingImage。读者读完本文后,将掌握如何在 Longhorn 中为 BackingImage 配置副本数量与调度约束、如何结合 Kubernetes 标签实施节点/磁盘定向存储、以及如何在节点排空(drain)前安全触发驱逐以保障数据可用性。
该特性源自 Longhorn 社区增强提案 enhancements/20240426-backing-image-enhancement.md,对应的功能设计目标源自 longhorn/longhorn#2856 与 longhorn/longhorn#6526(此处仅作为背景说明,不展开外部链接)。
特性总览
BackingImage 是 Longhorn 中用于预置磁盘镜像(如虚拟机镜像、操作系统镜像)的机制,Volume 创建时可直接以该镜像为模板,无需重复下载。原实现中 BackingImage 仅有一个副本,副本所在节点宕机或节点被排空时,唯一的 BackingImage 副本会丢失,用户需要重新准备镜像。
本增强特性在 Longhorn 中引入三项能力:
- 高可用(HA):通过
numOfCopies/minNumberOfCopies维护集群内 BackingImage 副本数量,副本数不足时自动补足,副本多余且长期未被使用时自动清理。 - 节点/磁盘选择器(nodeSelector / diskSelector):将 BackingImage 副本精准调度到具备指定标签(tag)的节点与磁盘,与 Volume Replica 的调度保持一致,提升空间利用率。
- 驱逐处理(Eviction):用户对节点或磁盘手动设置驱逐请求后,Longhorn 将 BackingImage 副本迁移到其他节点或磁盘。
以下各节分别深入这三项能力的设计、CRD 变化、控制器实现与测试方案。
高可用(HA):维护 BackingImage 副本数
设计目标
- 用户可设置全局的高可用因子(对所有 BackingImage 生效),也可为单个 BackingImage 单独指定副本数。
- Longhorn 在集群内持续维护 BackingImage 的副本数量。
- 当副本数超过因子、且多余副本一段时间内未被使用时,Longhorn 自动删除多余的副本。
CRD 变更
在 BackingImage CRD 中新增minNumberOfCopies字段。从当前仓库的 CRD 定义(deploy/longhorn.yaml)可以看到 BackingImage 的spec结构:
# deploy/longhorn.yaml 中 BackingImage CRD 的 spec 片段 spec: properties: checksum: type: string dataEngine: default: v1 enum: - v1 - v2 diskFileSpecMap: additionalProperties: properties: dataEngine: enum: [v1, v2] evictionRequested: type: boolean diskSelector: items: {type: string} type: array minNumberOfCopies: type: integer nodeSelector: items: {type: string} type: array sourceType: enum: [download, upload, export-from-volume, restore, clone]可见minNumberOfCopies与nodeSelector、diskSelector、evictionRequested均已在 CRD 中落地,disks字段被标注为 Deprecated(已由diskFileSpecMap取代)。
BackingImage Controller 的副本维护逻辑
- 当第一个 BackingImage 副本就绪后,控制器开始维护集群中的副本数量。
- 若副本数低于设定值,控制器挑选一个合法的节点与磁盘,每次增加一个副本,直至副本数达到或超过设定值。
- 若副本数高于设定值,且多余副本一段时间内未被使用(受
Backing Image Cleanup Wait Interval控制),Longhorn 删除这些未使用的副本。该清理逻辑在原提案中已有实现参考(对应 longhorn-manager v1.6.1 的 node_controller.go#L1152 的backingImageCleanupWaitInterval设置项)。
相关全局设置
在 Helm Chart 的 values.yaml 中,BackingImage 相关的 StorageClass 设置如下:
backingImage: # -- 在 Longhorn StorageClass 中使用 backing image enable: false # -- 用于创建和恢复 Volume 的 backing image 名称 name: ~ # -- backing image 的数据源类型(如 download) dataSourceType: ~ # -- 数据源参数,JSON 字符串形式的 map # 示例: '{"url":"https://backing-image-example.s3-region.amazonaws.com/test-backing-image"}' dataSourceParameters: ~ # -- backing image 的预期 SHA-512 checksum expectedChecksum: ~清理间隔设置位于 values.yaml:
# -- 当磁盘上没有 replica 使用 backing image 文件时,Longhorn 等待多少分钟后清理该文件 backingImageCleanupWaitInterval: ~ # -- 当所有镜像磁盘文件状态变为 failed 或 unknown 时,Longhorn 等待多少秒后重新下载 backingImageRecoveryWaitInterval: ~nodeSelector 与 diskSelector:定向调度 BackingImage
设计目标
- 用户创建 BackingImage 时可通过
nodeSelector和diskSelector指定目标节点与磁盘。 - BackingImage 副本只放置在带有对应标签(tag)的节点和磁盘上。
- 当节点或磁盘被禁用调度时,BackingImage 副本无法被放置在该节点或磁盘上。
- Replica 无法被调度到无法存储对应 BackingImage 的节点和磁盘上。
与 Volume Replica 调度的一致性
原实现中,Longhorn 将 BackingImage 副本随机放置在节点和磁盘上;当某个 Replica 需要该 BackingImage 时,Longhorn 必须把 BackingImage 复制到 Replica 所在的磁盘。引入选择器后,只要 Replica 与 BackingImage 使用相同的nodeSelector和diskSelector,BackingImage 与 Replica 将存储在相同的节点和磁盘集合中,从而避免跨磁盘复制,显著提升空间利用效率。
调度逻辑
- BackingImage Controller 选择节点/磁盘时,遵循
diskSelector与nodeSelector设置。 - Replica Scheduler 在评估节点候选与磁盘候选时,会额外检查该节点/磁盘是否可用于 Replica 所使用的 BackingImage。若 BackingImage 无法存储在该节点或磁盘上,则 Replica 也不会被调度到该节点。
驱逐处理(Eviction):主动迁移 BackingImage
设计目标
当用户对节点或磁盘设置驱逐请求(evictionRequested = true)时,Longhorn 将 BackingImage 副本迁移到其他节点或磁盘。该能力仅在用户手动设置驱逐请求时生效;节点 cordon 或 drain 时 Longhorn 不会自动驱逐 BackingImage(与 Replica 的自动驱逐行为不同)。原因是自动驱逐需要为 BackingImageManager 配置 PodDisruptionBudget(PDB),会增加流程复杂度并引入卡住风险。因此,用户应在 drain 节点前先手动设置驱逐请求。
CRD 变更
BackingImage Spec 由原来的Disks map[string]string扩展为Disks map[string]*BackingImageDiskFileSpec,其中新增EvictionRequested字段:
// 变更前 type BackingImageSpec struct { Disks map[string]string `json:"disks"` Checksum string `json:"checksum"` SourceType BackingImageDataSourceType `json:"sourceType"` SourceParameters map[string]string `json:"sourceParameters"` } // 变更后 type BackingImageSpec struct { Disks map[string]*BackingImageDiskFileSpec `json:"disks"` Checksum string `json:"checksum"` SourceType BackingImageDataSourceType `json:"sourceType"` SourceParameters map[string]string `json:"sourceParameters"` } type BackingImageDiskFileSpec struct { EvictionRequested bool `json:"evictionRequested"` }在 deploy/longhorn.yaml 中,diskFileSpecMap的 schema 已体现evictionRequested布尔字段;节点 CRD 中同样包含节点级evictionRequested(deploy/longhorn.yaml)以及磁盘级evictionRequested(deploy/longhorn.yaml)。
控制器实现
Node Controller
当节点或磁盘被设置为evictionRequested = true时,Node Controller 会将该节点上所有 BackingImage 副本的EvictionRequested更新为 true。
BackingImage Controller
核心方法为replenishBackingImageCopies()与cleanupEvictionRequestedBackingImageCopies():
replenishBackingImageCopies():- 若
nonFailedCopies >= MinNumberOfCopies,检查是否需要为驱逐补充副本:当NonEvictingCount < MinNumberOfCopies时补充一个副本。 - 若
nonFailedCopies < MinNumberOfCopies,补充一个副本以满足MinNumberOfCopies要求。
- 若
cleanupEvictionRequestedBackingImageCopies():- 若没有非驱逐的健康副本,则不删除被驱逐的副本(避免唯一副本被删除)。
- 否则删除被驱逐的副本。
测试方案
原提案给出了 5 组测试用例,以下结合预期行为整理为可复现的验证清单:
- HA 副本数维护:创建
minNumberOfCopies = 2的 BackingImage → 创建后立即同步文件到另一个节点/磁盘 → 将Backing Image Cleanup Wait Interval更新为 1 分钟 → 将minNumberOfCopies更新为 1 → 多余的 BackingImage 副本被清理。 - nodeSelector/diskSelector 定向放置:为 node1 设置
nodeTag: [node1], diskTag: [disk1]→ 创建minNumberOfCopies = 2、nodeSelector = [node1]、diskSelector = [disk1]的 BackingImage → 第一个副本落在 node1/disk1 → 第二个副本始终不出现,日志显示unable to get a ready node disk。 - 与 Replica 选择器不一致(负向测试):node1/disk1 设置
nodeTag: [node1], diskTag: [disk1],node2/disk2 设置nodeTag: [node2], diskTag: [disk2]→ 创建minNumberOfCopies = 1、nodeSelector = [node1]、diskSelector = [disk1]的 BackingImage → 创建numberOfReplicas = 1、nodeSelector = [node2]、diskSelector = [disk2]的 Volume 并附加到 node2 → Volume 的Scheduled条件为false,因为 Replica 无法被调度。 - 驱逐 - 1:创建只有 1 个副本的 BackingImage → 驱逐副本所在节点 → 先在另一个节点创建副本 → 被驱逐的副本被删除。
- 驱逐 - 2:设置
minNumberOfCopies = 1→ 创建 2 个副本的 BackingImage → 驱逐其中一个副本所在节点 → 被驱逐的副本被删除(不补充新副本)。 - 驱逐 - 3(负向测试):设置
nodeTag: [node1], diskTag: [disk1]→ 创建minNumberOfCopies = 1、nodeSelector = [node1]、diskSelector = [disk1]的 BackingImage(副本在 node1)→ 驱逐 node1 → 由于它是唯一副本且受选择器限制无法复制到其他节点,该副本不会被删除。
升级策略
原提案指出本特性的升级策略为None:无需额外的数据迁移或版本升级步骤,特性随 Longhorn Manager 升级自动生效。新增字段(minNumberOfCopies、nodeSelector、diskSelector、diskFileSpecMap)均由控制器以默认值/空值兼容旧对象,不破坏既有 BackingImage。
实践要点与注意事项
- 驱逐与节点维护的配合:Longhorn 不会在节点 cordon/drain 时自动驱逐 BackingImage,因此节点维护前需先在 Longhorn UI 或 API 中对目标节点/磁盘设置
evictionRequested,等待 BackingImage 迁移完成后再执行 drain。 - 选择器与副本数的相互约束:当选择器限制可放置节点/磁盘集合小于副本数需求时(如测试用例 2),Longhorn 无法补足副本,日志会出现
unable to get a ready node disk;此时需要放宽选择器或扩充符合条件的节点/磁盘集合。 - 唯一副本保护:驱逐逻辑保证不会删除最后一个健康的非驱逐副本(测试用例 6),避免因驱逐导致 BackingImage 数据彻底丢失。
- 副本清理时机:副本清理依赖
backingImageCleanupWaitInterval,且仅清理未被 Replica 使用的多余副本,避免影响运行中的 Volume。
延伸阅读
- 增强提案原文:enhancements/20240426-backing-image-enhancement.md
- 相关增强提案:V2 数据引擎下的 BackingImage 支持见 enhancements/20241203-v2-backing-image-support.md;磁盘/节点驱逐机制的更早期设计见 enhancements/20200727-add-replica-eviction-support-for-disks-and-nodes.md
- CRD 定义:deploy/longhorn.yaml 与 chart/templates/crds.yaml
- Helm Chart 设置:chart/values.yaml(含
backingImageCleanupWaitInterval、backingImageRecoveryWaitInterval等全局参数)
说明:本文基于当前仓库中的增强提案文档、CRD 定义与 Helm Chart 配置编写;提案中引用的 longhorn-manager v1.6.1 node_controller.go 行号属于提案撰写时的外部参考,本仓库为纯文档/部署清单仓库,不含 Go 源码实现,相关控制器行为以提案描述与 Longhorn 官方行为为准。
- 云原生
- 存储
- 高可用
- 容器编排
【免费下载链接】longhorn
Cloud-Native distributed storage built on and for Kubernetes
相关推荐
Longhorn 副本驱逐(Replica Eviction)机制深度解析:磁盘与节点级驱逐的设计、实现与运维实战
Longhorn 副本驱逐(Replica Eviction)机制深度解析:磁盘与节点级驱逐的设计、实现与运维实战 本篇技术指南围绕 Longhorn 增强提案
云原生存储高可用容器编排Longhorn 磁盘级副本软反亲和(Disk Anti-Affinity):单节点多磁盘场景下的副本分散调度指南
Longhorn 磁盘级副本软反亲和(Disk Anti Affinity):单节点多磁盘场景下的副本分散调度指南 导读 Longhorn 允许每个节点挂载多块
云原生存储高可用容器编排如何构建智能票务自动化系统:深度解析大麦抢票框架的技术哲学
如何构建智能票务自动化系统:深度解析大麦抢票框架的技术哲学 在当今数字化票务生态中,效率已成为决定成败的关键因素。大麦智能票务自动化系统正是基于这一理念构建的技
云原生存储高可用容器编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考