Longhorn 分布式存储使用 helm 部署
项目介绍:https://www.rancher.cn/longhorn/
Longhorn 是 Kubernetes 云原生分布式块存储解决方案。
Longhorn 支持以下的的 Access Modes:
- ReadWriteOnce (RWO)
- ReadWriteOncePod (RWOP)
- ReadWriteMany (RWX)
Longhorn 不支持 ReadOnlyMany (ROX),但可以通过以只读方式挂载 ReadWriteMany。比如:
# PVC 用 RWX(不是 ROX)
spec:
accessModes:
- ReadWriteMany
# Pod 中设置只读挂载
volumeMounts:
- name: data
mountPath: /data
readOnly: true
技术文档:https://longhorn.io/docs/
本案例使用 helm 部署一个 1.12.0 版本的单节点测试示例。也可以使用 kubectl 部署。
前提
节点 IP:192.168.4.250
物理节点名称:k8s-Longhorn
kubeadm 版本:v1.35.5
kubernetes node 节点名称:k8s-longhorn
在这台单节点的机器中,设置了一个单独的硬盘给 Longhorn 使用。挂载目录为/data/longhorn:
lsblk -f /dev/nvme0n2p1
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
nvme0n2p1 ext4 1.0 520428ce-b354-4f88-8cd9-8ac0106ccb48 55.7G 0% /data/longhorn
安装依赖组件
安装 open-iscsi
kubernetes 其他数据节点和 longhorn 都需要安装 open-iscsi:
dnf install -y iscsi-initiator-utils
systemctl enable --now iscsid
安装 nfs
ReadWriteMany (RWX) 类型的卷底层需要 NFS 协议,为每个 RWX 卷启动一个专用的 NFS 服务器,从而让多个 Pod 可以同时读写同一个卷,所以需要安装 nfs-utils:
dnf install -y nfs-utils
当您创建一个访问模式为 ReadWriteMany 的 PVC 时,Longhorn 会在 longhorn-system 命名空间中自动创建一个名为 share-manager-<卷名> 的 Pod。这个 Pod 内部运行着一个 NFSv4 服务器,它通过 NFS 协议将底层的 Longhorn 块卷共享出来 。随后,无论您的业务 Pod 调度到哪个节点,都可以通过网络挂载这个 NFS 共享,实现多节点、多 Pod 的并发读写。
设置污点
Longhorn 专用节点打上污点,隔离存储节点,阻止普通应用调度上去:
kubectl taint nodes k8s-longhorn Longhorn=true:NoSchedule
设置 Label
对所有需要使用 Longhorn 的节点设置 label:
kubectl label nodes k8s-longhorn storage=longhorn
kubectl label nodes k8s-node01 storage=longhorn
kubectl label nodes k8s-node02 storage=longhorn
设置默认存储数据节点的 label:
kubectl label nodes k8s-longhorn default-storage-node=true
部署 Longhorn
添加 repo
添加 Longhorn Helm 存储库:
helm repo add longhorn https://charts.longhorn.io
从存储库中获取更新:
helm repo update
搜索 longhorn:
# helm search repo longhorn/longhorn
NAME CHART VERSION APP VERSION DESCRIPTION
longhorn/longhorn 1.12.0 v1.12.0 Longhorn is a distributed block storage system ...
拉取 longhorn 并解压:
helm pull longhorn/longhorn
tar xzf longhorn-1.12.0.tgz
修改安装参数
设置 tolerations
如果希望创建专用于 Longhorn 的节点(仅用于存储副本数据),并为其分配大容量存储空间和/或 CPU 资源,同时拒绝其他通用工作负载,则可以对这些节点添加污点(taint),并为 Longhorn 组件配置相应的容忍(toleration)。这样,Longhorn 就可以部署到这些节点上。
- 使用 Helm 安装 Longhorn,为用户部署的组件(例如 Longhorn Manager、Longhorn Driver 和 Longhorn UI)设置污点容忍度。在安装 chart 之前更改 value. yaml 文件中的
global.tolerations,longhornManager.tolerations,longhornUI.tolerations,longhornDriver.tolerations的 Helm 值:
tolerations:
- key: "Longhorn"
operator: "Equal"
value: "true"
effect: "NoSchedule"
- 使用 Helm 安装 Longhorn,为系统管理的组件(例如,Instance Manager, CSI Driver, 和 Engine images)设置污点容忍度。更改 value. yaml 文件中的
defaultSettings.taintToleration值:
taintToleration: Longhorn=true:NoSchedule
注意:这个默认一定要设置,否则 Engine images 等一些系统 DaemonSet 组件无法在有污点的节点上运行。比如
kubectl get engineimages.longhorn.io -n longhorn-system查询 longhorn-engine 的状态一直在 deploying 部署中。
更多信息:https://longhorn.io/docs/1.12.0/advanced-resources/deploy/taint-toleration/
设置 nodeSelector
- 如果想把 Longhorn 的系统组件部署到专用节点上(例如 Longhorn Manager、Longhorn Driver 和 Longhorn UI),则需要对这些组件设置 nodeSelector。使用 Helm 安装 Longhorn,在安装 chart 之前更改 value. yaml 文件中的
global.nodeSelector,longhornManager.nodeSelector,longhornUI.nodeSelector,longhornDriver.nodeSelector的 Helm 值:
nodeSelector:
storage: longhorn
- 使用 Helm 安装 Longhorn,为系统管理的组件(例如,Instance Manager,Backing Image Manager,Share Manager,CSI Driver,和 Engine Image)。更改 value. yaml 文件中的
defaultSettings.taintToleration值:
systemManagedComponentsNodeSelector: "storage=longhorn"
更多信息:https://longhorn.io/docs/1.12.0/advanced-resources/deploy/node-selector/
设置默认数据路径
在安装 chart 之前更改 value. yaml 文件中的defaultSettings.defaultDataPath:
defaultDataPath: /data/longhorn
修改默认存储数据的节点
设置 Longhorn 仅使用具有指定标签的节点来存储卷数据:
defaultNodeSelector:
enable: true
selector: "default-storage-node"
如后面需要修改节点标签,除了修改这里,还需要修改 Longhorn 节点对象中的标签信息,kubectl edit nodes.longhorn.io -n longhorn-system k8s-longhorn:
spec:
tags:
- default-storage-node
修改副本数
由于使用的是单节点,修改默认副本数defaultSettings.defaultReplicaCount和persistence.defaultClassReplicaCount为 1:
persistence:
defaultReplicaCount: 1
defaultSettings:
defaultClassReplicaCount: 1
<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">persistence</font>部分,属于StorageClass设置。主要影响使用默认StorageClass动态创建的持久卷(PV)<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">defaultSettings</font>部分,属于系统默认设置。主要影响通过Longhorn UI或API创建的卷
两者使用区别如下:
- 如果您主要使用Kubernetes的PVC(PersistentVolumeClaim)来管理存储:
- 您应该关注 persistence.defaultClassReplicaCount。它会修改Longhorn安装时自动创建的默认StorageClass的副本数配置。
- 如果您需要更精细的控制,也可以不依赖默认StorageClass,而是创建自定义的StorageClass,并在其中明确指定numberOfReplicas参数。
- 如果您习惯使用Longhorn UI或命令行工具(如longhornctl)来直接操作卷:
- 那么 defaultSettings.defaultReplicaCount 会生效。它设定了通过UI或API创建新卷时的默认副本数,您仍然可以在创建时单独修改每个卷的副本数。
其他更多参数,参考https://longhorn.io/docs/1.12.0/references/helm-values/
安装 Longhorn
kubectl create namespace longhorn-system
helm install -n longhorn-system longhorn .
安装完成后,正常的节点状态:
# kubectl get nodes.longhorn.io -n longhorn-system
NAME READY ALLOWSCHEDULING SCHEDULABLE AGE
k8s-longhorn True true True 20m
k8s-node01 True true True 20m
k8s-node02 True true True 20m
Longhorn 在创建卷时,每个节点都需要运行一个 Engine 进程来处理数据操作,
# kubectl get engineimage -n longhorn-system
NAME INCOMPATIBLE STATE IMAGE REFCOUNT BUILDDATE AGE
ei-a4d05f02 false deployed docker.io/longhornio/longhorn-engine:v1.12.0 3 53d 110m
查看输出中 STATE 列是否为deployed。如果显示Deploying或Error,说明镜像还没准备好,或有异常。
Engine Image 的数量也应有 3 个:
# kubectl get pods -n longhorn-system -l app=longhorn-manager
NAME READY STATUS RESTARTS AGE
longhorn-manager-7cr5w 2/2 Running 1 (11m ago) 12m
longhorn-manager-9xvr7 2/2 Running 0 12m
longhorn-manager-sc4hk 2/2 Running 0 12m
测试使用
部署 pvc
pvc.yaml 示例如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-pvc-claim
spec:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
部署后 pvc 和 pv 已动态绑定:
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
longhorn-pvc-claim Bound pvc-8124476b-1fa1-4191-b949-67a4c22d37b1 3Gi RWO longhorn <unset> 6s
#
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-8124476b-1fa1-4191-b949-67a4c22d37b1 3Gi RWO Delete Bound default/longhorn-pvc-claim longhorn <unset> 13s
部署 nginx
nginx.yaml 示例如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.30.0
name: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage # volume 的名称
volumes:
- name: task-pv-storage # volume 的名称
persistentVolumeClaim:
claimName: longhorn-pvc-claim # PVC 的名称
部署这个 deployment 后,查看 pod 的 Event 事件可看到 Attach 关联上:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 36s default-scheduler Successfully assigned default/nginx-584b8c5fcb-ztwfv to k8s-node02
Normal SuccessfulAttachVolume 20s attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-8124476b-1fa1-4191-b949-67a4c22d37b1"
Normal Pulling 18s kubelet spec.containers{nginx}: Pulling image "nginx:1.30.0"
Normal Pulled 9s kubelet spec.containers{nginx}: Successfully pulled image "nginx:1.30.0" in 8.446s (8.446s including waiting). Image size: 62964182 bytes.
Normal Created 9s kubelet spec.containers{nginx}: Container created
Normal Started 9s kubelet spec.containers{nginx}: Container started
查看
在 longhorn 节点上,可以查看到 pvc 的卷数据:
# ls -lh /data/longhorn/replicas/pvc-471c68a7-c311-489c-8030-56c48f47849e-46e2fd68/
total 114M
-rw-r--r-- 1 root root 3.0G Jul 26 01:50 volume-head-000.img
-rw-r--r-- 1 root root 126 Jul 26 01:49 volume-head-000.img.meta
-rw-r--r-- 1 root root 160 Jul 26 01:49 volume.meta
Longhorn 分布式存储使用 helm 部署
https://www.seafog.cn/archives/rjGq3vqI