1、简介
Longhorn是由Rancher Labs开发的分布式块存储系统,旨在提供高性能、可靠性和易用性。它基于微服务架构,使用Containerd作为其运行时,与Kubernetes紧密集成。Longhorn支持多种存储后端,如本地磁盘、网络存储和公共云提供商的存储服务,使其能够在不同的环境中灵活部署。
2、特点
高度可用:Longhorn通过数据副本和自动故障转移确保数据的高可用性,即使在节点故障的情况下也能保持服务的连续性。
扩展性强:Longhorn可以轻松地水平扩展,以支持大规模的数据存储需求。
多租户支持:Longhorn支持多租户环境,允许多个团队或项目共享存储资源,同时保持数据隔离。
快照和备份:Longhorn提供快照功能,可以快速备份和恢复数据,简化数据保护流程。
监控和指标:Longhorn集成了Prometheus监控,提供了丰富的指标,帮助用户监控存储系统的性能和健康状况。
3、原理
Longhorn 为每个卷创建一个专用的存储控制器,并在多个节点上存储的多个副本之间同步复制该卷。Longhorn 在整体上分为两层:数据平面
和 控制平面
。
Longhorn Engine 是存储控制器,对应数据平面。
Longhorn Manager 对应控制平面。
Longhorn Manager 会以 DaemonSet 的形式在 Longhorn 集群中的每个节点上运行,它负责在 Kubernetes 集群中创建和管理卷,并处理来自 UI 或 Kubernetes 卷插件的 API 调用,遵循 Kubernetes 控制器模式。
Longhorn Manager 通过与 APIServer 通信来创建新的 Longhorn volume CRD,并一直 Watch APIServer 的响应,当发现创建了一个新的 Longhorn volume CRD 时,Longhorn Manager 就会去创建一个新的对应卷。
当 Longhorn Manager 被要求创建一个卷时,它会在卷所连接的节点上创建一个 Longhorn Engine 实例,并在每个将放置副本的节点上创建一个副本。通过副本的多条数据访问路径,确保了 Longhorn 卷的高可用性,即使某个副本或引擎出现问题,也不会影响所有副本或 Pod 对卷的访问。
Longhorn Engine 始终与使用 Longhorn 卷的 Pod 在同一节点中运行,它在存储在多个节点上的多个副本之间同步复制卷。
如下图所示,描述了 Longhorn 卷、Longhorn Engine、副本实例和磁盘之间的读/写数据流:

关系图说明:
上图有3个 Longhorn 卷实例。
每个卷都有一个专用控制器,称为 Longhorn Engine,并作为 Linux 进程运行。
每个 Longhorn 卷有两个副本,每个副本也是一个 Linux 进程。
通过为每个卷创建单独的 Longhorn Engine,如果一个控制器发生故障,其他卷的功能不会受到影响。
注意:图中的 Engine 并非是单独的一个 Pod,而是每一个 Volume 会对应一个 golang exec 出来的 Linux 进程。
在 Longhorn 中,每个 Engine 只需要服务一个卷,简化了存储控制器的设计,由于控制器软件的故障域与单个卷隔离,因此控制器崩溃只会影响一个卷。由于 Longhorn Engine 足够简单和轻便,因此可以创建多达 100000 个独立的 Engine,Kubernetes 去调度这些独立的 Engine,从一组共享的磁盘中提取资源,并与 Longhorn 合作形成一个弹性的分布式块存储系统。
因为每个卷都有自己的控制器,所以每个卷的控制器和副本实例也可以升级,而不会导致 IO 操作明显中断。Longhorn 可以创建一个长时间运行的 job 任务来协调所有卷的升级,而不会中断系统的运行。
Longhorn 是通过 CSI 驱动在 Kubernetes 中管理的,CSI 驱动通过调用 Longhorn 来创建卷,为 Kubernetes 工作负载创建持久性数据,CSI 插件可以让我们创建、删除、附加、分离、挂载卷,并对卷进行快照操作,Kubernetes 集群内部使用 CSI 接口与Longhorn CSI 驱动进行通信,而 Longhorn CSI 驱动是通过使用 Longhorn API 与 Longhorn Manager 进行通信。
此外 Longhorn 还提供一个 UI 界面程序,通过 Longhorn API 与 Longhorn Manager 进行交互,通过 Longhorn UI 可以管理快照、备份、节点和磁盘等,此外,集群工作节点的空间使用情况还可以通过 Longhorn UI 查看。
4、安装条件
要在 Kubernetes 集群上安装 Longhorn,需要集群的每个节点都必须满足以下要求:
与 Kubernetes 兼容的容器运行时。
Kubernetes v1.18+。
安装
open-iscsi
,并且iscsid
守护程序在所有节点上运行,这是必要的,因为 Longhorn 依赖主机上的iscsiadm
为 Kubernetes 提供持久卷。RWX 支持需要每个节点上都安装 NFSv4 客户端。
宿主机文件系统支持
file extents
功能来存储数据,目前支持:ext4 与 XFS。bash、curl、findmnt、grep、awk、blkid、lsblk 等工具必须安装。
Mount propagation
必须启用,它允许将一个容器挂载的卷与同一 pod 中的其他容器共享,甚至可以与同一节点上的其他 pod 共享。Longhorn workloads 必须能够以 root 身份运行才能正确部署和操作 Longhorn。
5、配置依赖
为了验证这些环境要求,Longhorn 官方提供了一个脚本来帮助我们进行检查,执行该脚本需要在本地安装 jq
工具,脚本地址:
https://github.com/longhorn/longhorn/blob/master/scripts/environment_check.sh
可以下载下来在服务器上面执行:

提示所有节点要安装 open-iscsi
,其它服务也可以一并安装好:
# 直接 yum 安装
[root@xfzqak8s0001 ~]# yum install -y iscsi-initiator-utils nfs-utils
6、安装 Longhorn
获取longhorn部署的chart包
[root@xfzqak8s0001 ~]# helm repo add longhorn https://charts.longhorn.io
[root@xfzqak8s0001 ~]# helm repo update
[root@xfzqak8s0001 ~]# helm pull longhorn/longhorn --version v1.2.0
[root@xfzqak8s0001 ~]# tar xf longhorn-1.2.0.tgz
[root@xfzqak8s0001 ~]# cd longhorn/
修改配置参数如下
[root@xfzqak8s0001 ~]# vim values.yaml
service:
ui:
type: NodePort # 需要在集群外看到页面,调整webUI访问模式为nodeport,默认cluster
nodePort: 30012 # 设置访问端口
persistence:
defaultFsType: xfs # 默认ext4,这里改成和本地的磁盘格式一致即可
defaultClassReplicaCount: 2 # 因为master不参与调度,所以卷副本数改成2,和node节点数一样
defaultSettings
defaultDataPath: "/data/longhorn" # 设置默认数据目录,默认存放到/var/lib/longhorn
安装服务
[root@xfzqak8s0001 ~]# kubectl create ns longhorn
[root@xfzqak8s0001 ~]# helm install longhorn -n longhorn . # 将longhorn存储安装到longhorn命名空间
[root@xfzqak8s0001 ~]# helm list -A
[root@xfzqak8s0001 ~]# kubectl -n longorn get pod # 确保所有pod均为running状态表示部署成功
访问集群任意节点的30012打开webI页面查看仪表盘

查看集群的存储类
[root@xfzqak8s0001 ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
longhorn (default) driver.longhorn.io Delete Immediate true 3h45m
7、持久化测试
使用默认的 StorageClass 创建 PVC
[root@xfzqak8s0001 ~]# vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
namespace: longhorn-system
name: pvc-longhorn
spec:
storageClassName: longhorn
resources:
requests:
storage: 1Gi
accessModes:
- ReadWriteOnce
然后使用这个 PVC 部署一个 mysql
[root@xfzqak8s0001 ~]# vim mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: longhorn-system
name: deploy-mysql
spec:
selector:
matchLabels:
app.kuberneets.io/name: mysql
template:
metadata:
labels:
app.kuberneets.io/name: mysql
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-longhorn
containers:
- name: mysql
image: mysql:5.6
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: data
mountPath: var/lib/mysql
通过sc创建pvc时会自动创建一个pv实例绑定
[root@xfzqak8s0001 test-pod]# kubectl get pvc,pv -n longhorn-system|grep pvc-longhorn
persistentvolumeclaim/pvc-longhorn Bound pvc-5a24eed6-010b-43a3-8bbf-cd0940348988 1Gi RWO longhorn 5m23s
persistentvolume/pvc-5a24eed6-010b-43a3-8bbf-cd0940348988 1Gi RWO Delete Bound longhorn-system/pvc-longhorn
进入容器创建数据库
[root@xfzqak8s0001 test-pod]# kubectl get pod -n longhorn-system
NAME READY STATUS RESTARTS AGE
deploy-mysql-8dc4979bc-h9rkr 1/1 Running 0 3m50s
[root@xfzqak8s0001 test-pod]# kubectl exec -it deploy-mysql-8dc4979bc-h9rkr -n longhorn-system bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@deploy-mysql-8dc4979bc-h9rkr:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
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 |
| #mysql50#lost+found |
| mysql |
| performance_schema |
+---------------------+
4 rows in set (0.01 sec)
mysql> create database helloworld;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+---------------------+
| Database |
+---------------------+
| information_schema |
| helloworld |
| #mysql50#lost+found |
| mysql |
| performance_schema |
+---------------------+
5 rows in set (0.01 sec)
mysql> exit
Bye
root@deploy-mysql-8dc4979bc-h9rkr:/# exit
exit
删除pod,重新创建,发现数据库依然存在
[root@xfzqak8s0001 test-pod]# kubectl get pod -n longhorn-system
NAME READY STATUS RESTARTS AGE
deploy-mysql-8dc4979bc-gxtwk 1/1 Running 0 12s
[root@xfzqak8s0001 test-pod]# kubectl exec -it deploy-mysql-8dc4979bc-gxtwk -n longhorn-system bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@deploy-mysql-8dc4979bc-gxtwk:/# mysql -u root -p
Enter password:
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 |
| helloworld |
| #mysql50#lost+found |
| mysql |
| performance_schema |
+---------------------+
5 rows in set (0.08 sec)
mysql> exit
Bye
root@deploy-mysql-8dc4979bc-gxtwk:/# exit
exit
欢迎大家扫码关注:

本公众号只写原创,不接广告、不接广告、不接广告。下期小伙伴想学习什么技术,可以私信发我吆。





