1. 项目概述:为什么在 Rancher + k3s 环境里部署 Longhorn 1.0.0 是个务实选择
Longhorn 1.0.0 不是某个“新潮概念”,而是 Kubernetes 生态中第一个真正意义上完成 GA(General Availability)的、专为云原生环境设计的开源分布式块存储系统。它不依赖外部存储硬件,也不绑定特定云厂商,而是把本地磁盘——哪怕是几块旧笔记本硬盘——通过容器化方式组织成高可用、可快照、可备份、可跨节点调度的块存储池。当这个版本遇上 Rancher + k3s 的组合,就构成了一个极简但完整的边缘级到中小规模生产级 K8s 存储栈:k3s 轻量、单二进制、内存占用低,适合嵌入式设备、边缘网关、测试集群甚至开发笔记本;Rancher 提供统一的图形界面、多集群管理、RBAC 和应用商店;而 Longhorn 1.0.0 则补上了 k3s 原生缺失的持久化存储能力——没有它,你连一个带数据库的 WordPress 都跑不稳,更别说 StatefulSet 类应用的滚动更新和故障恢复。
我最早在某高校边缘计算实验室部署这套组合时,目标很实际:用三台二手 NUC 主机(i5-8259U + 16GB RAM + 512GB NVMe)搭建一个能跑 AI 模型训练 Pipeline 的轻量平台。当时试过直接挂载 NFS,结果一遇到节点重启,PVC 就 pending;也试过 Rook/Ceph,编译耗时两小时,部署后监控组件占掉 3GB 内存,完全违背了 k3s “轻”的初衷。直到把 Longhorn 1.0.0 的 Helm Chart 拉下来,执行一条helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace,12 分钟内完成部署,控制台里看到三个节点的磁盘自动聚合、Replica 同步状态绿色、创建 PVC 后 3 秒内绑定成功——那一刻我才意识到,所谓“云原生存储落地难”,很多时候不是技术不行,而是选型没对上真实场景的重量级。
这个组合特别适合三类人:第一类是 DevOps 工程师,手头只有几台物理机或 VPS,想快速搭一个能跑 CI/CD + 数据库 + 日志分析的闭环环境;第二类是边缘 IoT 开发者,在工厂产线、车载终端、农业传感器网关上需要本地可靠存储,又不能依赖中心云;第三类是教学与培训讲师,要在 2 小时内让学生亲手部署一个“有状态应用可弹性伸缩”的 K8s 实例。Longhorn 1.0.0 的价值,不在于它有多“高级”,而在于它把存储的复杂性封装得足够薄——你不需要懂 Raft 协议怎么选举 Leader,不需要调优 Ceph 的 crush map,甚至不需要手动分区格式化磁盘。它默认只用/var/lib/longhorn/这个路径,自动发现可用空间,Replica 数默认设为 3,快照保留数默认为 25,所有这些参数背后都有大量真实集群压测数据支撑。换句话说,它不是给你一堆开关让你调,而是把“大多数情况该怎么做”这件事,已经帮你做完了。
2. 整体架构设计与方案选型逻辑
2.1 为什么是 Longhorn 1.0.0,而不是更高或更低版本?
Longhorn 在 1.0.0 版本之前,比如 0.8.x 系列,虽然功能已基本成型,但存在几个硬伤:一是 CSI Driver 的 VolumeAttachment 生命周期管理不稳定,偶尔出现 PVC 绑定后 Pod 启动失败,日志里报failed to attach volume: timeout;二是 UI 中的快照清理逻辑有竞态条件,批量删除快照时可能卡住整个 UI;三是备份到 S3 兼容存储时,若网络抖动超过 45 秒,备份任务会直接失败且不重试。这些问题在 1.0.0 中被系统性修复:CSI 插件重构为独立 DaemonSet,VolumeAttachment 状态同步改用 Informer 缓存机制,快照清理引入幂等队列,S3 备份增加指数退避重试(最多 5 次,间隔从 2s 递增至 32s)。更重要的是,1.0.0 是第一个通过 CNCF 官方一致性认证的 Longhorn 版本,意味着它能 100% 兼容 Kubernetes 1.16–1.20 的所有 CSI 接口规范——这在 Rancher 管理多个不同 K8s 版本集群时,是决定性的兼容保障。
至于为什么不直接上 1.5.x 或更新版?因为 1.0.0 是 Longhorn 的“稳定基线锚点”。后续版本新增了如 DR(Disaster Recovery)卷、跨集群备份、加密卷等功能,但这些特性在中小规模场景中属于“锦上添花”。而 1.0.0 的代码体积仅 12MB(镜像解压后),启动内存峰值 <180MB,Controller 容器 CPU limit 设为 200m 即可稳压;相比之下,1.5.x 的镜像体积涨到 28MB,Controller 内存占用翻倍,且引入了额外的 backup-target-operator 组件,增加了运维面。我在某公司内部 CI 流水线中做过对比测试:同样三节点 k3s 集群(每节点 4C8G),部署 Longhorn 1.0.0 后,集群整体资源开销增加 3.2%,而 1.5.x 增加 7.9%。对于内存敏感的边缘设备,这 4.7% 的差异,可能就是能否同时跑起 Grafana + Prometheus + Alertmanager 的分水岭。
2.2 为什么必须搭配 k3s,而不是 k8s 或 microk8s?
k3s 是 Rancher 团队专门为边缘和轻量场景打造的 K8s 发行版,它的核心设计哲学是“减法”:移除所有非必要组件(如 cloud-controller-manager、kube-proxy 的 iptables 模式被替换为更轻量的 IPVS)、用 sqlite 替代 etcd 作为默认后端、所有组件打包进单个二进制文件。这意味着你不需要单独维护 etcd 集群,不需要配置 kube-proxy 参数,甚至不需要写 systemd unit 文件——curl -sfL https://get.k3s.io | sh -一行命令就能拉起一个可工作的集群。而 Longhorn 正好吃透了这个“减法红利”:它的 Manager 组件默认监听localhost:9500,不对外暴露,只与本地 kubelet 通信;Replica 进程直接读写本地磁盘,不走网络协议栈;Backup Target 使用 HTTP+JSON API,而非复杂的 gRPC 流式传输。这种“本地优先、协议极简”的设计,与 k3s 的轻量基因天然契合。
反观标准 k8s:etcd 默认使用 WAL 日志落盘,频繁写入 SSD 会加速磨损;kube-proxy 的 iptables 规则在节点规模 >50 时性能陡降;NodePort 服务在多网卡环境下需手动指定--node-ip,否则流量转发异常。microk8s 虽然也轻量,但它强制使用 LXD 容器运行时,而 Longhorn 的 Replica 进程需要直接访问/dev/下的块设备,LXD 的设备映射层会拦截部分 ioctl 调用,导致磁盘健康检测失败。我在某智能充电桩项目中实测过:microk8s + Longhorn 1.0.0 部署后,longhorn-manager日志持续报错failed to get device info for /dev/sdb: operation not permitted,切换到 k3s 后该错误消失。根本原因在于 k3s 默认使用 containerd 运行时,并允许通过--privileged标志授予容器完整设备访问权限,而 microk8s 的 LXD 安全策略对此限制更严。
2.3 为什么必须经由 Rancher 管理,而不是裸装?
Rancher 在这里扮演的不是“锦上添花”的 UI 角色,而是关键的“抽象层”和“策略中枢”。首先,Longhorn 自身提供 Web UI,但它只管 Longhorn 命名空间内的资源(Volume、Engine、Replica),无法看到 PVC/PV 如何被上层应用(如 MySQL StatefulSet)引用。而 Rancher 的 Cluster Explorer 页面,能把 PVC、PV、StorageClass、Longhorn Volume、Pod 这五层资源关系,用一张拓扑图直观串起来——当你发现某个 MySQL Pod 无法启动时,点开 PVC,再点开关联的 Longhorn Volume,立刻能看到 Replica 是否同步完成、是否有节点离线、快照是否占满空间。这种跨层级的可观测性,是 Longhorn 原生 UI 无法提供的。
其次,Rancher 提供了 StorageClass 的策略模板能力。比如你可以定义一个名为longhorn-replica-3的 StorageClass,其中parameters字段预置:
numberOfReplicas: "3" staleReplicaTimeout: "2880" # 48小时 diskSelector: "[ssd]"然后在应用 YAML 中只需写storageClassName: longhorn-replica-3,无需每次重复配置。更重要的是,Rancher 支持基于命名空间的 StorageClass 白名单:你可以在dev命名空间只允许使用longhorn-replica-1(节省资源),而在prod命名空间强制使用longhorn-replica-3(保障高可用)。这种策略级管控,在裸装 Longhorn 时只能靠 RBAC + 准入控制器(Admission Controller)硬编码实现,而 Rancher 把它变成了图形界面上拖拽即可生效的配置项。
最后,Rancher 的 App Catalog(应用商店)集成了 Longhorn 的 Helm Chart,版本锁定在 1.0.0,并预置了针对 k3s 的适配参数(如自动禁用serviceMonitor,因为 k3s 默认不装 Prometheus Operator)。你不需要去 GitHub 找 Chart,不需要手动修改values.yaml,点击安装即完成——这对非专业运维人员来说,是降低使用门槛的关键一跳。
3. 核心细节解析与实操要点
3.1 磁盘准备:不是所有“空闲空间”都适合 Longhorn
Longhorn 对底层磁盘的要求,远比你想象中具体。它不关心你用的是 SATA SSD 还是 NVMe,但极度在意磁盘的“行为一致性”。我见过太多人栽在第一步:在一台旧服务器上,df -h显示/dev/sdb还剩 1.2TB 空间,兴冲冲执行longhorn-manager,结果日志里疯狂刷failed to create replica directory: permission denied。排查半天才发现,这块盘是之前用 LVM 创建过逻辑卷,虽然lvremove删除了 LV,但 PV 元数据仍残留在磁盘开头 1MB 区域,Longhorn 的磁盘扫描器读取到非法签名,直接拒绝挂载。
正确的磁盘准备流程必须包含四个不可跳过的步骤:
卸载并清空分区表:
umount /dev/sdb* wipefs -a /dev/sdb # 彻底清除所有文件系统签名验证磁盘是否“干净”:
fdisk -l /dev/sdb | grep "Disk label" # 应输出空行 blkid /dev/sdb # 应无任何输出设置 I/O 调度器为 none(SSD)或 deadline(HDD):
echo none > /sys/block/sdb/queue/scheduler # SSD 必须设为 none # HDD 可设为 deadline:echo deadline > /sys/block/sdb/queue/scheduler提示:k3s 节点若启用了 systemd-boot,需在
/boot/cmdline.txt中添加elevator=none参数,否则重启后调度器会恢复为默认 cfq。关闭磁盘写缓存(关键!):
hdparm -W0 /dev/sdb # 禁用硬件写缓存这一步常被忽略,但极其重要。Longhorn 的 Replica 同步依赖于磁盘的
fsync()调用能真正落盘。如果开启写缓存,断电时未刷入 NAND 的数据会丢失,导致两个 Replica 数据不一致,触发 Longhorn 的自动修复机制,反而引发 IO 飙升。我在某物流分拣系统中就因此遭遇过:UPS 断电后,三节点集群中两个节点的 Replica 数据校验失败,Longhorn 启动全量同步,持续 6 小时,期间订单数据库响应延迟从 12ms 涨到 2.3s。
3.2 Longhorn 1.0.0 的核心参数详解与安全阈值
Longhorn 1.0.0 的settings配置项共 32 个,但真正影响生产稳定性的核心参数只有 7 个。它们不是“可调可不调”,而是必须根据你的硬件规格显式设置,否则 Longhorn 会使用保守默认值,导致性能浪费或稳定性风险。
| 参数名 | 默认值 | 推荐值(3节点NVMe集群) | 说明 |
|---|---|---|---|
default-replica-count | 3 | 3 | Replica 数必须为奇数,且 ≤ 集群节点数。设为 4 会导致某个节点永远存不下 Replica,浪费空间。 |
backup-target | "" | s3://longhorn-backup@cn-north-1/?region=cn-north-1&endpoint=https://s3.cn-north-1.amazonaws.com.cn | S3 兼容存储地址。注意末尾不能带/,且 region 和 endpoint 必须匹配,否则备份任务卡在Creating backup状态。 |
backup-target-credential-secret | "" | longhorn-s3-secret | 必须提前创建 Secret,Key 名固定为aws_access_key_id和aws_secret_access_key。Longhorn 不支持 IAM Role。 |
create-default-disk-labeled-nodes | true | true | 自动将所有带node.longhorn.io/create-default-disk=trueLabel 的节点,挂载/var/lib/longhorn/目录作为默认磁盘。这是最安全的磁盘注册方式。 |
default-data-path | /var/lib/longhorn/ | /data/longhorn/ | 强烈建议修改!避免与 k3s 的/var/lib/rancher/k3s/目录混用同一块盘,防止 IO 争抢。 |
guaranteed-engine-cpu | 0.25 | 0.5 | Engine 进程(处理 IO 请求)的 CPU 保底。NVMe 盘需至少 0.5,否则高并发写入时 Engine 会因 CPU 不足丢请求。 |
storage-minimal-available-percentage | 10 | 25 | 当磁盘可用空间 <25% 时,Longhorn 自动拒绝新 Volume 创建,并标记现有 Volume 为Degraded。防止空间耗尽导致 Replica 同步失败。 |
其中guaranteed-engine-cpu的设置需要一点计算:Engine 进程本质是一个 Go 程序,每个 Volume 对应一个 goroutine,处理读写请求。k3s 默认给longhorn-engineDeployment 设置的 CPU request 是 250m(即 0.25 核),但在 1.0.0 中,这个值是硬编码在源码里的。如果你的节点有 4 核 CPU,且计划部署 10 个 Volume,那么总 CPU 需求 = 10 × 0.5 = 5 核,显然超限。此时必须修改longhorn-manager的 Deployment,将spec.template.spec.containers[0].resources.requests.cpu改为500m,并确保guaranteed-engine-cpu设为0.5,让每个 Engine 都能分到足额算力。
3.3 Rancher 中的 StorageClass 与 PVC 绑定原理
很多人以为 PVC 绑定 Longhorn Volume 是“自动发生”的,其实背后有一套严谨的调度链路。理解它,才能精准排障。
整个过程分为四步:
- 用户创建 PVC:指定
storageClassName: longhorn,resources.requests.storage: 10Gi; - Kubernetes Scheduler 触发 Provisioner:Rancher 会将 PVC 转发给
longhorn.csi.dell.com这个 CSI Driver; - CSI Driver 调用 Longhorn Manager API:Manager 根据
default-replica-count=3,在集群中寻找 3 个满足条件的节点(磁盘空间 ≥10Gi、节点状态 Ready、Label 匹配); - Manager 创建 Volume 并返回 PV:生成 PV 对象,
spec.csi.volumeHandle字段填入 Longhorn Volume ID(如pvc-abc123),PVC 的spec.volumeName自动填充为该 PV 名。
关键点在于第 3 步的“条件筛选”。Longhorn Manager 不会随机选节点,而是按以下优先级排序:
- 第一优先级:节点磁盘剩余空间 / 总空间 比值最高者(避免某节点磁盘被撑爆);
- 第二优先级:节点上已存在的 Replica 数最少者(均衡负载);
- 第三优先级:节点 Label 中
node.longhorn.io/allow-scheduling=true为 true(手动控制调度范围)。
所以,如果你发现 PVC 总是绑定到同一个节点,大概率是其他节点磁盘空间不足,或者被打了node.longhorn.io/allow-scheduling=false的 Label。检查命令:
# 查看各节点磁盘使用率 kubectl get nodes -o wide | awk '{print $1, $7}' | while read node ip; do echo "$node: $(kubectl get node $node -o jsonpath='{.status.allocatable.ephemeral-storage}')" ; done # 查看节点 Label kubectl get nodes --show-labels | grep longhorn注意:Longhorn 1.0.0 的 Volume 创建是“同步阻塞”的。如果 Manager 在 30 秒内找不到 3 个合格节点,PVC 会一直处于
Pending状态,且不会自动重试。此时必须手动删除 PVC,调整节点状态后再重试。
4. 实操过程与核心环节实现
4.1 从零开始:k3s + Rancher + Longhorn 1.0.0 全流程部署
整个部署过程严格遵循“先底层、再中间件、最后上层”的顺序,任何一步跳过都会导致后续失败。以下是我在某制造企业 MES 系统迁移项目中验证过的、100% 可复现的步骤(以 Ubuntu 20.04 为例):
Step 1:准备三台节点,统一基础环境
# 关闭 swap(Longhorn 要求) sudo swapoff -a sudo sed -i '/ swap / s/^/#/' /etc/fstab # 加载 required kernel modules sudo modprobe br_netfilter sudo modprobe overlay # 配置 sysctl cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF sudo sysctl --system # 安装 containerd(k3s 1.20+ 默认使用) sudo apt-get update && sudo apt-get install -y containerd sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo systemctl restart containerdStep 2:部署 k3s Server(主节点)
# 安装 k3s,禁用 traefik(Rancher 自带 ingress) curl -sfL https://get.k3s.io | \ INSTALL_K3S_VERSION=v1.20.15+k3s1 \ sh -s - --disable traefik --write-kubeconfig-mode 644 # 获取 token 用于 agent 加入 sudo cat /var/lib/rancher/k3s/server/node-token # 配置 kubectl export KUBECONFIG=/etc/rancher/k3s/k3s.yamlStep 3:部署 k3s Agent(工作节点)
# 在另外两台机器上执行,替换 {SERVER_IP} 和 {NODE_TOKEN} curl -sfL https://get.k3s.io | \ INSTALL_K3S_VERSION=v1.20.15+k3s1 \ sh -s - --server https://{SERVER_IP}:6443 \ --token {NODE_TOKEN} \ --write-kubeconfig-mode 644Step 4:安装 Rancher Server
# 创建 rancher namespace kubectl create namespace cattle-system # 添加 Helm repo helm repo add rancher-stable https://releases.rancher.com/server-charts/stable helm repo update # 安装 Rancher(使用自签名证书,生产环境请换为 Let's Encrypt) helm install rancher rancher-stable/rancher \ --namespace cattle-system \ --set hostname=rancher.example.com \ --set ingress.tls.source=secret \ --set replicas=1Step 5:在 Rancher UI 中导入 k3s 集群
- 访问
https://rancher.example.com,首次登录用admin+kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}{{"\n"}}'获取密码; - 进入 Cluster Management → Create → Import Existing Cluster;
- 复制页面提供的
kubectl apply -f命令,在 k3s Server 节点执行; - 等待集群状态变为 Active(约 2 分钟)。
Step 6:通过 Rancher App Catalog 安装 Longhorn 1.0.0
- 进入 Cluster Explorer → Apps → Charts;
- 搜索
longhorn,选择longhornChart(不是longhorn-crd); - 点击 Install,Version 选择
1.0.0; - 在
Customize页签中,展开Advanced Options:global.storageClass.defaultDataPath:/data/longhorn/longhorn.enableDefaultStorageClass:truelonghorn.defaultReplicaCount:3
- 点击 Install,等待所有 Pod 状态为 Running(约 5 分钟)。
实操心得:整个流程中最容易卡住的是 Step 6 的 Helm Release。如果
longhorn-managerPod 一直 CrashLoopBackOff,请立即执行kubectl logs -n longhorn-system deploy/longhorn-manager,90% 的情况是磁盘路径/data/longhorn/不存在或权限不对。此时不要删 Helm Release,而是进入对应节点,执行sudo mkdir -p /data/longhorn && sudo chown -R 100:101 /data/longhorn(100:101 是 longhorn-manager 的默认 UID:GID),然后kubectl rollout restart deploy -n longhorn-system longhorn-manager。
4.2 创建首个 MySQL StatefulSet:验证存储可靠性
部署完 Longhorn,必须用一个真实的有状态应用来验证其可靠性。MySQL 是最佳选择,因为它对 IO 延迟、数据一致性、故障恢复速度极为敏感。
YAML 文件mysql-statefulset.yaml:
apiVersion: v1 kind: Service metadata: name: mysql labels: app: mysql spec: ports: - port: 3306 name: mysql clusterIP: None selector: app: mysql --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: selector: matchLabels: app: mysql serviceName: "mysql" replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 env: value: "password" ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim volumeClaimTemplates: - metadata: name: mysql-pv-claim spec: accessModes: ["ReadWriteOnce"] storageClassName: "longhorn" # 关键:指向 Longhorn StorageClass resources: requests: storage: 5Gi部署后,执行以下验证步骤:
检查 PVC 绑定状态:
kubectl get pvc # 输出应为:mysql-pv-claim Bound pvc-xxxxxx 5Gi RWO longhorn 2m进入 Pod,写入测试数据:
kubectl exec -it mysql-0 -- mysql -uroot -ppassword -e "CREATE DATABASE testdb;" kubectl exec -it mysql-0 -- mysql -uroot -ppassword testdb -e "CREATE TABLE t1(id INT); INSERT INTO t1 VALUES(1),(2),(3);"模拟节点宕机:
sudo shutdown -h now关闭运行mysql-0的节点;观察自动恢复:约 45 秒后,
kubectl get pods显示mysql-0重新调度到另一节点,且kubectl exec mysql-0 -- mysql -uroot -ppassword testdb -e "SELECT * FROM t1;"仍能查出三行数据。
这个测试验证了 Longhorn 的三个核心能力:PVC 的跨节点可迁移性、Replica 的自动故障转移、Volume 数据的强一致性。如果第 4 步失败(查不到数据),说明 Replica 同步未完成,需检查kubectl get volumes.longhorn.io -n longhorn-system中对应 Volume 的State是否为attached,Robustness是否为healthy。
4.3 备份与恢复实战:S3 兼容存储接入
Longhorn 1.0.0 的备份功能不是“噱头”,而是经过生产验证的救命稻草。某次某公司财务系统因误操作清空了 MySQL 表,正是靠 Longhorn 的 3 小时前快照,在 8 分钟内完成了全库恢复。
Step 1:创建 S3 兼容存储的 Secret
kubectl create secret generic longhorn-s3-secret \ --from-literal=aws-access-key-id="YOUR_ACCESS_KEY" \ --from-literal=aws-secret-access-key="YOUR_SECRET_KEY" \ -n longhorn-systemStep 2:在 Rancher UI 中配置 Backup Target
- 进入 Cluster Explorer → Storage → Longhorn → Settings;
- 找到
backup-target,填入 S3 Endpoint(如s3://longhorn-backup@us-east-1/?region=us-east-1&endpoint=https://s3.us-east-1.amazonaws.com); - 找到
backup-target-credential-secret,填入longhorn-s3-secret; - 保存后,Longhorn Manager 会自动连接 S3 并创建
longhorn-backupBucket(若不存在)。
Step 3:手动触发一次备份
- 进入 Longhorn UI(Cluster Explorer → Storage → Longhorn → Volumes);
- 找到你的 MySQL Volume,点击
Create Backup; - 填写备份名称(如
mysql-pre-deploy-20231001),点击 Create; - 状态变为
Completed后,进入 S3 控制台,确认longhorn-backup/backupstore/volumes/.../下有.zip和.json文件。
Step 4:灾难恢复演练
- 删除 MySQL StatefulSet 和 PVC(保留 PV);
- 进入 Longhorn UI,找到刚才的 Backup,点击
Restore; - 输入新 Volume 名(如
mysql-restored),选择恢复到哪个节点; - 等待状态变为
attached; - 创建新的 PVC,
spec.dataSource指向该 restored Volume; - 重新部署 MySQL StatefulSet,挂载新 PVC。
整个恢复过程平均耗时 3 分 20 秒(5Gi 数据),比传统 mysqldump + restore 快 6 倍。关键是,它恢复的是 Block Level 快照,不依赖 MySQL 的 binlog 或 redo log,即使数据库处于崩溃状态也能恢复。
5. 常见问题与排查技巧实录
5.1 PVC 长时间 Pending:不只是“没空间”那么简单
PVC Pending 是 Longhorn 最常见的表象问题,但根因千差万别。我整理了 7 类高频场景及对应排查命令,按出现概率排序:
| 现象 | 根本原因 | 排查命令 | 解决方案 |
|---|---|---|---|
Waiting for a volume to be created, finally time out | Longhorn Manager 未就绪 | kubectl get pods -n longhorn-system | 等待所有 Manager Pod Running,或检查其日志kubectl logs -n longhorn-system deploy/longhorn-manager |
no available topology | 节点未打 Label 或磁盘未注册 | kubectl get nodes --show-labels | grep longhornkubectl get disks.longhorn.io -A | 给节点打 Labelkubectl label node NODE_NAME node.longhorn.io/create-default-disk=true,并确认/data/longhorn/目录存在 |
provisioning failed: failed to get default disk | default-data-path路径不存在或权限不足 | kubectl exec -n longhorn-system longhorn-manager-xxxxx -- ls -l /data/longhorn/ | 在对应节点执行sudo mkdir -p /data/longhorn && sudo chown -R 100:101 /data/longhorn |
volume is not ready | Replica 同步中,但网络延迟高 | kubectl get engines.longhorn.io -n longhorn-system | 检查Status.currentImage是否为longhornio/longhorn-engine:v1.0.0,若为v0.8.1则需升级 Engine Image |
no healthy replica | 某个 Replica 所在节点宕机且未恢复 | kubectl get replicas.longhorn.io -n longhorn-system -o wide | 等待节点恢复,或手动删除失效 Replicakubectl delete replica -n longhorn-system REPLICA_NAME |
timeout waiting for volume | k3s kubelet 与 Longhorn CSI Driver 通信超时 | kubectl get csinodes | 重启 kubeletsudo systemctl restart k3s,并检查/var/lib/rancher/k3s/agent/etc/cni/net.d/下是否有重复 cni 配置 |
invalid storage class | PVC 中storageClassName拼写错误 | kubectl get sc | 确认 StorageClass 名为longhorn(默认),而非longhorn-storage或longhorn-sc |
实操心得:我曾在一个客户现场连续三天解决不了 PVC Pending,最后发现是 Rancher 的 Cluster Explorer 页面缓存了旧的 StorageClass 列表,实际
kubectl get sc显示longhorn已被删除。强制刷新浏览器(Ctrl+F5)后问题消失。这提醒我们:一切以kubectl命令行输出为准,UI 只是辅助。
5.2 Replica 同步慢:IO 瓶颈的定位与优化
Longhorn 的 Replica 同步速度,直接受限于三方面:源节点磁盘写入速度、网络带宽、目标节点磁盘写入速度。1.0.0 版本中,同步默认使用 rsync over SSH,但实际是 Longhorn 自研的基于 TCP 的流式复制协议,单流带宽上限约 120MB/s(万兆网卡)。
要判断瓶颈在哪,用这组命令:
# 查看同步实时速率(单位:MB/s) kubectl get volumes.longhorn.io -n longhorn-system NAME -o jsonpath='{.status.replicationStatus[].progress}' # 查看源节点磁盘 IO(关注 %util 和 await) iostat -x 1 3 | grep sdb # 查看网络连接状态(确认是否建立长连接) ss -tnp | grep :9500 # 查看目标节点磁盘 IO kubectl exec -n longhorn-system longhorn-manager-xxxxx -- iostat -x 1 3 | grep sdc常见优化手段:
- 网络层面:确保所有节点在同一二层网络,关闭 TCP BBR(
echo 'net.core.default_qdisc=fq' >> /etc/sysctl.conf && echo 'net.ipv4.tcp_congestion_control=bic' >> /etc/sysctl.conf),因为 Longhorn 复制协议对 BBR 的拥塞窗口激进增长不友好; - 磁盘层面:对 NVMe 盘,启用多队列:
echo 'nvme_core.default_ps_max_latency_us=0' > /etc/default/grub,然后update-grub && reboot; - Longhorn 层面:修改
concurrent-replica-count参数(默认 5),在 10G 网络下可提到 10,但需同步调高guaranteed-engine-cpu。
5.3 备份失败:S3 权限与网络的双重校验
S3 备份失败的错误日志往往含糊其辞,如failed to upload backup。必须分两层验证:
第一层:S3 权限校验
- 使用
aws-cli在 Longhorn Manager Pod 内测试:kubectl exec -n longhorn-system longhorn-manager-xxxxx -- sh -c " apk add aws-cli && aws s3 ls s3://longhorn-backup/ --endpoint-url https://s3.us-east-1.amazonaws.com " - 若报
AccessDenied,检查 Secret 中的 Key 是否