k8s雲原生分布式塊存儲 --Longhorn 初體驗


我們了解了本地存儲、NFS共享存儲,除了這些存儲類型之外,還有一個塊存儲,同樣為 Kubernetes 提供塊存儲的方案有很多,比如 Ceph RBD,今天我們為大家介紹的是 Rancher 開源的一款 Kubernetes 的雲原生分布式塊存儲方案 - Longhorn

使用 Longhorn,可以:

  • 使用 Longhorn 卷作為 Kubernetes 集群中分布式有狀態應用程序的持久存儲
  • 將你的塊存儲分區為 Longhorn 卷,以便你可以在有或沒有雲提供商的情況下使用 Kubernetes 卷
  • 跨多個節點和數據中心復制塊存儲以提高可用性
  • 將備份數據存儲在 NFS 或 AWS S3 等外部存儲中
  • 創建跨集群災難恢復卷,以便可以從第二個 Kubernetes 集群中的備份中快速恢復主 Kubernetes 集群中的數據
  • 調度一個卷的快照,並將備份調度到 NFS 或 S3 兼容的二級存儲
  • 從備份還原卷
  • 不中斷持久卷的情況下升級 Longhorn

Longhorn 還帶有獨立的 UI,可以使用 Helm、kubectl 或 Rancher 應用程序目錄進行安裝。

架構

Longhorn 為每個卷創建一個專用的存儲控制器,並在多個節點上存儲的多個副本之間同步復制該卷。Longhorn 在整體上分為兩層:數據平面和控制平面,Longhorn Engine 是存儲控制器,對應數據平面,Longhorn Manager 對應控制平面。

Longhorn Manager 會以 DaemonSet 的形式在 Longhorn 集群中的每個節點上運行,它負責在 Kubernetes 集群中創建和管理卷,並處理來自 UI 或 Kubernetes 卷插件的 API 調用,它是遵循 Kubernetes 控制器模式。

Longhorn Manager 通過與 Kubernetes APIServer 通信來創建新的 Longhorn volume CRD,然后 Longhorn Manager 會一直 Watch APIServer 的響應,當它看到發現創建了一個新的 Longhorn volume CRD 時,Longhorn Manager 就會去創建一個新的對應卷。當 Longhorn Manager 被要求創建一個卷時,它會在卷所連接的節點上創建一個 Longhorn Engine 實例,並在每個將放置副本的節點上創建一個副本,副本應放置在不同的主機上以確保最大可用性。副本的多條數據路徑確保了 Longhorn 卷的高可用性,即使某個副本或引擎出現問題,也不會影響所有副本或 Pod 對卷的訪問。

Longhorn Engine 始終與使用 Longhorn 卷的 Pod 在同一節點中運行,它在存儲在多個節點上的多個副本之間同步復制卷。

如下圖所示,描述了 Longhorn 卷、Longhorn Engine、副本實例和磁盤之間的讀/寫數據流:

卷、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 查看。

安裝

要在 Kubernetes 集群上安裝 Longhorn,需要集群的每個節點都必須滿足以下要求:

  • 與 Kubernetes 兼容的容器運行時(Docker v1.13+、containerd v1.3.7+ 等)
  • 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。

依賴

為了驗證這些環境要求,Longhorn 官方提供了一個腳本來幫助我們進行檢查,執行該腳本需要在本地安裝 jq 工具,執行下面的命令即可運行腳本:

➜ curl -sSfL https://raw.githubusercontent.com/longhorn/longhorn/v1.2.3/scripts/environment_check.sh | bash
daemonset.apps/longhorn-environment-check created
waiting for pods to become ready (0/2)
waiting for pods to become ready (0/2)
all pods ready (2/2)

  MountPropagation is enabled!

cleaning up...
daemonset.apps "longhorn-environment-check" deleted
clean up complete

如果沒有檢查通過會給出相關的提示信息。

要安裝 open-iscsi,可以直接使用下面的命令即可:

# apt-get install open-iscsi # Debian 和 Ubuntu 系統命令 ➜ yum install -y iscsi-initiator-utils

Longhorn 官方還為我們還提供了一個 iscsi 安裝程序,可以更輕松地自動安裝 open-iscsi

➜ kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.2.3/deploy/prerequisite/longhorn-iscsi-installation.yaml

部署完成后,運行以下命令來檢查安裝程序的 pod 狀態:

➜ kubectl get pod | grep longhorn-iscsi-installation
longhorn-iscsi-installation-49hd7   1/1     Running   0          21m
longhorn-iscsi-installation-pzb7r   1/1     Running   0          39m

也可以通過以下命令查看日志,查看安裝結果:

➜ kubectl logs longhorn-iscsi-installation-pzb7r -c iscsi-installation
...
Installed:
  iscsi-initiator-utils.x86_64 0:6.2.0.874-7.amzn2

Dependency Installed:
  iscsi-initiator-utils-iscsiuio.x86_64 0:6.2.0.874-7.amzn2

Complete!
Created symlink from /etc/systemd/system/multi-user.target.wants/iscsid.service to /usr/lib/systemd/system/iscsid.service.
iscsi install successfully

同樣要安裝 NFSv4 客戶端,可以直接使用下面的命令一鍵安裝:

# apt-get install nfs-common # Debian 和 Ubuntu 系統命令 ➜ yum install nfs-utils

同樣 Longhorn 官方也提供了一個 nfs 客戶端安裝程序,可以更輕松地自動安裝 nfs-client:

➜ kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.2.3/deploy/prerequisite/longhorn-nfs-installation.yaml

部署完成后,運行以下命令來檢查安裝程序的 pod 狀態:

➜ kubectl get pod | grep longhorn-nfs-installation
NAME                                  READY   STATUS    RESTARTS   AGE
longhorn-nfs-installation-t2v9v   1/1     Running   0          143m
longhorn-nfs-installation-7nphm   1/1     Running   0          143m

也可以通過以下命令查看日志,查看安裝結果:

➜ kubectl logs longhorn-nfs-installation-t2v9v -c nfs-installation
...
nfs install successfully

相關依賴環境准備好過后就可以開始安裝 Longhorn 了。

部署

官方支持使用 Rancher Catalog 應用、kubectl 與 helm 三種方式來進行安裝,同樣這里我們選擇使用 helm 進行安裝。

首先添加 longhorn 的 chart 倉庫:

➜ helm repo add longhorn https://charts.longhorn.io
➜ helm repo update

然后可以根據自己的實際場景定制 values 文件,可以通過下面的命令獲取默認的 values 文件:

➜ curl -Lo values.yaml https://raw.githubusercontent.com/longhorn/charts/master/charts/longhorn/values.yaml

然后可以修改 values 文件中的配置,longhorn 推薦單獨掛盤作為存儲使用,這里作為測試直接使用默認的 /var/lib/longhorn 目錄。

如下所示默認配置的示例片段:

defaultSettings: backupTarget: s3://backupbucket@us-east-1/backupstore backupTargetCredentialSecret: minio-secret createDefaultDiskLabeledNodes: true defaultDataPath: /var/lib/longhorn-example/ replicaSoftAntiAffinity: false storageOverProvisioningPercentage: 600 storageMinimalAvailablePercentage: 15 upgradeChecker: false defaultReplicaCount: 2 defaultDataLocality: disabled guaranteedEngineCPU: defaultLonghornStaticStorageClass: longhorn-static-example backupstorePollInterval: 500 taintToleration: key1=value1:NoSchedule; key2:NoExecute systemManagedComponentsNodeSelector: "label-key1:label-value1" priority-class: high-priority autoSalvage: false disableSchedulingOnCordonedNode: false replicaZoneSoftAntiAffinity: false volumeAttachmentRecoveryPolicy: never nodeDownPodDeletionPolicy: do-nothing mkfsExt4Parameters: -O ^64bit,^metadata_csum guaranteed-engine-manager-cpu: 15 guaranteed-replica-manager-cpu: 15 ingress: # 開啟ingress enabled: true ingressClassName: nginx # 配置 ingressclass host: longhorn.k8s.local annotations: # 添加annotations nginx.ingress.kubernetes.io/proxy-body-size: 10000m enablePSP: false

然后執行下面的命令一鍵安裝 Longhorn:

➜ helm upgrade --install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace -f values.yaml
NAME: longhorn
LAST DEPLOYED: Sun Feb 20 16:14:05 2022
NAMESPACE: longhorn-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Longhorn is now installed on the cluster!

Please wait a few minutes for other Longhorn components such as CSI deployments, Engine Images, and Instance Managers to be initialized.

Visit our documentation at https://longhorn.io/docs/

部署后可以查看 Pod 的運行狀態來確保安裝正確:

➜ kubectl get pods -n longhorn-system
NAME                                        READY   STATUS    RESTARTS   AGE
csi-attacher-5f46994f7-fqntq                1/1     Running   0          33s
csi-attacher-5f46994f7-ltxg8                1/1     Running   0          36m
csi-attacher-5f46994f7-vw75d                1/1     Running   0          36m
csi-provisioner-6ccbfbf86f-bvc99            1/1     Running   0          33s
csi-provisioner-6ccbfbf86f-k46hn            1/1     Running   0          36m
csi-provisioner-6ccbfbf86f-lxm8h            1/1     Running   0          36m
csi-resizer-6dd8bd4c97-52gmm                1/1     Running   0          35m
csi-resizer-6dd8bd4c97-9btj6                1/1     Running   0          3s
csi-resizer-6dd8bd4c97-fdjmp                1/1     Running   0          35m
csi-snapshotter-86f65d8bc-5mjk2             1/1     Running   0          33s
csi-snapshotter-86f65d8bc-5rrfs             1/1     Running   0          35m
csi-snapshotter-86f65d8bc-bg6nv             1/1     Running   0          35m
engine-image-ei-fa2dfbf0-jrb2d              1/1     Running   0          36m
engine-image-ei-fa2dfbf0-m5799              1/1     Running   0          36m
instance-manager-e-051171e6                 1/1     Running   0          36m
instance-manager-e-db94b4b7                 1/1     Running   0          24m
instance-manager-r-dd84ad5c                 1/1     Running   0          36m
instance-manager-r-f5eefb8a                 1/1     Running   0          24m
longhorn-csi-plugin-mljt2                   2/2     Running   0          35m
longhorn-csi-plugin-rfzcj                   2/2     Running   0          24m
longhorn-driver-deployer-6db849975f-dh4p4   1/1     Running   0          58m
longhorn-manager-bxks6                      1/1     Running   0          24m
longhorn-manager-tj58k                      1/1     Running   0          2m50s
longhorn-ui-6f547c964-k56xr                 1/1     Running   0          58m

由於上面安裝的時候我們添加了 Ingress 支持,所以可以通過配置的域名去訪問 Longhorn UI:

➜ kubectl get ingress  -n longhorn-system
NAME               CLASS   HOSTS                ADDRESS         PORTS   AGE
longhorn-ingress   nginx   longhorn.k8s.local   192.168.31.31   80      4m11s

這里我們使用的 ingress-nginx 這個控制器,安裝完成后在瀏覽器中直接訪問 http://longhorn.k8s.local 即可:

Longhorn UI

Longhorn UI 界面中展示了當前存儲系統的狀態,也可以在頁面中進行其他相關配置。

此外還會創建一個默認的 StorageClass 對象:

➜ kubectl get sc longhorn
NAME                 PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
longhorn (default)   driver.longhorn.io   Delete          Immediate           true                   91m
➜ kubectl get sc longhorn -o yaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  annotations:
    ......
    storageclass.kubernetes.io/is-default-class: "true"
  creationTimestamp: "2022-02-20T09:32:51Z"
  ......
  name: longhorn
  resourceVersion: "4524911"
  uid: 6066e858-e7ab-4dab-95db-7ff829e6e01b
parameters:
  fromBackup: ""
  fsType: ext4
  numberOfReplicas: "3"
  staleReplicaTimeout: "30"
provisioner: driver.longhorn.io
reclaimPolicy: Delete
volumeBindingMode: Immediate

測試

下面我們來測試使用 longhorn 提供一個存儲卷,由於提供了默認的 StorageClass,所以直接創建 PVC 即可,創建一個如下所示的 PVC:

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

然后部署一個 mysql 應用來使用上面的 PVC 進行數據持久化:

apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: containers: - image: mysql:5.6 name: mysql env: - name: MYSQL_ROOT_PASSWORD value: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: data mountPath: /var/lib/mysql volumes: - name: data persistentVolumeClaim: claimName: mysql-pvc

直接創建上面的資源對象:

➜ kubectl get pvc mysql-pvc
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-pvc   Bound    pvc-ec17a7e4-7bb4-4456-9380-353db3ed4307   1Gi        RWO            longhorn       8s
➜ kubectl get pods
NAME                     READY   STATUS    RESTARTS      AGE
mysql-6879698bd4-r8cxz   1/1     Running   0             3m10s
➜ kubectl exec -it mysql-6879698bd4-r8cxz -- mysql -uroot -ppassword
Warning: Using a password on the command line interface can be insecure.
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 longhorn; Query OK, 1 row affected (0.01 sec)  mysql>

應用啟動成功后我們可以去節點上查看數據來驗證是否成功:

➜ ls /var/lib/longhorn/
engine-binaries  longhorn-disk.cfg  replicas
➜ ls /var/lib/longhorn/replicas/
pvc-ec17a7e4-7bb4-4456-9380-353db3ed4307-c40376c5
➜ ls /var/lib/longhorn/replicas/pvc-ec17a7e4-7bb4-4456-9380-353db3ed4307-c40376c5
revision.counter  volume-head-000.img  volume-head-000.img.meta  volume.meta

需要注意的是 longhorn 是分布式塊存儲,與分布式文件系統不同,不能超過 pv 設置的存儲大小(上例中為1G)。我們在數據庫中創建了一個名為 longhorn 的數據庫,然后我們重建 Pod 再次查看數據是否依然存在:

➜ kubectl get pods
NAME                     READY   STATUS    RESTARTS      AGE
mysql-6879698bd4-s8tfv   1/1     Running   0             6s
➜  kubectl exec -it mysql-6879698bd4-s8tfv -- mysql -uroot -ppassword
Warning: Using a password on the command line interface can be insecure.
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 | | longhorn | | #mysql50#lost+found | | mysql | | performance_schema | +---------------------+ 5 rows in set (0.00 sec)  mysql>

可以看到前面創建的數據庫依然存在,證明我們的數據持久化成功了。在 Longhorn UI 界面中也可以看到數據卷的信息:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM