«

K8S 部署Longhorn(云原生分布式块存储解决方案)

myluzh 发布于 阅读:23 Kubernetes


0x00 前言

Longhorn 是 Kubernetes 里的分布式块存储,主要用来给 PVC 提供持久化存储。它不需要单独部署 Ceph 这种重型存储集群,直接使用各个 worker 节点上的本地磁盘,然后通过副本机制把数据分散到不同节点上。

我这里选择 Longhorn,主要是因为这几个点:

Longhorn 的核心不是“共享一个目录”,而是“每个卷有多个副本”。比如一个 5Gi 的 PVC,如果副本数是 2,Longhorn 会保存两份数据。最好让这两个副本落在不同节点或者不同磁盘上。

副本数可以简单这样理解:

副本数 实际占用 容错能力 适合场景
1 PVC 容量 x 1 没有节点级容错 测试环境
2 PVC 容量 x 2 允许丢一个副本 小集群常用
3 PVC 容量 x 3 容错更好 节点数和磁盘空间充足时

容量按副本数计算:

实际占用容量 = PVC 容量 x 副本数
可用容量约等于 = Longhorn 总磁盘容量 / 副本数

比如两个 worker 节点,每个节点给 Longhorn 准备 500Gi 磁盘:

Longhorn 总容量 = 500Gi x 2 = 1000Gi
副本数 = 2
理论可用容量约等于 1000Gi / 2 = 500Gi

实际可用容量还要扣掉系统保留空间、Longhorn 调度预留空间、快照、备份和临时重建副本需要的空间,所以不要按满盘规划。

副本数不要乱设。两个 worker 节点就不要强行设 3 副本,副本调度不满,卷容易长期处于 Degraded。如果只有一个 worker 节点,那 Longhorn 只能提供本地盘能力,不能提供节点级容错。

还有一个比较重要的点:Longhorn 默认数据路径是:

/var/lib/longhorn

正式用不建议直接拿系统盘跑 Longhorn。最好提前准备一块单独的数据盘,挂载到 /var/lib/longhorn,然后再部署 Longhorn。这样系统盘和存储盘分开,后面排查、扩容、重装系统都更清楚。

0x01 部署前处理

每个需要承载 Longhorn 数据的 worker 节点都先准备好挂载目录:

mkdir -p /var/lib/longhorn

示例:把单独的数据盘挂载到 Longhorn 默认目录:

mount /dev/sdb1 /var/lib/longhorn

再写入 /etc/fstab 固化挂载:

blkid /dev/sdb1

vi /etc/fstab
UUID=这里替换成实际UUID  /var/lib/longhorn  ext4  defaults,noatime  0  2

确认挂载没问题:

df -h /var/lib/longhorn

如果 Longhorn 已经运行了一段时间,再去移动 /var/lib/longhorn,不要直接复制目录硬搬。应该先在 Longhorn UI 里禁用调度、驱逐副本,等数据迁移完成后再调整磁盘路径。

Longhorn 还依赖节点上的 iSCSI 工具。如果系统是 Debian/Ubuntu,可以先装:

apt install -y open-iscsi nfs-common
systemctl enable --now iscsid

如果系统是 CentOS/RHEL,可以先装:

yum install -y iscsi-initiator-utils nfs-utils
systemctl enable --now iscsid

其中 nfs-common / nfs-utils 主要用于 Longhorn RWX 卷。

0x02 部署

这边采用 kubectl YAML 方式,也可以用 Helm 方式部署。

下载 YAML

wget https://raw.githubusercontent.com/longhorn/longhorn/v1.11.2/deploy/longhorn.yaml

查看依赖镜像,修改成加速地址

grep -oE '[a-zA-Z0-9._-]+/[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+' longhorn.yaml | sort -u
docker.io/longhornio/backing-image-manager:v1.11.2
docker.io/longhornio/csi-attacher:v4.11.0-20260428
docker.io/longhornio/csi-node-driver-registrar:v2.16.0-20260428
docker.io/longhornio/csi-provisioner:v5.3.0-20260428
docker.io/longhornio/csi-resizer:v2.1.0-20260428
docker.io/longhornio/csi-snapshotter:v8.5.0-20260428
docker.io/longhornio/livenessprobe:v2.18.0-20260428
docker.io/longhornio/longhorn-engine:v1.11.2
docker.io/longhornio/longhorn-instance-manager:v1.11.2
docker.io/longhornio/longhorn-manager:v1.11.2
docker.io/longhornio/longhorn-share-manager:v1.11.2
docker.io/longhornio/longhorn-ui:v1.11.2
docker.io/longhornio/support-bundle-kit:v0.0.84

替换成加速地址:

sed -i 's|docker\.io/longhornio/\([^: ]*\):\([^ "]*\)|swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/\1:\2-amd64|g' longhorn.yaml

再检查一次:

grep -oE '[a-zA-Z0-9._-]+/[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+' longhorn.yaml | sort -u
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/backing-image-manager:v1.11.2-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/csi-attacher:v4.11.0-20260428-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/csi-node-driver-registrar:v2.16.0-20260428-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/csi-provisioner:v5.3.0-20260428-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/csi-resizer:v2.1.0-20260428-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/csi-snapshotter:v8.5.0-20260428-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/livenessprobe:v2.18.0-20260428-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/longhorn-engine:v1.11.2-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/longhorn-instance-manager:v1.11.2-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/longhorn-manager:v1.11.2-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/longhorn-share-manager:v1.11.2-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/longhorn-ui:v1.11.2-amd64
swr.cn-east-3.myhuaweicloud.com/itho/docker.io/longhornio/support-bundle-kit:v0.0.84-amd64

开始部署

kubectl apply -f longhorn.yaml

查看 Pod:

kubectl -n longhorn-system get pod -o wide
NAME                                                READY   STATUS    RESTARTS        AGE   IP              NODE
csi-attacher-79b46ddbb5-8mxpf                       1/1     Running   1 (7m11s ago)   11m   10.244.36.206   k8s-worker-01
csi-attacher-79b46ddbb5-bfm5q                       1/1     Running   1 (7m11s ago)   11m   10.244.36.207   k8s-worker-01
csi-attacher-79b46ddbb5-zzxz7                       1/1     Running   4 (4m ago)      11m   10.244.118.79   k8s-worker-02
csi-provisioner-589b68df94-8jv2l                    1/1     Running   4 (3m53s ago)   11m   10.244.118.80   k8s-worker-02
csi-provisioner-589b68df94-m5rp8                    1/1     Running   4 (3m54s ago)   11m   10.244.118.81   k8s-worker-02
csi-provisioner-589b68df94-mbg2p                    1/1     Running   0               11m   10.244.36.208   k8s-worker-01
csi-resizer-6686cb7b68-5282c                        1/1     Running   4 (3m48s ago)   11m   10.244.118.82   k8s-worker-02
csi-resizer-6686cb7b68-7zl5v                        1/1     Running   0               11m   10.244.36.210   k8s-worker-01
csi-resizer-6686cb7b68-wb89s                        1/1     Running   0               11m   10.244.36.209   k8s-worker-01
csi-snapshotter-567bc6c575-5sn2z                    1/1     Running   0               11m   10.244.36.211   k8s-worker-01
csi-snapshotter-567bc6c575-78r9h                    1/1     Running   3 (4m33s ago)   11m   10.244.118.84   k8s-worker-02
csi-snapshotter-567bc6c575-jmncl                    1/1     Running   3 (4m35s ago)   11m   10.244.118.83   k8s-worker-02
engine-image-ei-89a2d474-5qfkt                      1/1     Running   0               12m   10.244.36.203   k8s-worker-01
engine-image-ei-89a2d474-5t482                      1/1     Running   0               12m   10.244.118.77   k8s-worker-02
instance-manager-39bcec98d10b689799eff1e45a19367f   1/1     Running   0               11m   10.244.118.78   k8s-worker-02
instance-manager-c25d748ecd3392e94e4597b302d0eeac   1/1     Running   0               11m   10.244.36.204   k8s-worker-01
longhorn-csi-plugin-jgz58                           3/3     Running   1 (5m44s ago)   11m   10.244.118.85   k8s-worker-02
longhorn-csi-plugin-n7zj5                           3/3     Running   0               11m   10.244.36.212   k8s-worker-01
longhorn-driver-deployer-66dc8cf958-hn22t           1/1     Running   0               13m   10.244.118.75   k8s-worker-02
longhorn-manager-2r4rs                              2/2     Running   0               13m   10.244.36.201   k8s-worker-01
longhorn-manager-lmh7c                              2/2     Running   0               13m   10.244.118.74   k8s-worker-02
longhorn-ui-66b5b4dc7d-8fl2p                        1/1     Running   0               13m   10.244.118.76   k8s-worker-02
longhorn-ui-66b5b4dc7d-9bxzl                        1/1     Running   0               13m   10.244.36.202   k8s-worker-01

查看 StorageClass:

kubectl get sc
NAME                 PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-s3               ru.yandex.s3.csi     Delete          Immediate           false                  17h
longhorn (default)   driver.longhorn.io   Delete          Immediate           true                   12m
longhorn-static      driver.longhorn.io   Delete          Immediate           true                   12m

查看 Service:

kubectl get svc -n longhorn-system
NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
longhorn-admission-webhook   ClusterIP   10.104.158.115   <none>        9502/TCP   15m
longhorn-backend             ClusterIP   10.96.13.116     <none>        9500/TCP   15m
longhorn-frontend            ClusterIP   10.104.253.143   <none>        80/TCP     15m
longhorn-recovery-backend    ClusterIP   10.97.147.135    <none>        9503/TCP   15m

0x03 暴露 Web UI

这里直接把 longhorn-frontend 改成 NodePort:

kubectl -n longhorn-system patch svc longhorn-frontend \
  -p '{"spec":{"type":"NodePort","ports":[{"port":80,"targetPort":8000,"nodePort":30880}]}}'

访问地址:

http://节点IP:30880

如果只是临时看一下,也可以用 port-forward

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

然后访问:

http://localhost:8080

0x04 修改默认副本数

方法一:kubectl patch

kubectl -n longhorn-system patch settings.longhorn.io default-replica-count \
  --type='merge' \
  -p '{"value":"{\"v1\":\"2\",\"v2\":\"2\"}"}'

参数说明:

方法二:kubectl edit

kubectl -n longhorn-system edit settings.longhorn.io default-replica-count

方法三:Longhorn UI

浏览器打开 Longhorn UI,进入 Settings,找到 Default Replica Count,直接改成 2

常用查看命令

# 查看某个设置项的值
kubectl -n longhorn-system get settings.longhorn.io default-replica-count -o jsonpath='{.value}'

# 列出所有设置项
kubectl -n longhorn-system get settings.longhorn.io -o wide

Longhorn 的所有配置都是 settings.longhorn.io 资源,名称就是配置项,改 value 字段就行。

0x05 快速使用

直接创建 PVC

写一个 PVC,storageClassName 不填就会用默认的 longhorn

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn
  resources:
    requests:
      storage: 5Gi

在 Pod 中使用

apiVersion: v1
kind: Pod
metadata:
  name: test-longhorn
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: /data
          name: data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: my-pvc

在 Deployment 中使用

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: html
      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: my-pvc

0x06 常用说明

关键特性

功能 说明
默认副本数 这里改成 2,数据在两个 worker 间冗余
扩容 支持,PVC 中改 storage 大小即可,allowVolumeExpansion: true
快照/备份 通过 Longhorn UI 或 kubectl 操作
UI 面板 可以用 NodePort 或 port-forward 访问

两个 StorageClass 区别

几个注意点

k8s kubernetes Longhorn


正文到此结束
版权声明:若无特殊注明,本文皆为 Myluzh Blog 原创,转载请保留文章出处。
文章内容:https://itho.cn/k8s/607.html
文章标题:《K8S 部署Longhorn(云原生分布式块存储解决方案)