本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名原文链接~~~

开箱即用的 Kubernetes 持久化存储!

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:


Longhorn 是由 Rancher 实验室创建的一款云原生的、轻量级、可靠且易用的开源分布式块存储系统,后来由 CNCF 孵化。它借助 CSI 存储卷插件以外置的存储解决方案形式运行。Longhorn 遵循微服务的原则,利用容器将小型独立组件构建为分布式块存储,并使用编排工
具来协调这些组件,从而形成弹性分布式系统。部署到 Kubernetes 集群上之后,Longhorn 会自动将集群中所有节点上可用的本地存储(默认为 /var/lib/longhorn/ 目录所在的设备)聚集为存储集群,而后利用这些存储管理分布式、带有复制功能的块存储,且支持快照及数据备份操作。

面向现代云环境设计的存储系统的控制器随着待编排存储卷数量的急速增加也变得高度复杂。为了摆脱这种困境,Longhorn 充分利用了近年来关于如何编排大量容器的关键技术,采用微服务的设计模式,将大型复杂的存储控制器切分为每个存储卷一个专用的、小型存储控制器,而后借助现代编排工具来管理这些控制器,从而将每个 CSI 卷构建为一个独立的微服务。如图所示的存储架构中,3 个 Pod 分别使用了一个 Longhorn 存储卷,每个卷有一个专用的控制器(Engine)资源和两个副本(Replica) 资源,它们都是为了便于描述其应用而由 Longhorn 引入的自定义资源类型。

image.png

Engine 容器仅负责单个存储卷的管理,其生命周期与存储卷相同,因而它并非真正的 CSI 插件级别的卷控制器或节点插件。Longhorn 上负责处理来自 Kubernetes CSI 卷插件的 API 调用,以及完成存储卷管理的组件是 Longhorn Manager(node-driver-registrar),它是一个容器化应用且受 DaemonSet 控制器资源编排,在 Kubernetes 集群的每个节点上运行一个副本。Longhorn Manager 持续监视 Kubernetes API 上与 Longhorn 存储卷相关的资源变动,一旦发现新的资源创建,它负责在该卷附加的节点(即 Pod 被 Kubernetes 调度器绑定的目标节点)上创建一个 Engine 资源对象,并在副本相关的每个目标节点上相应创建一个 Replica 资源对象。

Kubernetes 集群内部通过 CSI 插件接口调用 Longhorn 插件以管理相关类型的存储卷,而 Longhorn 存储插件则基于 Longhorn API 与 Longhorn Manager 进行通信,卷管理之外的其他功能则要依赖 Longhorn Ul 完成,例如快照、备份、节点和磁盘的管理等。另外,Longhorn 的块设备存储卷的实现建立在 iSCSI 协议之上,因而需要调用 Longhorn 存储卷的 Pod 所在节点必须部署了相关的程序包,例如 open-iscsiiscsiadm 等。

目前版本(v1.1.2)的 Longhorn 要求运行于 v1.13 或更高版本的 Docker 环境下,以及 v1.4 或更高版本的 Kubernetes 之上,并且要求各节点部署了 open-iscsicurlfindmntgrepawkblkidIsblk 等程序包。以 CentOS 7 安装基础环境为例:

yum -y install iscsi-initiator-utils curl util-linux

基础环境准备完成后,我们使用类似如下的命令即能完成 Longhorn 应用的部署:

$ kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml
namespace/longhorn-system created
serviceaccount/longhorn-service-account created
clusterrole.rbac.authorization.k8s.io/longhorn-role created
clusterrolebinding.rbac.authorization.k8s.io/longhorn-bind created
customresourcedefinition.apiextensions.k8s.io/engines.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/replicas.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/settings.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/volumes.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/engineimages.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/nodes.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/instancemanagers.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/sharemanagers.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/backingimages.longhorn.io created
customresourcedefinition.apiextensions.k8s.io/backingimagemanagers.longhorn.io created
configmap/longhorn-default-setting created
podsecuritypolicy.policy/longhorn-psp created
role.rbac.authorization.k8s.io/longhorn-psp-role created
rolebinding.rbac.authorization.k8s.io/longhorn-psp-binding created
configmap/longhorn-storageclass created
daemonset.apps/longhorn-manager created
service/longhorn-backend created
deployment.apps/longhorn-ui created
service/longhorn-frontend created
deployment.apps/longhorn-driver-deployer created

$ kubectl get pod -n longhorn-system 
NAME                                        READY   STATUS    RESTARTS   AGE
csi-attacher-54c7586574-4f5kk               1/1     Running   0          13m
csi-attacher-54c7586574-qkv97               1/1     Running   0          13m
csi-attacher-54c7586574-v2j8d               1/1     Running   0          13m
csi-provisioner-5ff5bd6b88-8qtbl            1/1     Running   0          13m
csi-provisioner-5ff5bd6b88-wzgpq            1/1     Running   0          13m
csi-provisioner-5ff5bd6b88-zjqjq            1/1     Running   0          13m
csi-resizer-7699cdfc4-cffvp                 1/1     Running   0          13m
csi-resizer-7699cdfc4-d9cvk                 1/1     Running   0          13m
csi-resizer-7699cdfc4-wmq8r                 1/1     Running   0          13m
csi-snapshotter-8f58f46b4-j97p5             1/1     Running   0          13m
csi-snapshotter-8f58f46b4-q4mr7             1/1     Running   0          13m
csi-snapshotter-8f58f46b4-xwhcs             1/1     Running   0          13m
engine-image-ei-a5a44787-8mggj              1/1     Running   0          15m
engine-image-ei-a5a44787-bqv29              1/1     Running   0          15m
engine-image-ei-a5a44787-q2cst              1/1     Running   0          15m
instance-manager-e-3db801c5                 1/1     Running   0          14m
instance-manager-e-6b2b140b                 1/1     Running   0          15m
instance-manager-e-a7e8665f                 1/1     Running   0          15m
instance-manager-r-9f307d66                 1/1     Running   0          14m
instance-manager-r-cb3ab4ad                 1/1     Running   0          15m
instance-manager-r-eb18aa64                 1/1     Running   0          15m
longhorn-csi-plugin-85twv                   2/2     Running   0          13m
longhorn-csi-plugin-lkdvl                   2/2     Running   0          13m
longhorn-csi-plugin-rxlwj                   2/2     Running   0          13m
longhorn-driver-deployer-5479f45d86-r6hcb   1/1     Running   0          16m
longhorn-manager-88n87                      1/1     Running   1          16m
longhorn-manager-j4cbz                      1/1     Running   0          16m
longhorn-manager-qb4hh                      1/1     Running   0          16m
longhorn-ui-79f8976fbf-2x79z                1/1     Running   0          16m

可以看到,该部署清单会在默认的 longhorn-system 名称空间下部署 csi-attachercsi-provisionercsi-resizerengine-image-eilonghorn-csi-pluginlonghorn-manager 等应用相关的 Pod 对象,待这些 Pod 对象成功转为 Running 状态之后即可测试使用 Longhorn CSI 插件。

该部署清单还会默认创建如下面资源清单中定义的名为 longhornStorageClass 资源:

kind: StorageClass # 资源类型
apiVersion: storage.k8s.io/v1 # API 群组及版本
metadata:
  name: longhorn
provisioner: driver.longhorn.io # 存储供给驱动
allowVolumeExpansion: true # 是否支持存储卷弹性伸缩
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "3" # 副本数量
  staleReplicaTimeout: "2880" # 过期副本超时时长
  fromBackup: ""

它以部署好的 Longhorn 为后端存储系统,支持存储卷动态预配机制。我们也能够以类似的方式定义基于该存储系统的、使用了不同配置的其他 StorageClass 资源,例如仅有一个副本以用于测试场景或对数据可靠性要求并非特别高的应用等。

随后,我们随时可以按需创建基于该存储类的 PVC 资源来使用 Longhorn 存储系统上的持久存储卷提供的存储空间。下面的示例资源清单(pvc-dyn-longhorn-demo.yaml)便定义了一个基于 Longhorn 存储类的 PVC,它请求使用 2GB 的空间。

apiVersion: v1
kind: PersistentVolumeClaim
metadata: 
  name: pvc-dyn-longhorn-demo
  namespace: default
spec: 
  accessModes: ["ReadWriteMany"]
  volumeMode: Filesystem
  resources:
    requests:
      storage: 2Gi
  storageClassName: longhorn

如前所述,Longhorn 存储设备支持动态预配,于是默认以存储类 longhorn 为模板 PVC 在无满足其请求条件的 PV 时,可由控制器自动创建出适配的 PV 卷来。下面两条命令及结果也反映了这种预配机制。

$ kubectl apply -f pvc-dyn-longhorn-demo.yaml
persistentvolumeclaim/pvc-dyn-longhorn-demo created

$ kubectl get pvc
NAME                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-dyn-longhorn-demo   Bound    pvc-61085d88-be9e-45d1-8475-2511ae300810   2Gi        RWX            longhorn       14m

对于每个存储卷,Longhorn 存储系统都会使用自定义的 Volumes 类型资源对象维持及跟踪其运行状态,每个 Volumes 资源都会有一个 Engines 资源对象作为其存储控制器,如下面的两个命令及结果所示:

$ kubectl get volume -n longhorn-system 
NAME                                       STATE      ROBUSTNESS   SCHEDULED   SIZE         NODE   AGE
pvc-61085d88-be9e-45d1-8475-2511ae300810   detached   unknown      True        2147483648          115m

$ kubectl get engine -n longhorn-system 
NAME                                                  STATE     NODE   INSTANCEMANAGER   IMAGE   AGE
pvc-61085d88-be9e-45d1-8475-2511ae300810-e-1ad1ec24   stopped                                    115m

Engines 资源对象的详细描述或资源规范中的 specstatus 字段记录有当前资源的详细信息,包括关联的副本、purge 状态、 恢复状态和快照信息等。

$ kubectl describe engine pvc-61085d88-be9e-45d1-8475-2511ae300810-e-1ad1ec24 -n longhorn-system 
Name:         pvc-61085d88-be9e-45d1-8475-2511ae300810-e-1ad1ec24
Namespace:    longhorn-system
Labels:       longhornnode=
              longhornvolume=pvc-61085d88-be9e-45d1-8475-2511ae300810
Annotations:  <none>
API Version:  longhorn.io/v1beta1
Kind:         Engine
Metadata:
  Creation Timestamp:  2021-07-16T09:57:02Z
  Finalizers:
    longhorn.io
  Generation:  3
  Owner References:
    API Version:     longhorn.io/v1beta1
    Kind:            Volume
    Name:            pvc-61085d88-be9e-45d1-8475-2511ae300810
    UID:             23694c8c-33cd-41c4-a280-a2084eb6e8b6
  Resource Version:  16039903
  Self Link:         /apis/longhorn.io/v1beta1/namespaces/longhorn-system/engines/pvc-61085d88-be9e-45d1-8475-2511ae300810-e-1ad1ec24
  UID:               3875014c-e5bf-4fd8-92e0-a2cafedace02
Spec:
  Backup Volume:     
  Desire State:      stopped
  Disable Frontend:  false
  Engine Image:      longhornio/longhorn-engine:v1.1.2
  Frontend:          blockdev
  Log Requested:     false
  Node ID:           # 绑定的节点,它必须与调用了该存储卷的 Pod 运行于同一节点
  Replica Address Map: # 关联的存储卷副本
    pvc-61085d88-be9e-45d1-8475-2511ae300810-r-9d236e63:  10.244.2.14:10000
    pvc-61085d88-be9e-45d1-8475-2511ae300810-r-9f156bdf:  10.244.0.14:10000
    pvc-61085d88-be9e-45d1-8475-2511ae300810-r-c0517a14:  10.244.1.48:10000
  Requested Backup Restore:                               
  Revision Counter Disabled:                              false
  Salvage Requested:                                      false
  Upgraded Replica Address Map:
  Volume Name:  pvc-61085d88-be9e-45d1-8475-2511ae300810
  Volume Size:  2147483648
Status:
  Backup Status:  <nil>
  Current Image:  
  Current Replica Address Map:
    pvc-61085d88-be9e-45d1-8475-2511ae300810-r-9d236e63:  10.244.2.14:10000
    pvc-61085d88-be9e-45d1-8475-2511ae300810-r-9f156bdf:  10.244.0.14:10000
    pvc-61085d88-be9e-45d1-8475-2511ae300810-r-c0517a14:  10.244.1.48:10000
  Current Size:                                           2147483648
  Current State:                                          stopped
  Endpoint:                                               
  Instance Manager Name:                                  
  Ip:                                                     
  Is Expanding:                                           false
  Last Expansion Error:                                   
  Last Expansion Failed At:                               
  Last Restored Backup:                                   
  Log Fetched:                                            false
  Owner ID:                                               k8s-master1
  Port:                                                   0
  Purge Status:                                           <nil>
  Rebuild Status:                                         <nil>
  Replica Mode Map:                                       <nil>
  Restore Status:                                         <nil>
  Salvage Executed:                                       false
  Snapshots:
    Volume - Head:
      Children:
      Created:  2021-07-16T09:57:29Z
      Labels:
      Name:         volume-head
      Parent:       
      Removed:      false
      Size:         101867520
      Usercreated:  false
  Snapshots Error:  
  Started:          false
Events:
  Type    Reason  Age              From                        Message
  ----    ------  ----             ----                        -------
  Normal  Stop    8s (x2 over 8s)  longhorn-engine-controller  Stops pvc-61085d88-be9e-45d1-8475-2511ae300810-e-1ad1ec24

Replicas 也是 Longhorn 提供的一个独立资源类型,每个资源对象对应着一个存储卷副本,如下面的命令结果所示:

$ kubectl get replica -n longhorn-system 
NAME                                                  STATE     NODE          DISK                                   INSTANCEMANAGER               IMAGE                               AGE
pvc-61085d88-be9e-45d1-8475-2511ae300810-r-9d236e63   running   k8s-master1   16bd736f-bf18-4209-bc76-2d689cabfcfb   instance-manager-r-cb3ab4ad   longhornio/longhorn-engine:v1.1.2   57m
pvc-61085d88-be9e-45d1-8475-2511ae300810-r-9f156bdf   running   k8s-master2   95e94f5e-484e-4ca6-b362-a0cf6ffc0c9b   instance-manager-r-9f307d66   longhornio/longhorn-engine:v1.1.2   57m
pvc-61085d88-be9e-45d1-8475-2511ae300810-r-c0517a14   running   k8s-node1     9106daad-689d-4d39-8a39-68573d3d6dae   instance-manager-r-eb18aa64   longhornio/longhorn-engine:v1.1.2   57m

基于 Longhorn 存储卷的 PVC 被 Pod 引用后,Pod 所在的节点便是该存储卷 Engine 对象运行所在的节点,Engine 的状态也才会由
Stopped 转为 Running。示例清单 test-longhorn-deploy.yaml 定义了一个调用 pvc/pvc-dyn-longhorn-demo 资源的 Deployment 资源,因而该 Deployment 控制器管理的 Pod 所在的节点便是该 PVC 后端 PV 相关的 Engine 绑定的节点,如下面 3 个命令及其结果所示。

$ cat test-longhorn-deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  test-longhorn
  namespace: default
  labels:
    app:  test-longhorn
spec:
  selector:
    matchLabels:
      app: test-longhorn
  replicas: 1
  template:
    metadata:
      labels:
        app:  test-longhorn
    spec:
      containers:
      - name:  test-longhorn
        image:  zze326/test-tools
        volumeMounts:
        - name: longhorn-pvc
          mountPath: /data
      volumes:
        - name: longhorn-pvc
          persistentVolumeClaim: 
            claimName: pvc-dyn-longhorn-demo
      restartPolicy: Always

$ kubectl apply -f test-longhorn-deploy.yaml 
deployment.apps/test-longhorn created

$ kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE
test-longhorn-b6b8b8667-9btgg   1/1     Running   0          74s

$ kubectl get pod test-longhorn-b6b8b8667-9btgg -o jsonpath="{.spec.nodeName}"
k8s-master2

$ kubectl get engine pvc-61085d88-be9e-45d1-8475-2511ae300810-e-1ad1ec24 -n longhorn-system -o jsonpath="{.spec.nodeID}"
k8s-master2

由以上 Longhorn 存储系统的部署及测试结果可知,该存储系统不依赖于任何外部存储设备,仅基于 Kubernetes 集群工作节点本地的存储即能正常提供存储卷服务,且支持动态预配等功能。但应用于生产环境时,还是有许多步骤需要优化,例如将数据存储与操作系统等分离到不同的磁盘设备、是否可以考虑关闭底层的 RAID 设备等,具体请参考 Longhorn 文档中的最佳实践。

Longhorn 还提供了一个 Web 服务来便于我们通过 Kubernetes 集群外部的浏览器访问该用户接口以管理 Longhorn 各项功能,我们需要把相关的 Service 对象的类型修改为 NodePort

$ kubectl patch svc/longhorn-frontend -p '{"spec":{"type":"NodePort"}}' -n longhorn-system
service/longhorn-frontend patched

$ kubectl get svc -n longhorn-system -lapp=longhorn-ui
NAME                TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
longhorn-frontend   NodePort   10.0.0.241   <none>        80:31851/TCP   100m

随后,我们经由任意一个节点的 IP 地址节点端口(例如上面命令中自动分配而来的 31851)即可访问该 UI, 如下图所示:

image.png

节点、存储卷、备份和系统设置导航标签各自给出了相关功能的配置入口,更多其它功能就等着你去探索啦~~附上 Longhorn 官方文档:

需要注意的是,考虑到该 UI 并没有内嵌用户认证机制,如此将其发布到集群外部可能会带来安全风险。

# Kubernetes  

如果这篇文章对您有帮助,可点击下方链接分享给你的朋友们😋,如果遇到问题欢迎评论、留言~~~😇

评论

公众号:zze_coding

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×