本指南专为 1 主 2 从(3 节点) 的 Kubernetes 集群设计,旨在构建一个高可用、支持动态供给的分布式存储系统。


📋 核心概念速览

在开始之前,了解几个关键概念有助于理解后续操作:

  • StorageClass (存储类): 定义存储的“模板”(如副本数、性能策略)。K8s 通过它实现动态供给
  • PVC (PersistentVolumeClaim): 用户提出的“存储申请单”(我要 10G 空间)。
  • PV (PersistentVolume): 实际分配出来的“存储资源”,由 StorageClass 自动创建。
  • Replica (副本): Longhorn 会将你的数据复制多份(默认 3 份),分散在不同节点,防止单点故障。
  • Degraded (降级): 当实际副本数 < 设定副本数时的状态(例如设定 3 份,但只成功了 2 份)。数据依然可用,但冗余度降低。

1️⃣ 前置准备:安装系统依赖

Longhorn 基于 iSCSI 协议提供块存储,因此集群中的每一个节点(包括 Master)都必须安装 open-iscsi 发起器。

🛠️ 操作步骤

请在 Master、Worker1、Worker2 所有节点上分别执行以下命令:

Ubuntu / Debian 系统
# 1. 更新软件源
sudo apt-get update

# 2. 安装 open-iscsi (核心依赖) 和 nfs-common (辅助依赖)
sudo apt-get install -y open-iscsi nfs-common

# 3. 启动服务并设置开机自启
# 解释:ensure iscsid daemon runs on boot and starts now
sudo systemctl enable iscsid
sudo systemctl start iscsid

# 4. 【验证步骤】检查服务状态
# 预期输出应包含 "active (running)"
systemctl status iscsid
CentOS / RHEL / Rocky Linux 系统
# 1. 安装依赖包
sudo yum install -y iscsi-initiator-utils nfs-utils

# 2. 启动服务
sudo systemctl enable iscsid
sudo systemctl start iscsid

# 3. 【验证步骤】
systemctl status iscsid

💡 原理解释:如果没有安装这个服务,当 Pod 尝试挂载 Longhorn 卷时,K8s 节点无法识别 iSCSI 设备,Pod 会卡在 ContainerCreating 状态并报错 mount failed


2️⃣ 部署 Longhorn

🚀 方法 A:一键部署(推荐)

官方 YAML 文件已经内置了大多数场景所需的配置,包括对 Master 节点常见污点(Taints)的容忍度。

# 应用官方最新稳定版 (v1.7.0)
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.7.0/deploy/longhorn.yaml

🔧 方法 B:处理调度失败(如果 Master 节点没跑起来)

如果在部署后发现 Master 节点上没有 longhorn-manager Pod,说明集群的污点比较特殊。我们需要手动添加容忍度。

  1. 下载配置文件
curl -L https://raw.githubusercontent.com/longhorn/longhorn/v1.7.0/deploy/longhorn.yaml -o longhorn-custom.yaml
  1. 编辑文件 (vim longhorn-custom.yaml):
    找到 kind: DaemonSetname: longhorn-manager 的部分,在 spec.template.spec 层级下,确保 tolerations 包含以下内容:
tolerations:
  # 容忍新版 K8s 的控制平面污点
  - key: "node-role.kubernetes.io/control-plane"
    operator: "Exists"
    effect: "NoSchedule"
  # 容忍旧版 K8s 的 master 污点
  - key: "node-role.kubernetes.io/master"
    operator: "Exists"
    effect: "NoSchedule"
  # 容忍云厂商未初始化污点
  - key: "node.cloudprovider.kubernetes.io/uninitialized"
    operator: "Exists"
    effect: "NoSchedule"

注意:tolerations 必须与 containers 平级,缩进要正确。

  1. 应用配置
kubectl apply -f longhorn-custom.yaml

✅ 验证部署状态

关键检查点:确认 longhorn-manager 是否在 所有 3 个节点 上都运行了。

kubectl get pods -n longhorn-system -o wide

成功标准
你应该看到 3 个 longhorn-manager-xxx Pod,它们的 NODE 列分别对应:

  1. master
  2. work1
  3. work2

如果某个节点缺失,请检查该节点的 iscsid 服务或查看 Pod 日志 (kubectl logs -n longhorn-system <pod-name>)。


3️⃣ 访问 Longhorn 管理界面 (UI)

Longhorn 提供了一个强大的 Web UI 用于监控和管理存储。默认服务类型是 ClusterIP(仅限集群内访问)。

🌐 方式一:端口转发(最安全,适合临时调试)

在你的本地电脑终端执行(需要本地配置了 kubectl):

kubectl -n longhorn-system port-forward svc/longhorn-frontend 8080:80

然后在浏览器访问:http://localhost:8080

💡 提示:如果你是在远程服务器上操作且没有本地 kubectl,可以使用 SSH 隧道:
ssh -L 8080:10.96.x.x:80 root@<Master-IP> (其中 10.96.x.x 是 kubectl get svc -n longhorn-system 查到的 longhorn-frontend IP)。

🌍 方式二:配置 Ingress(适合生产/长期访问)

如果你集群内有 Nginx Ingress Controller,可以配置域名访问。

创建 longhorn-ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: longhorn-ingress
  namespace: longhorn-system
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: longhorn.example.com  # 替换为你的实际域名
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: longhorn-frontend
            port:
              number: 80

应用后,解析域名到 Ingress IP 即可访问。


4️⃣ 实战测试:动态存储供给

我们将部署一个 Nginx 应用,它会自动触发 PVC 创建,验证“动态供给”功能。

📝 创建测试清单

创建文件 nginx-test.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-longhorn-test
  labels:
    app: nginx-longhorn
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-longhorn
  template:
    metadata:
      labels:
        app: nginx-longhorn
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        volumeMounts:
        # 将存储卷挂载到 Nginx 的网页目录
        - name: data-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: data-volume
        persistentVolumeClaim:
          claimName: longhorn-dynamic-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: longhorn-dynamic-pvc
spec:
  accessModes:
    - ReadWriteOnce  # 读写模式:单节点读写
  # 不指定 storageClassName,K8s 会自动使用标记为 (default) 的 'longhorn' 类
  resources:
    requests:
      storage: 1Gi   # 申请 1GB 空间

🏃 执行与验证

  1. 部署应用
kubectl apply -f nginx-test.yaml
  1. 观察状态变化
# 监视 PVC 状态,应从 Pending -> Bound
kubectl get pvc longhorn-dynamic-pvc -w

# 监视 Pod 状态,应从 ContainerCreating -> Running
kubectl get pods -l app=nginx-longhorn -w

💡 原理解释:当你创建 PVC 时,K8s 发现没有对应的 PV。它会查找默认的 StorageClass (longhorn),调用 Longhorn 的 CSI Provisioner。Provisioner 会在后台创建 3 个副本(分布在 3 个节点),生成 PV,并绑定给 PVC。全过程无需人工干预。

  1. 写入测试数据
kubectl exec -it deploy/nginx-longhorn-test -- bash -c "echo '<h1>Hello from Longhorn HA Storage!</h1>' > /usr/share/nginx/html/index.html"
  1. 验证持久化(模拟故障)
    删除 Pod,让 K8s 重新调度一个新的 Pod。如果存储是持久的,新 Pod 应该能读到刚才写的文件。
# 删除 Pod
kubectl delete pod -l app=nginx-longhorn

# 等待新 Pod 运行 (约 10-20 秒)
kubectl get pods -l app=nginx-longhorn -w

# 再次读取文件
kubectl exec -it deploy/nginx-longhorn-test -- cat /usr/share/nginx/html/index.html

成功标志:输出依然是 <h1>Hello from Longhorn HA Storage!</h1>


5️⃣ 故障排查与深度优化

⚠️ 常见问题:Volume 状态显示 Degraded (降级)

现象:在 UI 中看到卷状态为黄色 Degraded,提示 Scheduling Failure
原因:Longhorn 默认策略是 3 副本。如果你的集群只有 2 个节点可用,或者某个节点磁盘空间不足(小于预留空间 + 卷大小),第 3 个副本就无法创建,导致状态降级。

解决方案

  1. 检查磁盘空间
    • 进入 UI -> Node
    • 点击节点名称,查看 Storage Available 是否大于 Storage Reserved
    • 如果空间紧张,点击 Edit Disk,将 Storage Reserved 调小(例如从 7Gi 改为 2Gi),保存。
  1. 手动修复副本
    • 如果空间足够但依然报错,可能是调度器卡住。
    • 进入 UI -> Volume -> 点击故障卷。
    • 删除那个灰色的、失败的 Replica。
    • 点击 Add Replica,手动选择缺失的那个节点(如 master),强制添加。
  1. 验证恢复
    • 操作后,卷状态应在几秒内变为绿色 Healthy
    • Replicas 列表中确认有 3 个蓝色健康的副本,分别位于 3 个不同节点。

🔍 如何查看数据物理位置?

如果你想确认数据真的存在磁盘上:

  1. 逻辑查看(在 Pod 内):
kubectl exec -it <pod-name> -- ls -lh /usr/share/nginx/html
  1. 物理查看(在节点上):
    • 在 UI 的 Volume 详情页,记下 Replica 的路径(例如 /var/lib/longhorn/replicas/pvc-xxx...)。
    • SSH 登录对应节点,进入该目录:
cd /var/lib/longhorn/replicas/pvc-xxx...
ls -lh
    • 你会看到 volume-head-000.img 等文件,你的数据就以二进制形式存储在这个镜像文件中。

🎉 总结

至此,你已经成功完成:

  1. ✅ 在 3 节点集群上部署了 Longhorn。
  2. ✅ 实现了 Master 节点参与存储(3 副本高可用)。
  3. ✅ 验证了 PVC 的动态创建数据持久化
  4. ✅ 掌握了 UI 监控和故障修复方法。

你的 Kubernetes 集群现在拥有了生产级的分布式存储能力,可以安心部署数据库、中间件等有状态应用了!

Logo

更多推荐