Longhorn v1.13.0 于 2026 年 9 月 29 日发布:最低要求抬到 Kubernetes v1.34、V2 卷首次可在线升级但只支持从 v1.12.2 起,新增 longhorn-global-manager 三副本控制面,另公开 3 条未修复的已知问题,前置部署 Forward Deployed Engineer(FDE)升级前要过 4 项人工检查
Longhorn v1.13.0 于 2026 年 9 月 29 日发布,最低环境要求抬到 Kubernetes v1.34,V2 卷可在线升级。
前置部署 Forward Deployed Engineer(FDE)在客户自建 Kubernetes 上交付「持久化存储」(persistent storage)时,最怕的不是装不上,而是升级把在线卷打挂。本条把这次升级的「升级门槛」与「最小版本」约束、默认值变化与三条尚未修复的已知问题一次列清,FDE 可以据此决定「现在升还是先等」。
一、这条发布是什么,属于哪条产品线
Longhorn 是云原生计算基金会(Cloud Native Computing Foundation)旗下的「分布式块存储」(distributed block storage)项目,由 SUSE / Rancher 主导维护,用 Kubernetes 自身的 CRD 与控制器把节点上的裸盘聚成可被 PVC 消费的持久卷。它在物理隔离(air-gapped)与边缘场景里被广泛使用,因为它不依赖任何公有云块存储服务。
v1.13.0 的 GitHub release 时间戳是 2026-09-29T09:13:24Z,前一个条目是 v1.13.0-rc4(2026-09-23),所以本次是正式版而不是候选版。这是一个特性版本(feature release)而不是补丁版,官方发布说明的章节顺序是:破坏性变更、主要亮点、安装、升级、发布后已知问题、已解决问题清单。
前置部署 Forward Deployed Engineer(FDE)要注意一个结构性事实:这一版同时改了「能不能升」(Kubernetes 版本门槛)、「怎么升」(V2 卷「在线升级」live upgrade)与「升上去之后控制面长什么样」(多了一个 Deployment),三件事都落在同一个升级窗口里,不能拆开处理。
二、破坏性变更一:最低 Kubernetes 版本抬到 v1.34
官方把这一条写在破坏性变更的第一条:因为 CSI external-provisioner 升级到了 v6.3.0,所有集群在安装或升级到 Longhorn v1.13.0 之前,必须运行 Kubernetes v1.34 或更新版本。改动前的实现是 Longhorn 只要求较低版本的 Kubernetes,根因在外部依赖的版本约束——external-provisioner v6.3.0 自身的 Kubernetes 客户端库已经不再向后兼容更老的 API。
这条对 FDE 的实际含义是:升级 Longhorn 之前必须先升 Kubernetes,而升 Kubernetes 是客户环境里周期最长、审批链最长的一步。先执行 kubectl version 核对服务端版本号;如果客户集群低于 v1.34,这次升级在排期上就应该按「先排 Kubernetes 升级」立项,而不是按「换个 Helm chart 版本」立项。
三、破坏性变更二:旧版 V2 链接克隆卷只能卸载或删除
第二条破坏性变更针对「链接克隆」(linked clone)卷。在 Longhorn v1.12.0 及更早版本里创建的 V2 链接克隆卷,从 v1.12.1 起被标记为旧版(legacy)并弃用,原因是 Ticket #12552 引入的新链接克隆架构与旧设计不兼容。升级到 v1.12.1 或更新版本之后,这些旧卷除了卸载(detachment)和删除之外不能再做别的操作。
官方给的替代路径很轻:直接从这些旧卷背后的同一个源卷再建一个新的链接克隆卷即可。官方明确保证只要旧卷还存在,它的源卷就一定还在,所以重建链接克隆不需要复制任何数据。FDE 在现场核对时可以用一条判断规则:如果客户集群里存在 2026 年之前建的 V2 链接克隆卷,升级前先列出来、逐个按源卷重建,不要等升级完再补。
四、破坏性变更三:CSI 控制器改用独立 ServiceAccount,默认拿到全集群 Secret 的 get 权限
v1.13.0 把 CSI 控制器的 sidecar 从共享的 longhorn-service-account 挪到专用的 longhorn-csi-service-account 上,而基础角色 longhorn-csi-role 与 longhorn-csi-bind 本身是不含 Secret 权限的。但为了兼容已有的 Secret 引用,官方发布的 Helm chart 与静态安装清单默认给这个新账号授予了全集群范围的核心 Kubernetes Secret 读取权限,由 longhorn-csi-secret-role 与 longhorn-csi-secret-bind 两个对象实现,其中 ClusterRole 只含 secrets 的 get 动词,ClusterRoleBinding 精确绑定到 Longhorn 命名空间下的longhorn-csi-service-account。
这条默认授权是刻意的、也是静态的:它由安装动作控制,不由 longhorn-driver-deployer 在启动时创建或删除,所以改 StorageClass 既不会触发调谐,也不需要重启 deployer;反过来,手工删掉它也不会被 deployer 自动恢复,只有后续再 apply 一次带该授权的清单才能重建。Helm 用户如果不想要控制器侧的 Secret 访问,可以设置 csi.allowControllerSecretAccess=false,Helm 就会既不渲染 longhorn-csi-secret-role 也不渲染 longhorn-csi-secret-bind。官方对这条的设置描述很直白:请对照贵集群自己的 Secret 访问策略复核。
关闭之前有一个前置动作不能漏:必须先从 StorageClass 里移除历史上的csi.storage.k8s.io/provisioner-secret-* 参数,否则用那些 StorageClass 新建卷会失败。因为 StorageClass 的参数是不可变的,官方给的做法是重建同名的 StorageClass,只去掉 provisioner-secret-* 这几个历史参数,其余字段(节点侧 Secret 参数、标签、注解、默认类标记)全部保留。这个迁移过程不碰已有 PVC、PV、Longhorn 卷与 CSI volume handle,不需要备份、卸载、重新绑定或替换 PV。
FDE 在金融与政企客户里通常要把这条默认授权关掉,关闭顺序是:先改 StorageClass(去掉历史 provisioner 侧 Secret 参数),再设 csi.allowControllerSecretAccess=false,最后确认 longhorn-csi-secret-bind 确实不在集群里。顺序颠倒会让新建卷直接失败。
五、V2 数据引擎首次支持在线升级,但入口只有一个
V2 数据引擎(V2 Data Engine)在 v1.12.0 达到正式可用(GA),v1.13.0 给它加上了在线升级(live upgrade):升级 Longhorn 时 V2 卷可以保持挂载状态,V2 instance manager 不必先卸载卷再升级,从而避免升级过程打断业务。
门槛写得很死:V2 在线升级只支持从 Longhorn v1.12.2 升上来。如果客户集群还停在 v1.12.0 或 v1.12.1,或者不满足官方列出的在线升级前置条件(prerequisites),就必须在升级前把所有 V2 卷卸载,并确认它们的副本已经停止。前置部署 Forward Deployed Engineer(FDE)在排升级窗口时,第一件事是查当前 Longhorn 版本号,而不是查 Kubernetes 版本号——这一条决定窗口能不能做到不停机。
六、两处默认值变化:中断模式与 CPU 隔离
中断模式(interrupt mode)在这一版变成完全事件驱动:SPDK 的 reactor 改为等待 I/O 事件,而不是持续轮询,只保留低频后台检查,因此在空闲或低 I/O 负载下 CPU 占用明显下降。这修正了 v1.10.0 引入的混合实现的短板——那套实现即使卷完全空闲也会持续占一点 CPU。但官方的取舍也写明了:在持续高吞吐负载下,中断模式可能比轮询模式带来略高的 I/O 延迟。轮询模式仍然是默认值,要切换得设 data-engine-interrupt-mode-enabled 为 {"v2":"true"},而且必须在没有任何 V2 卷挂载的时候改。
CPU 隔离(CPU isolation)这一版直接改成默认开启:新安装会把 data-engine-cpu-isolation-enabled 设为 {"v2":"true"},把中断和其他内核后台工作从 V2 数据引擎使用的 CPU 核上挪开。两个例外必须记住:从 v1.12.x 升级上来的集群会保留原有取值,不会自动打开,要自己显式设成 {"v2":"true"};而 CPU 隔离只在轮询模式下生效,一旦启用了中断模式,Longhorn 会自动跳过它。
还有一条容易被忽略的变更:SPDK 的缓冲区池大小由 data-engine-iobuf-large-pool-size 与 data-engine-iobuf-small-pool-size 两个设置控制(这两项是 v1.12.1 引入的),池子越大越不容易在高队列深度下耗尽缓冲区;但因为池大小是 SPDK 启动时确定的,改这两个设置会重建那些没有运行中引擎或副本的 V2 instance manager pod。
七、调度侧新增两个开关,其中一个在托管 Kubernetes 上用不了
第一个是 StorageClass 新增的 volumeTopology 参数,取值只有三个:any(默认,不加约束)、zonal(副本留在创建卷时所选的可用区)、regional(同样的语义,作用域换成地域)。改动前的行为是可用区标签只用来把副本彼此分散,所以一次副本重建仍可能把副本放到与工作负载不同的可用区;v1.13.0 之后重建与副本数变更都会遵守这个约束。两个边界要留意:如果选中的可用区没有容量,调度会等待而不会回退到别的可用区;以及 volumeTopology 设为 zonal 且同时把 replicaZoneSoftAntiAffinity 设为 disabled 的 StorageClass,会在创建卷时被直接拒绝。没有拓扑标签的集群不受影响。
第二个是「调度器扩展」(scheduler extender),它让 kube-scheduler 能读到 Longhorn 磁盘的真实容量。官方给出了改动前依赖 CSIStorageCapacity 对象的三个具体缺陷:一是在一批 Pod 同时创建时上报容量滞后;二是带多个 PVC 的 Pod 不会按它在多个磁盘上的合计需求做校验;三是 PVC 已经绑定完成的 Pod 重新调度时完全不做容量检查。扩展还做一件对部署很实用的事:把重启的 Pod 钉回到已经持有它全部副本的那个节点上,所以它对 best-effort 数据本地性的卷最有用。
这条能力的部署代价几乎没有——扩展跑在 longhorn-manager 内部并参与 leader 选举,不额外引入组件;但它需要一个 kube-scheduler 配置变更,而托管 Kubernetes 服务(例如 GKE 与 EKS)不允许改这个配置。前置部署 Forward Deployed Engineer(FDE)在托管集群上交付时,这条能力可以直接划掉,但在客户自建集群上它是解决「Pod 起来后才发现盘不够」的现成答案。
八、控制面从 DaemonSet 拆出一个三副本 Deployment
v1.13.0 把集群级的 Pod 控制器与 PersistentVolume 控制器从 longhorn-manager DaemonSet 里搬出来,放进一个新的 longhorn-global-manager Deployment。改动前每个 longhorn-manager pod 都监听集群里所有 Pod,所以 kube-apiserver 的负载与 longhorn-manager 的内存占用会随节点数和 Pod 数一起涨;改动后由选出的单个 leader 运行这些控制器,longhorn-manager 只监听 longhorn-system 这一个命名空间。这个 Deployment 在安装和升级时都会创建,默认三副本(对应 longhornGlobalManager.replicas),一个 leader 加两个随时能接管的 standby。官方给升级前的要求是:确认它至少有一个 Pod 能被调度。
对 FDE 来说这是一条必须进交付清单的检查项:在节点被 taint 过、有节点亲和性限制、或者命名空间配了 ResourceQuota 的客户集群里,这个新 Deployment 有可能一个副本都调度不上,升级就卡在中间态。升级前用 kubectl 确认 longhorn-system 命名空间下至少有一个节点可调度,再动手。
九、快照与保留:卷组快照不是时间点一致
v1.13.0 新增「卷组快照」(volume group snapshot):可以在 Longhorn UI、用 kubectl、或者通过 CSI 的 VolumeGroupSnapshot 对象,用一次请求把一组相关的卷一起打快照。UI 与 kubectl 两条路径开箱可用;CSI 那条路径默认关闭,需要 VolumeGroupSnapshot CRD、snapshot-controller 上的 CSIVolumeGroupSnapshot 特性门,以及 Longhorn 自己的一个开关三样齐备。CSI 路径还额外支持组备份。
官方主动写出的局限比功能本身更值得引用:组内每个成员卷是各自独立打快照的,所以整组捕获的不是一个单一时间点;跨卷的应用级一致性被明确列为后续工作(Issue #2128)。换句话说,这个功能解决的是「一次操作打一组」的运维便利,不要把它当成数据库级的一致性快照来用。
第二项是保留策略。快照、备份与系统备份的周期性任务(recurring jobs)新增了「年龄保留」(age-based retention):把 retentionPolicy 设为 age-based,把 retainAge 设成一个时长比如 720h,每次运行时删掉比 retainAge 更旧的快照或备份,不看数量、也不看任务跑得多频繁。支持的单位只有 s、m、h 三种,写一天要写 24h。默认值仍是基于数量的 count-based,而且升级后已有周期性任务保持原样、不会被自动改成年龄保留——FDE 想统一口径,必须自己逐个改。
十、四条稳定性修复,第一条会造成数据损坏
第一条最严重:修复了一个 V2 链接克隆卷的备份恢复缺陷,该缺陷在源卷、或者克隆所基于的快照已经不存在时,可能恢复出一个损坏的卷。修复后的行为是:V2 链接克隆卷的备份会记录源卷与快照,两者任一缺失时恢复会直接报错而不是悄悄产出一个坏卷。对已经在用这条链路的团队,这条修复本身就是升级的理由。
第二条:修复了 dataLocality 设为 strict-local 的卷做 CSI 卷克隆时,可能报 hard affinity cannot be satisfied 失败的问题;现在会为克隆挑一个同时匹配该卷 nodeSelector 与 diskSelector 的节点。
第三条:修复了 Kubernetes 节点已被删除且未做驱逐(eviction)时,对应的 Longhorn 节点无法移除的问题;现在可以先禁用该节点的调度、清掉它剩余的副本与引擎,再删除节点。官方仍然建议先驱逐再从集群删除节点。
第四条针对 IPv6:修复了备份镜像(backing image)副本始终走 IPv4 传输的问题——在 IPv6 单栈与 IPv6 优先的双栈集群上,备份镜像此前会一直停在一份副本;现在备份镜像会按集群的 IP 协议族与存储网络传输。
十一、三条公开未修复的已知问题
第一条是规模化的挂载延迟:在已挂载 V2 卷数量持续增多的环境里,后续卷的挂载延迟会变长。官方初步分析认为可能与规模化的 NVMe-TCP 连接处理有关,但还没定位到究竟是 SPDK 用户态还是 Linux 内核层,调查仍在进行。
第二条是 ARM64 上的 NVMe 节点盘限制:在 ARM64 系统上,当 SPDK 配置了两个或更多 CPU 核、且节点盘使用 NVMe 驱动时,V2 卷可能出现 I/O 卡死。根因同样未定,可能在 Linux 内核也可能在 SPDK 自身。官方给的绕法是把 ARM64 上的节点盘从 NVMe 盘换成 AIO 盘。
第三条是 UBLK 前端的内核限制:V2 数据引擎的 UBLK 前端仍是实验特性,在 6.17 内核上挂载一个 UBLK 卷可能触发内核 panic,官方明确写了不要在这个内核版本上使用。前置部署 Forward Deployed Engineer(FDE)在边缘节点上做内核升级时要把这条一起纳入变更评审。
另外「存储分片」(storage sharding,基于「纠删码」erasure coding)仍被标为实验特性,官方写明它不支持备份与恢复、卷克隆、备份镜像、容灾卷与在线迁移,只建议用于评估与测试、不推荐用于生产。同一份说明里,自 v1.12.1 起默认创建的内部 NetworkPolicy 只在 CNI 插件真正执行 NetworkPolicy 时生效,并且 v1.12.2 补了三个 Helm 值:networkPolicies.v1DataEngineInitiatorSourceCIDRs、networkPolicies.recoveryBackendAdditionalIngressPorts,以及让 Prometheus 等抓取方能访问 longhorn-manager 在 TCP 9500 端口上的指标的 networkPolicies.metricsScrapeSources。v1.12.1 之前的 mTLS 只覆盖 instance manager 的 instance 与 proxy 两个 gRPC 服务,磁盘与 SPDK 服务仍接受明文连接;自 v1.12.1 起 mTLS 覆盖全部 gRPC 服务,配置了 longhorn-grpc-tls Secret 的集群里每个 gRPC 端口都要求有效客户端证书。
十二、官方要求升级前做的四项人工检查
官方明确承认自动化的升级前检查并不覆盖所有场景,所以建议做一轮「人工检查」,用 kubectl 或 UI 过一遍四项。第一项,针对 V2 卷核对在线升级前置条件;如果不满足,就卸载全部 V2 卷并确认副本已停止。第二项,不要在卷处于 Faulted 状态时升级,因为不可用的副本可能被删除,在没有备份的情况下会造成永久数据丢失。第三项,存在失败的 BackingImage 时不要升级。第四项,升级前建一次 Longhorn 系统备份,保证可恢复。
前置部署 Forward Deployed Engineer(FDE)可以直接把这四项改写成变更单上的勾选项,再补两条自己加的:确认 longhorn-global-manager 至少有一个 Pod 可调度;以及确认当前版本是 v1.12.2 以上,否则按「需要停机窗口」报价。
十三、局限:官方承认的部分与我方补充的部分
官方承认的第一条是规模化挂载延迟没有定位到层,只能说可能与 NVMe-TCP 连接处理有关,SPDK 用户态与 Linux 内核层都还没排除。
官方承认的第二条是 ARM64 上 SPDK 多核加 NVMe 节点盘会 I/O 卡死,绕法是换 AIO 盘,但根因未定,也没有给出受影响的核数上限或规模阈值。
官方承认的第三条是 UBLK 前端在 6.17 内核上会 panic,只能靠「不要用」来规避,没有给修复版本。
官方承认的第四条是卷组快照不保证单时间点一致,跨卷应用级一致性仍是未完成项。
官方承认的第五条是存储分片不支持备份恢复、卷克隆、备份镜像、容灾与在线迁移,且被限定为实验特性。
官方承认的第六条是调度器扩展到托管 Kubernetes 上不可用,原因是它需要改 kube-scheduler 配置。
官方承认的第七条是 StorageClass 的历史 provisioner Secret 参数清理只覆盖历史 provisioner 参数,明确不能假定 controller-publish-secret-*、controller-expand-secret-*、通用 Secret 参数或其他自定义控制器配置清理后仍然安全。
我方补充的第一条是全篇没有任何性能数字:官方没有给中断模式相对轮询模式的 CPU 节省比例,也没有给延迟增加的幅度,只说「略高」;控制面拆分只说降低负载与内存,没给百分比。要写进客户方案,必须自己在测试集群上量。
我方补充的第二条是规模口径缺失:官方说 longhorn-global-manager 是为「大集群」降低负载,也给过升级前要确认可调度,但没给节点数或 Pod 数的临界值,也没有给三副本能不能调到一或五的指引。
我方补充的第三条是三条已知问题都没有绕过后的可用性上限,比如 ARM64 换成 AIO 盘之后性能掉多少、规模化挂载延迟在多少卷之后开始出现,都没有数字。
我方补充的第四条是升级不可逆这件事只能从流程上防:官方只说明 Longhorn 仅允许从受支持的版本升级,但没有给版本回退(downgrade)路径。也就是说第一项人工检查没做完就动手,代价是回不去。
十四、实用结论:谁该行动、怎么做、什么时候别升
该行动的是三类人:在客户自建或边缘 Kubernetes 上用 Longhorn 提供持久卷的交付团队;被 Kubernetes 版本与存储插件版本互相卡住而排不出升级窗口的平台组;以及正在用 strict-local 克隆或 V2 链接克隆备份、有可能已经踩到损坏卷缺陷的人。
可以照着做的动作清单。第一步,两条命令先摸底:kubectl version 看服务端是否 v1.34 以上;helm list 或 kubectl get deployment -n longhorn-system 看当前 Longhorn 版本是否 v1.12.2 以上。第二步,列旧卷:把 v1.12.0 及更早创建的 V2 链接克隆卷列出来,按源卷逐一重建;旧卷除卸载与删除外不要再做操作。第三步,做四项人工检查并建系统备份,特别确认没有处于 Faulted 状态的卷、也没有失败的 BackingImage。第四步,确认 longhorn-global-manager 在 longhorn-system 里至少有一个 Pod 能被调度。第五步,只有版本与前置条件都满足时才按在线升级走;否则卸载全部 V2 卷、停掉副本,并按需要停机来排窗口。第六步,升完再按需打开年龄保留与 volumeTopology,这两项升级后都不会自动生效。
适用条件与不适用条件要分开写。适用的前提是:客户集群的 Kubernetes 已经到 v1.34 以上;当前 Longhorn 是 v1.12.2 以上;集群不是靠托管服务托管的——因为调度器扩展在 GKE 与 EKS 上无法启用。不适用的场景也很清楚:集群里还有需要保留的旧版 V2 链接克隆卷、且没有源卷可重建;节点是 ARM64 且节点盘走 NVMe 驱动、又需要 SPDK 用两个以上 CPU 核;或者节点的内核正好是 6.17 且计划使用 UBLK 前端。这三类场景应当先改造环境再升级。
回滚与退出方式只能按「避免走到需要回滚的程度」来设计,共三层。第一层是时间窗口:官方没有给版本回退路径,所以唯一的退出方式是在动手之前把四项人工检查做完、把系统备份建好。第二层是升级中断:V2 在线升级只支持从 v1.12.2 起,版本不符时先卸载卷再升级,避免升到一半出现挂载态与版本不匹配。第三层是权限收口要留后手:如果设了 csi.allowControllerSecretAccess=false,删掉 longhorn-csi-secret-bind 之后不会被 deployer 自动恢复,要恢复默认授权必须重新 apply 一份带该授权的清单,所以这个改动要写进变更记录,否则交接后没人知道为什么新建卷会失败。
最后一条判断规则:把 v1.13.0 当作「控制面与调度能力的版本」来评估,而不是当作「性能版本」。它真正省钱省事的地方是 longhorn-global-manager 把 apiserver 负载从 DaemonSet 上摘下来,以及调度器扩展能在自建集群上避免 Pod 起来后才发现盘不够;但它没有给任何性能数字,也没有解决规模化挂载延迟。前置部署 Forward Deployed Engineer(FDE)向客户提交建议时,应当把这三条未修复的已知问题与原版发布说明一起附上,而不是只挑功能列表。
原始来源:
- https://github.com/longhorn/longhorn/releases/tag/v1.13.0
- https://longhorn.io/docs/1.13.0/important-notes/
评论(0)
- 暂无评论。