2025,每天10分钟,跟我学K8S(三十四)- 对象属性 - Volume - Longhorn

        前面学习了动态PV,确实帮助我们省略了创建和删除的步骤,但还是觉得麻烦,先要创建RBAC,再创建NFS的客户端的pod,再创建pvc,最后才能应用到pod里面。能不能更简化一点?今天介绍一款软件 Longhorn 他来帮我们再减轻一些操作。

        可能提起Longhorn有些人不熟悉,但是他的出厂公司Rancher则大大有名。帮助了不少同学来学习K8S。Longhorn是一个轻量级且功能强大的云原生Kubernetes分布式存储平台,可以在任意基础设施上运行。

        官网地址:Longhorn | 强大的云原生Kubernetes储存平台 | Rancher Longhorn 是由Rancher研发的容器存储解决方案,Longhorn 已作为沙箱(Sandbox)项目加入CNCF社区。Longhorn 提供了一种简单、轻量、极适用于容器和K8S的持久化存储解决方案,Longhorn 同时极大地简化了用户部署、使用和管理的工作。https://www.rancher.cn/products/longhorn/

        github地址:https://github.com/longhorn/longhornhttps://github.com/longhorn/longhorn

部署longhorn

1.安装插件

# CentOS/RHEL
yum install -y iscsi-initiator-utils
systemctl enable iscsid --now

# Ubuntu/Debian
apt-get install -y open-iscsi
systemctl enable open-iscsi --now

# 验证安装
which iscsiadm  # 应输出:/usr/sbin/iscsiadm

2.下载yaml文件并修改

# 下载yaml文件 (202503月最新版)
# wget https://github.com/longhorn/longhorn/releases/download/v1.8.1/longhorn.yaml




# 修改标注内容,开放longhron-ui对外,方便访问管理
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: longhorn-ui
  name: longhorn-frontend
  namespace: longhorn-system
spec:
  type: NodePort  #这里改为nodeport
  selector:
    app: longhorn-ui
  ports:
  - name: http
    port: 80
    targetPort: http
    nodePort: 30080  #修改nodeport对外端口
---



# 修改镜像地址1
# cat longhorn.yaml |grep "image:"
        image: longhornio/longhorn-manager:master-head
        image: longhornio/longhorn-share-manager:master-head
        image: longhornio/longhorn-manager:master-head
        image: longhornio/longhorn-manager:master-head
        image: longhornio/longhorn-ui:master-head
修改为

        image: m.daocloud.io/docker.io/longhornio/longhorn-manager:master-head
        image: m.daocloud.io/docker.io/longhornio/longhorn-share-manager:master-head
        image: m.daocloud.io/docker.io/longhornio/longhorn-manager:master-head
        image: m.daocloud.io/docker.io/longhornio/longhorn-manager:master-head
        image: m.daocloud.io/docker.io/longhornio/longhorn-ui:master-head	


# 修改镜像地址2
        command:
        - longhorn-manager
        - -d
        - daemon
        - --engine-image
        - "longhornio/longhorn-engine:v1.8.1"
        - --instance-manager-image
        - "longhornio/longhorn-instance-manager:v1.8.1"
        - --share-manager-image
        - "longhornio/longhorn-share-manager:v1.8.1"
        - --backing-image-manager-image
        - "longhornio/backing-image-manager:v1.8.1"
        - --support-bundle-manager-image
        - "longhornio/support-bundle-kit:v0.0.52"
        - --manager-image
        - "longhornio/longhorn-manager:v1.8.1"
	
修改为
        command:
        - longhorn-manager
        - -d
        - daemon
        - --engine-image
        - "m.daocloud.io/docker.io/longhornio/longhorn-engine:v1.8.1"
        - --instance-manager-image
        - "m.daocloud.io/docker.io/longhornio/longhorn-instance-manager:v1.8.1"
        - --share-manager-image
        - "m.daocloud.io/docker.io/longhornio/longhorn-share-manager:v1.8.1"
        - --backing-image-manager-image
        - "m.daocloud.io/docker.io/longhornio/backing-image-manager:v1.8.1"
        - --support-bundle-manager-image
        - "m.daocloud.io/docker.io/longhornio/support-bundle-kit:v0.0.52"
        - --manager-image
        - "m.daocloud.io/docker.io/longhornio/longhorn-manager:v1.8.1"


# 修改镜像地址3
          - name: CSI_ATTACHER_IMAGE
            value: "longhornio/csi-attacher:v4.8.1"
          - name: CSI_PROVISIONER_IMAGE
            value: "longhornio/csi-provisioner:v5.2.0"
          - name: CSI_NODE_DRIVER_REGISTRAR_IMAGE
            value: "longhornio/csi-node-driver-registrar:v2.13.0"
          - name: CSI_RESIZER_IMAGE
            value: "longhornio/csi-resizer:v1.13.2"
          - name: CSI_SNAPSHOTTER_IMAGE
            value: "longhornio/csi-snapshotter:v8.2.0"
          - name: CSI_LIVENESS_PROBE_IMAGE
            value: "longhornio/livenessprobe:v2.15.0"
修改为
          - name: CSI_ATTACHER_IMAGE
            value: "m.daocloud.io/docker.io/longhornio/csi-attacher:v4.8.1"
          - name: CSI_PROVISIONER_IMAGE
            value: "m.daocloud.io/docker.io/longhornio/csi-provisioner:v5.2.0"
          - name: CSI_NODE_DRIVER_REGISTRAR_IMAGE
            value: "m.daocloud.io/docker.io/longhornio/csi-node-driver-registrar:v2.13.0"
          - name: CSI_RESIZER_IMAGE
            value: "m.daocloud.io/docker.io/longhornio/csi-resizer:v1.13.2"
          - name: CSI_SNAPSHOTTER_IMAGE
            value: "m.daocloud.io/docker.io/longhornio/csi-snapshotter:v8.2.0"
          - name: CSI_LIVENESS_PROBE_IMAGE
            value: "m.daocloud.io/docker.io/longhornio/livenessprobe:v2.15.0"

2.应用yaml文件

可以看到创建了一个 longhorn-system 的namespace和一大堆的资源

如果使用的是VMware虚拟机,可能会有个报错

# journalctl -u multipathd -f
-- Logs begin at Thu 2025-02-06 18:06:45 CST. --
Mar 28 18:02:54 k8s-master multipathd[741]: sda: failed to get sysfs uid: Invalid argument
Mar 28 18:02:54 k8s-master multipathd[741]: sda: failed to get sgio uid: No such file or directory
Mar 28 18:02:59 k8s-master multipathd[741]: sda: add missing path
Mar 28 18:02:59 k8s-master multipathd[741]: sda: failed to get udev uid: Invalid argument
Mar 28 18:02:59 k8s-master multipathd[741]: sda: failed to get sysfs uid: Invalid argument
Mar 28 18:02:59 k8s-master multipathd[741]: sda: failed to get sgio uid: No such file or directory
Mar 28 18:03:04 k8s-master multipathd[741]: sda: add missing path


# 解决办法 编辑配置文件
sudo vi /etc/multipath.conf

# 添加以下内容
blacklist {
    devnode "^sda"
}

3.验证longhorn

pod验证

如果所有pod都正常启动,正常显示应该如下图,如果发现只在部分节点运行,则查看是否有污染的情况

# kubectl describe nodes <node> | grep Taint

web页面验证

masterIP:30080  记得这里是开启了NodePort,需要做好安全策略,以防入侵

下图可知目前创建了0个卷,2个节点,合计有38G的可用空间。

注意:

  • longhorn是分布式块存储,与分布式文件系统不同(mfs,lizardfs),不同超过pv设置的存储大小
  • 使用dd命令测试(bs=1m,count=1024或者bs=500k,count=2048),发现longhorn的存储性能不及本地磁盘
  • longhorn性能要远超nfs-client-provisioner提供的存储性能(2-3倍)

举例验证

        在日常使用中,运行数据库的Pod,如果发生故障,相关业务也无法继续,这时你会失去客户、失去订单。在这里,就以一个mysql的pod举例,为它配置一个新的Longhorn持久卷

1.创建pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    type: longhorn
    app: example
spec:
  storageClassName: longhorn  #类型为longhorn  
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

2.创建一个mysql.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-mysql
  labels:
    app: example
spec:
  selector:
    matchLabels:
      app: example
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: example
        tier: mysql
    spec:
      containers:
      - image: m.daocloud.io/docker.io/mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          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  #对应pvc的名字

应用后查看pod,pv,pvc

通过下图可以看到,pvc已经绑定成功

mysql写入数据后,删除pod

root@k8s-master:~/longhorn# kubectl exec -it my-mysql-7f8f897d85-4zmpx -- /bin/bash
root@my-mysql-7f8f897d85-4zmpx:/#  mysql -u root -p mysql
Enter password:    #密码为yaml文件中设置的password
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.51 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>  create database k8s;   #创建一个K8s的数据库
Query OK, 1 row affected (0.00 sec)

mysql> exit
Bye
root@my-mysql-7f8f897d85-4zmpx:/# exit
exit

删除这个mysql pod

root@k8s-master:~/longhorn# kubectl delete pod my-mysql-7f8f897d85-4zmpx 
pod "my-mysql-7f8f897d85-4zmpx" deleted

大约一分钟之后,我们将再次寻找新的容器名称,连接到该容器名称,看看我们的数据库是否仍然存在,发现新的pod依然使用了之前的存储卷,并且数据还在。

root@k8s-master:~/longhorn# kubectl get pods | grep mysql
my-mysql-7f8f897d85-hkrp9   1/1     Running   0          27s
root@k8s-master:~/longhorn# kubectl exec -it my-mysql-7f8f897d85-hkrp9 -- /bin/bash
root@my-mysql-7f8f897d85-hkrp9:/# mysql -u root -p mysql
Enter password: 
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.51 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+---------------------+
| Database            |
+---------------------+
| information_schema  |
| k8s                 |
| #mysql50#lost+found |
| mysql               |
| performance_schema  |
+---------------------+
5 rows in set (0.00 sec)

mysql> 

卸载longhorn

参考官网文档

Longhorn | Documentationhttps://longhorn.io/docs/1.8.1/deploy/uninstall/#uninstalling-longhorn-using-kubectl具体步骤如下,记得切换版本号,保持和安装的版本一致

Uninstalling Longhorn using kubectl

  1. Create the uninstallation job to clean up CRDs from the system and wait for success:

    kubectl create -f https://raw.githubusercontent.com/longhorn/longhorn/v1.8.1/uninstall/uninstall.yaml
    kubectl get job/longhorn-uninstall -n longhorn-system -w
    

    Example output:

    $ kubectl create -f https://raw.githubusercontent.com/longhorn/longhorn/v1.8.1/uninstall/uninstall.yaml
    serviceaccount/longhorn-uninstall-service-account created
    clusterrole.rbac.authorization.k8s.io/longhorn-uninstall-role created
    clusterrolebinding.rbac.authorization.k8s.io/longhorn-uninstall-bind created
    job.batch/longhorn-uninstall created
    
    $ kubectl get job/longhorn-uninstall -n longhorn-system -w
    NAME                 COMPLETIONS   DURATION   AGE
    longhorn-uninstall   0/1           3s         3s
    longhorn-uninstall   1/1           20s        20s
    
  2. Remove remaining components:

    kubectl delete -f https://raw.githubusercontent.com/longhorn/longhorn/v1.8.1/deploy/longhorn.yaml
    kubectl delete -f https://raw.githubusercontent.com/longhorn/longhorn/v1.8.1/uninstall/uninstall.yaml

总结

        在安装了longhorn之后,我们就不需要关心底层实现是什么和实现的过程,只需要创建pvc+pod开箱即用,大大方便我们再k8s中使用存储。

以下是通过deepseek生成的 PV、StorageClass 和 Longhorn 的核心区别对比,结合 Kubernetes 存储架构与 Longhorn 的特性整理:

区别对照表:

维度PV (PersistentVolume)StorageClassLonghorn
定位集群级别的存储资源实体,如 NFS 卷、云盘等存储策略模板,用于动态生成 PV云原生分布式块存储系统,提供存储后端实现
核心功能代表实际存储空间,与底层存储系统绑定定义动态 PV 的创建规则(如存储类型、副本策略)实现分布式块存储,支持快照、备份、跨集群容灾等
创建方式管理员手动创建(静态供应)管理员定义模板(如 provisioner 和参数)通过 Helm 或 YAML 部署,集成到 Kubernetes 集群
生命周期独立于 Pod,可被多个 PVC 绑定(需回收策略支持)长期存在,用于动态生成 PV与 Kubernetes 集群共存,通过 Operator 管理存储资源
动态供应不支持,需预先创建核心动态供应机制,调用存储插件(如 Longhorn)自动生成 PV作为 StorageClass 的 provisioner,提供动态 PV 创建能力
访问模式支持 ReadWriteOnceReadOnlyManyReadWriteMany通过参数定义 PV 的默认访问模式支持 RWO 和 RWX(需 NFS 或 CSI 插件)
多租户隔离无原生隔离,依赖存储系统实现通过不同 StorageClass 隔离存储策略(如 SSD/HDD)提供多副本隔离,支持跨节点调度(如 nodeSelector
典型使用场景静态分配存储资源(如固定大小的云盘)自动化按需分配存储(如开发环境快速创建卷)分布式有状态应用(如 MySQL 集群)、跨集群灾备
与 Kubernetes 的集成通过 PVC 绑定使用,需手动维护通过 provisioner 字段关联存储插件(如 driver.longhorn.io提供 CSI 驱动,与 StorageClass 协同实现动态存储供应
高可用机制依赖底层存储的高可用(如云盘冗余)无直接高可用功能,依赖存储后端实现通过多副本(3 副本默认)和分布式控制器实现跨节点容灾

关键差异总结:

1.​抽象层级 

  • PV 是具体的存储资源实体,属于静态资源;StorageClass 是动态资源模板;Longhorn 是底层存储系统的实现。
  • 三者关系:StorageClass 动态生成 PV → PVC 绑定 PV → Longhorn 提供底层存储支持。

2.运维复杂度

  • PV 需手动维护,适合固定规模场景;StorageClass 通过自动化降低运维成本;Longhorn 提供完整的存储管理界面和运维工具。

3.功能扩展性

  • Longhorn 支持高级功能(如增量快照、跨集群备份),而原生 PV/StorageClass 需依赖存储插件实现。

4.生产建议

  • 静态场景:直接使用 PV + PVC;
  • 动态场景:优先采用 StorageClass + Longhorn 组合,实现弹性扩展和高可用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值