
提醒如果你已经读过我另外几篇关于存储的笔记大概知道我不太喜欢那种通篇贴命令然后说“照着抄就行”的文章。Longhorn 用 Helm 部署这件事表面上看是一条命令的事但真正决定它能不能在测试环境、生产环境稳定跑起来的往往是部署前对架构的认知、部署时那条values.yaml里每个参数的取舍、以及部署完了以后怎么验证存储链路是否真的健康。这篇文章我尽量把这些一次性说透顺便把我在自己集群里踩过的一些坑写出来希望你能少走点弯路。1. 为什么选择 Longhorn以及 Helm 部署到底解决了什么问题Longhorn 是 Rancher 团队开源的一个 Kubernetes 原生的分布式块存储方案。它和 Ceph、Rook、OpenEBS 这类常被拿来对比的存储不太一样的地方在于它把存储的控制面直接做成了 Kubernetes 的 CRDCustom Resource Definition和控制器也就是说它从设计之初就是“为 Kubernetes 而生”的完全跟着 Kubernetes 的资源模型走节点扩展、调度、故障迁移这些场景可以跟 K8s 原生语义打通。它的核心能力包括跨节点的数据多副本、增量快照、定期备份到 S3 或 NFS、跨集群灾难恢复。底层实现上每个卷会被拆成多个 block 级别的小 chunk分布在几个节点的本地磁盘上每个 chunk 由一个 engine 和若干 replica 组成。这个架构让我第一次接触的时候有种“麻雀虽小五脏俱全”的感觉——它没有像 Ceph 那样搞复杂的 monitor 集群和 crush map而是把所有逻辑都收敛到了 Kubernetes 内部用一套挺巧妙的事件驱动机制来保证数据最终一致。当然这个架构也决定了它特别吃 CPU因为每个卷的 IO 都要经过 engine 端的处理这个我后面会展开说。那为什么专门写一篇 Helm 的部署手册呢因为 Longhorn 虽然也提供基于 Rancher 的 UI 集成安装、基于 YAML 的 kubectl 安装但我个人在实际使用中的体会是Helm 是其中最灵活、最可控、最适合在多个环境里反复复用的方式。尤其是当你想在开发环境、预发环境、生产环境保持同一套基础配置只在部分参数上做差异化调整时Helm 的 values.yaml 机制是非常顺手的管理手段。它能把“升级”“回滚”“参数 diff”这些运维动作变成很标准化的流程而不是每次都要去记一堆 kubectl apply 的文件路径。我遇到不少朋友问的最多的问题是“Longhorn 和 Rook-Ceph 比到底哪个好”说实话这个没有绝对优劣更多是适不适合。如果是大规模的、需要极高并发吞吐的块存储场景Ceph 在成熟度和高性能上有优势但 Rook-Ceph 的运维复杂度明显高出一截尤其当集群版本升级或者盘故障需要修复的时候没点经验很容易把自己搞到深夜。Longhorn 更适合中小规模集群、边缘集群、或者团队里没有专门 SRE、但希望存储能够自主可控的场景。它的 UI 做得很不错很多操作比如创建卷、创建快照、设置备份目标都能在图形界面里完成这个特点对运维人力较少的团队是非常友好的。再回到 Helm 本身。虽然 Longhorn 官方文档给了一段很简单的安装命令helm repo add longhorn https://charts.longhorn.io helm repo update helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace但如果你真就这么装了大概率会在后续使用的时候遇到不少需要二次调整的地方。比如 Longhorn 默认会对每个 PVC 创建 3 个副本如果你只有一个节点的开发环境这个默认值就会导致卷一直处于 degraded 状态又比如默认情况下 Longhorn 会把节点上的所有可用磁盘都识别为“可调度磁盘”如果你的节点上挂了一块系统盘加一块数据盘而你又没做任何限制系统盘上的空间很容易被存储卷吃光。这些细节单靠“照着装”是完全不会注意到的但它们恰恰是生产环境稳定性的关键。所以这篇文章后面我花了不少篇幅在这类初始配置上目的就是希望你看完以后做出来的配置是能直接扛住业务压力的而不是装完就完事。2. 部署前的环境检查版本匹配、硬件要求与内核参数Longhorn 的官方安装文档对集群版本、节点资源、文件系统类型有明确要求但很多人在部署的时候不会仔细看往往等到卷创建失败或者 pod 无法调度了才回头查环境。这里我把实际部署前必须确认的事项列一遍建议你逐条过一遍避免后面踩坑。2.1 Kubernetes 与 Helm 的版本匹配问题Longhorn 对 Kubernetes 的版本要求比较严格原因在于它大量使用 Kubernetes 的新特性比如 CSI 的各种能力、VolumeSnapshot CRD、甚至某些结构调整还要依赖存储类的 topology 感知。以我现在用的 Longhorn v1.6.x 为例它要求的 Kubernetes 版本是 v1.21 到 v1.28 左右过老或过新的版本都可能出现兼容性问题。当然Longhorn 的版本一直在更新较新的 v1.7.x 和 v1.8.x 已经放宽到 v1.25 以上但我还是建议你以官方 compatibility matrix 为准。Helm 的版本影响相对小一些但也不要太旧至少用 Helm v3。Helm v2 因为 Tiller 的原因已经不适用了如果你还在用 v2先把 Helm 升级到 v3 再说。判断自己集群版本的命令很简单kubectl version --short helm version如果你用的是云厂商的托管 Kubernetes 集群比如 AKS、EKS、ACK一般版本都不会太旧但注意有些云厂商会默认打开一些安全策略比如 PodSecurityPolicy 或 OPA 策略可能会拦住 Longhorn 创建 privileged pod。这种情况下部署前最好先检查一下集群里是否有针对 namespace 的 PSP 或安全策略否则 Longhorn 的 DaemonSet Pod 很可能被拒绝运行。2.2 节点硬件要求CPU 和内存比你想的更吃紧Longhorn 的架构决定了它并不是“零成本”的存储方案每一个卷的 IO 都要经过 longhorn-engine 进程的处理。引擎进程跑在卷所在的一个或多个节点上负责把来自节点的块数据请求转发到对应副本节点去也就是说每次读写都要在 CPU 里完成一层类似代理和校验的工作。正因如此Longhorn 对节点 CPU 的消耗非常明显尤其在被大量随机读写压满的时候。根据官方给出的最低要求每个节点至少要 4 GB 内存但我在实际部署中强烈建议至少 8 GB 以上而且要单独预留一部分给系统、给 kubelet、给容器运行时。原因很简单Longhorn 除了 engine 之外每个节点上还有一个 longhorn-manager 在跑它负责管理该节点上的卷生命周期以及一个 longhorn-csi-plugin 插件当节点数量多了以后这些常驻进程加在一起的内存开销并不小。CPU 方面v1.6 之后引入了数据分析引擎 Data Engine v2也就是基于 SPDK 的那一套它对 CPU 的需求更大。如果你用的是普通的小型云主机比如 2C4G 这种建议老老实实用 Data Engine v1也就是默认的基于 Linux 内核 LIO 的方案不然性能会很难看而且 CPU 还容易被顶满。2.3 文件系统与磁盘直接决定了卷的性能和可靠性Longhorn 对节点本地文件系统的要求是 ext4 或 XFS。它默认在/var/lib/longhorn这个目录下存放数据如果你不希望跟系统盘混在一起部署前最好把一块独立的数据盘挂载到那个路径或者用符号链接指过去。生产环境千万不要把 Longhorn 数据放在根分区上否则日志一写、卷一扩张系统盘被占满导致节点直接 NotReady 的情况我是真的见过不止一次。另外Longhorn 默认是把每个节点上所有可用的挂载点都当作候选磁盘这个行为有点过于“激进”。我的做法是在 values.yaml 里通过defaultNodeSelector以及磁盘设置的disableSchedulingByDefault之类的参数来做约束确保只有真正用于存储的磁盘才会被纳入调度。这块在后面的配置参数部分会给出具体示例。2.4 内核模块与 iSCSI 依赖这是 Longhorn 部署里最容易被人忽略的一个前置条件也是我第一次装的时候卡了最久的一环。Longhorn 默认的 Data Engine v1 需要节点上有iscsi_tcp内核模块同时装上 open-iscsi 的用户态工具。原因是 Longhorn 的 block device 在节点和节点之间是通过 iSCSI 协议连接的。如果你在部署后创建第一个 PVC 时发现 pod 一直 ContainerCreatingevents 里报Failed to attach volume或者iscsiadm: not found那基本就是这块的问题。Debian/Ubuntu 系的安装命令sudo apt-get update sudo apt-get install -y open-iscsi sudo systemctl enable --now iscsidCentOS/RHEL 系sudo yum install -y iscsi-initiator-utils sudo systemctl enable --now iscsid还有一个multipathd的问题。如果节点上跑着 multipathd而它把 Longhorn 创建的 iSCSI 设备误以为需要做 multipath 聚合可能会给设备改名导致挂载失败。官方文档的建议是在 multipathd 的配置里忽略/dev/disk/by-path/*-iscsi-*开头的设备。好在大多数默认安装的 Linux 发行版里 multipathd 默认是关闭的但如果你用的镜像或云主机初始化脚本里开了这个服务就要特别小心。2.5 时间同步与服务发现所有分布式存储都很依赖节点时间一致。Longhorn 的调度判断、故障转移逻辑都基于事件时间戳如果节点间时间差太大可能出现“误判节点离线”或“副本同步超时”的情况。每个节点上装好 chrony 或 ntpd保持和 NTP 服务器同步这是基础但重要的一步。另外Longhorn 的组件之间通过固定名字的 Service 做服务发现如果集群中有 NetworkPolicy 把 namespace 之间的流量拦了需要确认放行longhorn-systemnamespace 内的通信。还有如果节点之间有防火墙比如使用云厂商的安全组要放行 3260 端口iSCSI 默认端口和 9500-9505 端口Longhorn 组件间的通信端口否则跨节点副本的同步根本走不通。3. Helm 部署的完整实操路径从 values.yaml 到安装验证环境确认没问题之后就可以进入正式的 Helm 部署流程了。这一节我尽量把每一步都写清楚并且重点说明哪些参数是我强烈建议你在第一次安装时就改掉的。3.1 获取 Longhorn Helm 仓库并确认版本先添加官方 Helm 仓库然后搜索可用版本helm repo add longhorn https://charts.longhorn.io helm repo update helm search repo longhorn -l这里有一个很多初学者容易忽略的点longhorn/longhorn这个 chart 的版本号并不等同于 Longhorn 的版本号而是 chart 自己的版本。你在部署前最好确认一下 chart 版本对应的 Longhorn app 版本最简单的方式是用helm show chart longhorn/longhorn查看输出里会同时包含version和appVersion通常前者是 chart 版本后者才是 Longhorn 本体版本。我见过有人因为用了很老的 chart 版本结果部署出来的是低版本的 Longhorn然后遇到一些已经在新版本里修复的 bug。所以建议直接选最新的稳定 chart 版本除非你有明确的兼容性理由必须固定在某个版本。3.2 定制一份适合你自己的 values.yamlhelm show values longhorn/longhorn values.yaml可以先把默认配置导出到文件然后据此修改。默认 values 里有几百个配置项你不需要全看懂但下面这几个是绝对值得认真确认的。3.2.1 副本数单节点环境一定要设为 1默认的defaultReplicaCount是 3。如果你的集群节点数少于 3创建出来的卷会一直处于 degraded降级状态LivenessProbe 可能都会跟着抖动。开发环境或者单节点测试环境我建议改成 1既能省空间又能避免无谓的告警。defaultSettings: defaultReplicaCount: 1如果你有 3 个以上节点而且追求生产级的数据安全可以保留 3但要注意这会占用三倍的存储空间一个 100 GB 的卷最终会占用 300 GB 的节点磁盘。存储容量规划的时候一定要把这层冗余算进去。3.2.2 数据局部性与节点策略defaultDataLocality默认是disabled意味着卷的多个副本可以散落在任意节点读取的时候不一定从本节点读会有额外的网络开销。如果你的业务对读延迟比较敏感可以改成best-effort尽量本地优先或者strict-local严格本地。但要注意strict-local会限制卷只能调度到某一个节点和节点高可用是冲突的生产环境一般不建议用 strict-local。节点调度方面我不太希望存储卷跑在那种临时加的、网络不太稳定的节点上所以我会给专用存储节点打标签然后在 values 里加上defaultSettings: defaultNodeSelector: storage-node: true只有打了这个标签的节点才会被 Longhorn 纳入存储调度范围。这个做法可以在集群节点比较杂的情况下把存储负载隔离到专门的大磁盘节点上避免业务 pod 和存储 IO 互相干扰。3.2.3 默认存储类命名Longhorn 安装后会自动创建一个名为longhorn的 StorageClass。如果你的集群里已经存在别的默认 StorageClass比如云厂商自带的 SSD StorageClass而你希望 Longhorn 成为真正的默认存储可以修改defaultSettings: defaultLonghornStaticStorageClass: longhorn persistence: defaultClass: true defaultClassReplicas: 1 defaultFsType: ext4 defaultMigratable: falsedefaultClass: true会使 Longhorn 的 StorageClass 被自动设置为集群的默认 StorageClass。defaultFsType我习惯用 ext4虽然 XFS 在某些场景下性能会更好但 ext4 兼容性最稳遇到需要调整文件系统大小的时候也更容易处理。3.2.4 污点容忍和节点维护如果节点上有 taintLonghorn 默认是不会调度上去的。但对于存储这种需要“依附于节点”的工作负载有时你得让它跑在有 taint 的节点上比如那些被专门标记为“仅存储”的节点。你可以通过tolerations: - key: CriticalAddonsOnly operator: Exists - key: node-role.kubernetes.io/storage operator: Exists来允许 Longhorn 的 DaemonSet Pod 调度到这类节点上。注意这里配置的是组件 Pod 的 tolerations不是卷的调度逻辑两个概念别搞混。3.3 执行安装用 helm install 一步到位假设你的 values.yaml 已经准备就绪安装命令如下helm install longhorn longhorn/longhorn \ --namespace longhorn-system \ --create-namespace \ -f values.yaml安装过程不需要等太久一分钟后你就可以看看资源状态kubectl get pods -n longhorn-system -o wide kubectl get svc -n longhorn-system正常情况下你会看到longhorn-driver-deployer、longhorn-manager-*、longhorn-csi-plugin-*、longhorn-ui-*这些 Pod 处于 Running 状态。这里的longhorn-driver-deployer是一个 Deployment它会负责把 CSI driver 注册到 Kubernetes 集群如果它一直 CrashLoopBackOff问题基本出在 API 权限或者集群版本兼容性上。3.4 安装后的 UI 访问方式Longhorn UI 默认是 ClusterIP 类型的 Service你可以用 kubectl port-forward 做本地预览kubectl port-forward -n longhorn-system svc/longhorn-frontend 8080:80然后浏览器打开http://localhost:8080就能看到控制台。登录页面会要求你设置 admin 密码初始密码是在第一次访问时生成的控制台会直接引导你完成。如果你希望团队里的其他人都能直接访问最简单的方式是改 Service 类型为 NodePortkubectl -n longhorn-system patch service longhorn-frontend \ -p {spec:{type:NodePort}}拿到 NodePort 之后用任意节点的 IP 加端口访问即可。如果集群在云上记得给安全组放行对应端口。进一步的做法是用 Ingress 暴露并配置 HTTPS这个就看你自己的网络环境了。3.5 验证安装是否真的“没问题”安装完成不等于万事大吉我每次装完都会做一轮比较完整的验证。首先是检查 StorageClasskubectl get storageclass然后建一个测试 PVC 和一个挂载它的 Pod确认 PV、PVC 都绑定成功Pod 能正常读写文件cat EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: longhorn-test-pvc spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 1Gi --- apiVersion: v1 kind: Pod metadata: name: longhorn-test-pod spec: containers: - name: test image: busybox command: [/bin/sh, -c, echo hello /mnt/test.txt sleep 3600] volumeMounts: - mountPath: /mnt name: testvol volumes: - name: testvol persistentVolumeClaim: claimName: longhorn-test-pvc EOFPod 起来之后进入容器确认写入是否正常kubectl exec -it longhorn-test-pod -- cat /mnt/test.txt如果输出hello说明整条数据链路——CSI 插件、engine、replica、底层磁盘——都已经通起来了。这时候再去 Longhorn UI 的 Volume 页面看看状态确认卷的Healthy状态、节点分布、副本数都符合预期才算真正完成部署验证。验证完把这套测试资源删掉kubectl delete pod longhorn-test-pod kubectl delete pvc longhorn-test-pvc4. 那些踩过的坑部署后最容易出问题的几个环节Longhorn 部署完成不等于“能用得稳”。我自己的集群在部署完成后的前两周里踩到过不少坑下面挑几个有代表性的按“现象—原因—解决”的方式写出来希望你能避开。4.1 单节点环境里的卷一直处于 degraded 状态现象我的测试集群只有一个节点按照默认配置装完 Longhorn创建 PVC 后Longhorn UI 里显示卷的状态是degradedPod 倒是能起来但一直有告警。原因默认副本数是 3但只有一个节点所以 Longhorn 只能在一个节点上放一个副本其余两个副本一直在等待调度卷自然就降级了。解决在 values.yaml 里把defaultReplicaCount改成 1 重新部署或者在 Longhorn UI 里对已有卷修改副本数。注意修改副本数后卷需要重新调度一般几分钟内就能恢复正常。如果你以后要把集群扩展成多节点别忘了把副本数调回 2 或 3。4.2 节点上所有磁盘都被当成可调度磁盘系统盘被撑爆现象集群跑了大概一周后某个节点的/分区使用率达到 80% 以上排查发现/var/lib/longhorn下的数据增长很快但我明明没有创建那么多大卷。原因Longhorn 默认会把节点上所有可挂载的磁盘都识别为候选存储磁盘只要满足最小可用空间要求就都会参与卷副本调度。系统盘如果也在其中快照、备份、卷数据都会往里面写。解决要么在部署前给系统盘挂载点排除掉要么在 Longhorn UI 的 Node 页面里对不需要的磁盘设置disabled。更稳妥的做法是在 values.yaml 里配置手动管理磁盘让节点上只有我指定的数据盘路径参与调度longhornManager: nodeDiskMap: # 这里可以用默认的自动发现但需要在UI里排除实际生产环境我更推荐把 Longhorn 数据目录/var/lib/longhorn单独软链到一块独立的大容量数据盘上比如/mnt/data/longhorn这样即使 Longhorn 把所有空间都用光也只是数据盘满不会影响系统盘的正常运行。这个软链操作只要在部署前做好就行部署中途改会涉及数据迁移挺麻烦的。4.3 iSCSI 依赖缺失PVC 一直绑定不上现象创建 PVC 后PV 也生成了但 Pod 一直 ContainerCreating事件里报Failed to attach volume。原因节点上没有安装 open-iscsi 工具或者内核缺少iscsi_tcp模块。Longhorn 的 Data Engine v1 通过 iSCSI 建立 block device 连接没有这个依赖根本挂载不上。解决按本文 2.4 小节的命令在集群每个节点上安装 open-iscsi 并启动 iscsid然后重启 kubelet 或者重启节点等 CSI 插件重新探测。这个依赖在节点扩容的时候特别容易忘记——新节点如果没装 open-iscsi调度上去的卷就会一直挂载失败。4.4 控制节点也参与副本调度影响稳定性现象集群里控制节点的磁盘空间被 Longhorn 的副本占用而且控制节点的负载明显变高。原因默认情况下只要节点有可用磁盘并且满足调度条件控制节点也会被纳入副本调度。解决给控制节点加 taint或者在 Longhorn 的 Node 页面手动禁用控制节点的调度也可以通过 values.yaml 的defaultNodeSelector做标签约束从源头避免。像我上面配的storage-node: true标签方案配合专门的数据节点打标签就能让控制节点彻底不被卷入存储调度。4.5 升级 Longhorn 时因为 chart 版本不匹配导致参数失效现象我升级过几次 Longhorn每次升级都会发现有些 UI 上配置好的参数在升级后悄然被重置或者某些自定义的 StorageClass 参数失效。原因Longhorn 的 Helm chart 在不同版本之间对 values.yaml 的字段名做了一些调整比如某些参数从defaultSettings挪到了顶层有些 deprecated 字段直接不生效了。用旧 values.yaml 直接覆盖新版本就会出现“字段还在但实际不生效”的情况。解决升级前一定先helm show values longhorn/longhorn --version 新版号把新版本的默认 values 导出和自己手上的 values.yaml 做 diff逐个字段确认兼容性。正规流程建议是helm show values longhorn/longhorn --version target-version values-new.yaml diff values-old.yaml values-new.yaml把差异处理完再执行升级不要图省事直接helm upgrade --reuse-values那个参数在配置结构变化较大的版本之间容易埋雷。5. 生产环境部署时的一些调优思路与长期维护建议Longhorn 装完只是第一步真正的挑战是让它的表现符合业务预期。这一部分我会聊几个生产环境里一定会碰到的调优点和运维习惯都是我自己的实践总结未必适合所有场景但作为参考一定有用。5.1 性能卷的 IO 路径与 SSD/NVMe 的选择Longhorn 的每个卷可以指定数据引擎v1 走 iSCSI/LIOv2 走 SPDK。如果你的节点都是 NVMe SSD并且 CPU 资源充足数据引擎 v2 能带来明显的性能提升尤其在高吞吐场景下直接把内核 iSCSI 的开销剥掉。但 v2 对系统配置要求更高比如要求节点内存有 1 GB 以上的大页支持而且目前对某些存储硬件的兼容性还在不断完善中。我个人在主流生产环境里还是会用 v1因为稳定压倒一切v2 更适合对性能有极致追求、环境可控的场景。磁盘类型的影响比引擎更大。同一台机器上把 Longhorn 数据盘从机械盘换成 NVMe SSD卷的 IOPS 可能提升几十倍。这个不是 Longhorn 的特殊问题任何存储架构都一样但 Longhorn 因为走了一层软件转发对底层磁盘延迟会更敏感所以有条件的话上 SSD 是很有必要的。5.2 监控与告警不要等到卷损坏了才登录 UILonghorn 自带一套很完整的监控指标暴露方式Prometheus 可以直接从http://longhorn-manager:9500/metrics抓取指标。我在集群里装了 Prometheus Operator然后加了一个 ServiceMonitor 来采集 Longhorn 的指标。比较关键的告警规则有这么几条longhorn_volume_actual_size_bytes接近卷容量上限的 80% 时提醒扩容longhorn_node_status变为 false 时说明节点离线需要立刻介入longhorn_disk_available_bytes低于某个阈值时提醒磁盘空间不足卷的robustness健壮性为 degraded 且持续超过 10 分钟说明有副本长时间不健康。如果你不想自己搭 PrometheusLonghorn UI 自带的可视化页面也能看到大部分状态包括节点、磁盘、卷、备份、快照的健康度。我建议至少给 UI 配一个独立的访问入口方便运维同学随时能看到存储侧的实时状况。5.3 备份与恢复S3 备份目标护住最后一道防线Longhorn 的备份功能是我比较喜欢的一环。创建一个 BackupTarget把备份目标指向 S3 兼容的对象存储比如 MinIO、AWS S3、阿里云 OSS然后按卷或按定时策略做增量备份。在 UI 上操作非常简单页面左栏选择 Backup添加 Backup Target填 S3 的 Endpoint、Bucket、Access Key 和 Secret Key 即可。对于自建 MinIO你要注意 Endpoint 的路径别写错而且 MinIO 的 region 要填us-east-1否则部分 SDK 会报错。我最初接 MinIO 的时候就在这里卡了半天。定时备份策略建议在生产环境一定要启起来哪怕一天只备份一次关键时刻都能救回数据。备份数据最好和 Longhorn 集群物理隔离也就是放到独立的对象存储上而不是放在同一个节点的磁盘上否则节点发生物理故障备份也没了。5.4 节点扩容与缩容时要注意的流程当你需要给 Longhorn 集群增加一个新节点时流程大概是这样先在节点上装好 open-iscsi 和 NFS 客户端如果要用 NFS 备份的话然后把它加入 Kubernetes 集群打上storage-nodetrue标签Longhorn 会自动发现这个节点并把它纳入调度范围。此时如果集群里已有卷的副本数不满足要求Longhorn 会自动在新节点上补建副本卷的状态会从 degraded 逐渐恢复为 healthy。缩容是很多人容易做错的地方。节点下线之前一定要先在 Longhorn UI 的 Node 页面找到对应节点检查上面有没有卷副本。如果有需要先把这些副本迁移到其他节点最简单的做法是把该节点的调度禁用Disable ScheduleLonghorn 会自动将副本重新调度到其他可用节点。等卷全部恢复健康、节点上已经没有任何 replica 之后再执行kubectl drain和节点下线。如果不按这个顺序操作轻则卷降级重则可能触发数据修复流程影响业务。5.5 升级路径尽量小步慢走不要跨大版本跳Longhorn 的大版本升级往往会伴随一些存储格式或行为的变化比如 v1.4 到 v1.5 之间就对 volume 的引擎镜像、甚至一些 CRD 字段做了调整。从低版本直接跳到最高版本虽然多数时候能成功但一旦遇到问题排错成本会非常高因为你很难判断是哪个中间版本的兼容性出了问题。我更建议采用逐版本升级的策略比如 v1.4.x → v1.5.x → v1.6.x在测试集群先完整走一遍升级流程确认没问题之后再操作生产集群。升级前一定要确保所有卷都是 healthy 状态备份关键数据保存当前版本的 values.yaml 以及helm get values longhorn -n longhorn-system的输出尽量不要在业务高峰期做这个操作。5.6 别忘了 UI 和 Driver 的高可用配置如果你是生产集群Longhorn 组件的副本数和反亲和策略值得花几分钟调一下。比如longhorn-ui这个 Deployment 默认就一个副本控制节点宕机的时候 UI 就访问不了了。可以把它做一个反亲和让副本分布到两个节点上虽然 UI 本身不是核心数据面但存储管理入口凉了运维会很被动。longhorn-driver-deployer也是 Deployment它负责处理 CSI driver 的注册逻辑如果它挂了新的 Pod 可能无法正常挂载卷。建议把它的副本数也调成多个并且配置 PodDisruptionBudget确保在节点维护期间 driver 始终有可用副本在运行。6. 最后分享一段个人体会先用起来再慢慢调优Longhorn 的部署过程本身并不复杂尤其是有了 Helm 帮助以后一个能跑起来的环境十几分钟就能搭好。但真正考验运维能力的是后续的调优和日常维护。我自己在部署第一套 Longhorn 集群的时候也经历过不少曲折最初也以为装完就算搞定结果用了几天就暴露出一堆环境问题不得不回头把集群重新梳理一遍。这里分享一个我个人比较推荐的工作节奏第一套集群不要追求一步到位先把 PV 创建链路跑通把备份目标接好把监控告警问题解决然后让它以相对保守的配置比如默认 v1 引擎、副本数按节点数来跑个一两周。期间观察卷的性能表现、节点的 CPU 和磁盘占用曲线再结合业务需求去做针对性调整。比如我发现某类业务对读性能要求特别高就专门给它们开了一个longhorn-fastStorageClass底层把dataEngine指定为 v2副本数改为 2数据局部性设为best-effort用的节点也是专门的 NVMe 机器。这样既不会因为全局统一配置导致资源浪费又能让不同业务各取所需。这种“先立后破、逐步加码”的方式比一上来就把所有高级参数全配好要稳得多而且踩坑成本低。存储这东西数据安全永远是第一位的宁可一开始慢一点、保守一点也不要为了追求性能或花哨特性把底层稳定性搭进去。希望这份手册能帮你把 Longhorn 顺利跑起来并且在后续的日子里用得顺手。