Longhorn,企業級雲原生容器分散式儲存 - 備份與恢復

為少發表於2021-08-24

內容來源於官方 Longhorn 1.1.2 英文技術手冊。

系列

目錄

  • 建立一個快照
  • 週期性(Recurring)快照和備份
    • 使用 Longhorn UI 設定週期性快照
    • 使用 StorageClass 設定 Recurring Jobs
    • 分離卷時允許 Recurring Job
  • 容災卷
    • 建立容災(DR)卷
  • 設定備份目標
    • 設定 AWS S3 備份儲存
    • 設定本地測試備份儲存
    • 使用自簽名 SSL 證書進行 S3 通訊
    • S3 相容的備份儲存啟用 virtual-hosted-style 訪問
    • NFS 備份儲存
  • 建立備份
  • 從備份恢復
  • Kubernetes StatefulSets 恢復卷
  • 在叢集上啟用 CSI 快照支援
    • 新增一個預設的 VolumeSnapshotClass
    • 如果您在 Air Gap 環境中從以前的 Longhorn 版本進行更新
    • 如果您的 Kubernetes 發行版未捆綁 Snapshot Controller
  • 通過 CSI 建立備份
  • 通過 CSI Mechanism 建立備份
    • CSI Mechanism 工作原理
    • 檢視備份
    • VolumeSnapshot 示例
  • 通過 CSI 恢復備份
  • 通過 VolumeSnapshot 物件恢復備份
    • 還原沒有關聯 VolumeSnapshot 的備份

建立一個快照

snapshotKubernetes Volume 在任何給定時間點的狀態。

要建立現有叢集的快照,

  1. Longhorn UI 的頂部導航欄中,單擊 Volume
  2. 單擊要為其建立快照的卷的名稱。這會導致卷詳細資訊頁面。
  3. 單擊 Take Snapshot 按鈕。

建立快照後,您將在卷頭(Volume Head)之前的卷的快照列表中看到它。

週期性快照和備份

Longhorn UI,可以安排週期性快照和備份。

要設定時間表(schedule),您將轉到 Longhorn 中的卷詳細資訊檢視。然後你將設定:

  • schedule 型別,備份(backup)快照(snapshot)
  • 將建立備份或快照的時間,以 CRON expression 的形式
  • 要保留的備份或快照的數量
  • 應應用於備份或快照的任何標籤(Any labels)

然後 Longhorn 會自動為當時的使用者建立快照或備份,只要該卷附加到一個節點。

可以使用 Longhorn UI 或使用 Kubernetes StorageClass 配置週期性快照。

注意:為了避免當卷長時間沒有新資料時,recurring jobs 可能會用相同的備份和空快照覆蓋舊的備份/快照的問題,Longhorn 執行以下操作:

  1. Recurring backup job 僅在自上次備份以來卷有新資料時才進行新備份。
  2. Recurring snapshot job 僅在卷頭(volume head)中有新資料(實時資料)時才拍攝新快照。

使用 Longhorn UI 設定週期性快照

可以從卷詳細資訊頁面配置週期性快照和備份。要導航到此頁面,請單擊 Volume,,然後單擊卷的名稱。

使用 StorageClass 設定 Recurring Jobs

可以在 StorageClassrecurringJobs 引數中配置計劃備份和快照。

使用這個 StorageClass 建立的任何未來卷都將自動設定這些 recurring jobs

recurringJobs 欄位應遵循以下 JSON 格式:

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: longhorn
    provisioner: driver.longhorn.io
    parameters:
      numberOfReplicas: "3"
      staleReplicaTimeout: "30"
      fromBackup: ""
      recurringJobs: '[
        {
          "name":"snap",
          "task":"snapshot",
          "cron":"*/1 * * * *",
          "retain":1
        },
        {
          "name":"backup",
          "task":"backup",
          "cron":"*/2 * * * *",
          "retain":1
        }
      ]'

應為每個 recurring job 指定以下引數:

  1. name:一項 job 的名稱。不要在一個 recurringJobs 中使用重複的名稱。 並且 name 的長度不能超過 8 個字元。

  2. task:一項 job 的型別。它僅支援 snapshot(定期建立快照)或backup(定期建立快照然後進行備份)。

  3. cronCron 表示式。它告訴一項 job 的執行時間。

  4. retainLonghorn 將為一項 job 保留多少快照/備份(snapshots/backups)。應該不少於 1

分離卷時允許 Recurring Job

Longhorn 提供了 allow-recurring-job-while-volume-detached 設定,即使卷已分離,您也可以進行週期性備份(recurring backup)。您可以在 Longhorn UI 中找到該設定。

啟用該設定後,Longhorn 將自動附加捲並在需要執行週期性快照/備份(recurring snapshot/backup)時進行快照/備份。

請注意,在卷自動附加(attached automatically)期間,卷尚未準備好處理工作負載。Workload 必須等到 recurring job 完成。

容災卷

容災 (DR) 卷是一種特殊卷,主要用於在整個主叢集出現故障時將資料儲存在備份叢集中。災難恢復卷用於提高 Longhorn 卷的彈性。

對於災難恢復卷,Last Backup 表示其原始備份卷的最新備份。

如果代表災難卷的圖示為灰色,則表示該卷正在恢復 Last Backup,並且該卷無法啟用。如果圖示為藍色,則表示該卷已恢復 Last Backup

建立容災(DR)卷

先決條件: 設定兩個 Kubernetes 叢集。它們將被稱為叢集 A 和叢集 B。在兩個叢集上安裝 Longhorn,並在兩個叢集上設定相同的備份目標。

  1. 在叢集 A 中,確保原始卷 X 已建立備份或已安排 recurring backups
  2. 在叢集 B 的備份頁面,選擇備份卷 X,然後建立容災卷 Y。強烈建議使用備份卷名作為容災卷名。
  3. Longhorn 會自動將 DRY 附加到隨機節點。然後 Longhorn 將開始輪詢卷 X 的最後一次備份,並將其增量恢復到卷 Y

設定備份目標

備份目標是用於訪問 Longhornbackupstore 的端點。backupstoreNFS 伺服器或 S3 相容伺服器,用於儲存 Longhorn 卷的備份。備份目標可以在 Settings/General/BackupTarget 中設定。

如果您無權訪問 AWS S3 或想先嚐試備份儲存,我們還提供了一種使用 MinIO 設定本地 S3 測試備份儲存的方法。

Longhorn 還支援通過 Longhorn UIKubernetes Storage Class 為卷設定週期性快照/備份(recurring snapshot/backup)作業。

設定 AWS S3 備份儲存

  1. AWS S3 中建立一個新儲存桶。

  2. Longhorn 設定許可權。有兩種設定憑據的選項。首先,您可以使用 AWS IAM 使用者的憑證設定 Kubernetes secret。第二個是您可以使用第三方應用程式通過 annotations 來管理 Pod 的臨時 AWS IAM 許可權,而不是使用 AWS 憑證進行操作。

    • 選項 1:使用 IAM 使用者憑證建立 Kubernetes secret

      1. 按照指南建立新的 AWS IAM 使用者,並設定以下許可權。編輯 Resource 部分以使用您的 S3儲存桶名稱:

        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "GrantLonghornBackupstoreAccess0",
              "Effect": "Allow",
              "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject"
              ],
              "Resource": [
                "arn:aws:s3:::<your-bucket-name>",
                "arn:aws:s3:::<your-bucket-name>/*"
              ]
            }
          ]
        }
        
      2. 在放置 Longhorn 的名稱空間(預設為 longhorn-system)中建立一個名稱為 aws-secretKubernetes secretsecret 必須在 longhorn-system 名稱空間中建立,以便 Longhorn 訪問它:

        kubectl create secret generic <aws-secret> \
            --from-literal=AWS_ACCESS_KEY_ID=<your-aws-access-key-id> \
            --from-literal=AWS_SECRET_ACCESS_KEY=<your-aws-secret-access-key> \
            -n longhorn-system
        
    • 選項 2:通過 AWS STS AssumeRolekube2iamkiam)使用 IAM 臨時憑證設定許可權

      kube2iamkiam 是一個 Kubernetes 應用程式,它允許通過 annotations 而不是操作 AWS 憑證來管理 PodAWS IAM 許可權。按照 kube2iamkiamGitHub 儲存庫中的說明將其安裝到 Kubernetes 叢集中。

      1. 按照指南AWS S3 服務建立新的 AWS IAM 角色,並設定以下許可權:

        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "GrantLonghornBackupstoreAccess0",
              "Effect": "Allow",
              "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject"
              ],
              "Resource": [
                "arn:aws:s3:::<your-bucket-name>",
                "arn:aws:s3:::<your-bucket-name>/*"
              ]
            }
          ]
        }
        
      2. 使用以下信任關係編輯 AWS IAM 角色:

        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                  "Service": "ec2.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            },
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<AWS_EC2_NODE_INSTANCE_ROLE>"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        }
        
      3. Longhorn 所在的名稱空間(預設為 longhorn-system)中建立一個名稱為 aws-secretKubernetes secretsecret 必須在 longhorn-system 名稱空間中建立,以便 Longhorn 訪問它:

        kubectl create secret generic <aws-secret> \
            --from-literal=AWS_IAM_ROLE_ARN=<your-aws-iam-role-arn> \
            -n longhorn-system
        
  3. 轉到 Longhorn UI。在頂部導航欄中,單擊 Settings。 在 Backup 部分中,將 Backup Target 設定為:

    s3://<your-bucket-name>@<your-aws-region>/
    

    確保末尾有 /,否則會報錯。可以使用子目錄(字首):

    s3://<your-bucket-name>@<your-aws-region>/mypath/
    

    還要確保您在 URL 中設定了 <your-aws-region>

    例如,對於 AWS,您可以在:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html 找到區域程式碼(region codes)。

    對於 Google Cloud Storage,您可以在:https://cloud.google.com/storage/docs/locations
    找到區域程式碼。

  4. 在備份部分將 備份目標憑據 Secret(Backup Target Credential Secret) 設定為:

    aws-secret
    

    這是具有 AWS 憑證或 AWS IAM 角色的 secret 名稱。

Result: Longhorn 可以在 S3 中儲存備份。要建立備份,請參閱本節

Note: 如果您在代理後面操作 Longhorn 並且您想使用 AWS S3 作為備份儲存,您必須在 aws-secret 中提供有關您的代理的 Longhorn 資訊,如下所示:

kubectl create secret generic <aws-secret> \
    --from-literal=AWS_ACCESS_KEY_ID=<your-aws-access-key-id> \
    --from-literal=AWS_SECRET_ACCESS_KEY=<your-aws-secret-access-key> \
    --from-literal=HTTP_PROXY=<your-proxy-ip-and-port> \
    --from-literal=HTTPS_PROXY=<your-proxy-ip-and-port> \
    --from-literal=NO_PROXY=<excluded-ip-list> \
    -n longhorn-system

確保 NO_PROXY 包含不應使用代理(proxy)的網路地址(network addresses)、網路地址範圍和域(network address ranges and domains)。為了讓 Longhorn 執行,NO_PROXY 的最低要求值為:

  • localhost
  • 127.0.0.1
  • 0.0.0.0
  • 10.0.0.0/8 (K8s components' IPs)
  • 192.168.0.0/16 (internal IPs in the cluster)

設定本地測試備份儲存

我們在 ./deploy/backupstores 中提供了兩個基於 NFS serverMinIO S3 server 的測試目的備份儲存(backupstore)。

  1. 建立 longhorn-system 後,使用以下命令為備份儲存設定 MinIO S3 伺服器。

    kubectl create -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/backupstores/minio-backupstore.yaml
    
  2. 轉到 Longhorn UI。在頂部導航欄中,單擊 Settings。在 Backup 部分,將 Backup Target 設定為

    s3://backupbucket@us-east-1/
    

    並將 Backup Target Credential Secret(備份目標憑據 Secret) 設定為:

    minio-secret
    

    minio-secret yaml 如下所示:

    apiVersion: v1
    kind: Secret
    metadata:
      name: minio-secret
      namespace: longhorn-system
    type: Opaque
    data:
      AWS_ACCESS_KEY_ID: bG9uZ2hvcm4tdGVzdC1hY2Nlc3Mta2V5 # longhorn-test-access-key
      AWS_SECRET_ACCESS_KEY: bG9uZ2hvcm4tdGVzdC1zZWNyZXQta2V5 # longhorn-test-secret-key
      AWS_ENDPOINTS: aHR0cHM6Ly9taW5pby1zZXJ2aWNlLmRlZmF1bHQ6OTAwMA== # https://minio-service.default:9000
      AWS_CERT: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMRENDQWhTZ0F3SUJBZ0lSQU1kbzQycGhUZXlrMTcvYkxyWjVZRHN3RFFZSktvWklodmNOQVFFTEJRQXcKR2pFWU1CWUdBMVVFQ2hNUFRHOXVaMmh2Y200Z0xTQlVaWE4wTUNBWERUSXdNRFF5TnpJek1EQXhNVm9ZRHpJeApNakF3TkRBek1qTXdNREV4V2pBYU1SZ3dGZ1lEVlFRS0V3OU1iMjVuYUc5eWJpQXRJRlJsYzNRd2dnRWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEWHpVdXJnUFpEZ3pUM0RZdWFlYmdld3Fvd2RlQUQKODRWWWF6ZlN1USs3K21Oa2lpUVBvelVVMmZvUWFGL1BxekJiUW1lZ29hT3l5NVhqM1VFeG1GcmV0eDBaRjVOVgpKTi85ZWFJNWRXRk9teHhpMElPUGI2T0RpbE1qcXVEbUVPSXljdjRTaCsvSWo5Zk1nS0tXUDdJZGxDNUJPeThkCncwOVdkckxxaE9WY3BKamNxYjN6K3hISHd5Q05YeGhoRm9tb2xQVnpJbnlUUEJTZkRuSDBuS0lHUXl2bGhCMGsKVHBHSzYxc2prZnFTK3hpNTlJeHVrbHZIRXNQcjFXblRzYU9oaVh6N3lQSlorcTNBMWZoVzBVa1JaRFlnWnNFbQovZ05KM3JwOFhZdURna2kzZ0UrOElXQWRBWHExeWhqRDdSSkI4VFNJYTV0SGpKUUtqZ0NlSG5HekFnTUJBQUdqCmF6QnBNQTRHQTFVZER3RUIvd1FFQXdJQ3BEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBVEFQQmdOVkhSTUIKQWY4RUJUQURBUUgvTURFR0ExVWRFUVFxTUNpQ0NXeHZZMkZzYUc5emRJSVZiV2x1YVc4dGMyVnlkbWxqWlM1awpaV1poZFd4MGh3Ui9BQUFCTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFDbUZMMzlNSHVZMzFhMTFEajRwMjVjCnFQRUM0RHZJUWozTk9kU0dWMmQrZjZzZ3pGejFXTDhWcnF2QjFCMVM2cjRKYjJQRXVJQkQ4NFlwVXJIT1JNU2MKd3ViTEppSEtEa0Jmb2U5QWI1cC9VakpyS0tuajM0RGx2c1cvR3AwWTZYc1BWaVdpVWorb1JLbUdWSTI0Q0JIdgpnK0JtVzNDeU5RR1RLajk0eE02czNBV2xHRW95YXFXUGU1eHllVWUzZjFBWkY5N3RDaklKUmVWbENtaENGK0JtCmFUY1RSUWN3cVdvQ3AwYmJZcHlERFlwUmxxOEdQbElFOW8yWjZBc05mTHJVcGFtZ3FYMmtYa2gxa3lzSlEralAKelFadHJSMG1tdHVyM0RuRW0yYmk0TktIQVFIcFc5TXUxNkdRakUxTmJYcVF0VEI4OGpLNzZjdEg5MzRDYWw2VgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    

    有關建立 secret 的更多資訊,請參閱 Kubernetes 文件
    secret 必須在 longhorn-system 名稱空間中建立,以便 Longhorn 訪問它。

    Note: 生成 base64 編碼時一定要使用 echo -n,否則會在字串末尾新增新行,訪問 S3 時會出錯。

  3. 單擊 UI 中的 Backup 選項卡。它應該報告一個沒有任何錯誤的空列表。

Result: Longhorn 可以在 S3 中儲存備份。

使用自簽名 SSL 證書進行 S3 通訊

如果要使用自簽名 SSL 證書,可以在提供給 LonghornKubernetes secret 中指定 AWS_CERT
請參閱設定本地測試備份儲存中的示例。
需要注意的是,證書需要採用 PEM 格式,並且必須是其自己的 CA
或者必須包含一個包含 CA 證書的證書鏈。
要包含多個證書,只需連線不同的證書(PEM 檔案)即可。

為 S3 相容的備份儲存啟用 virtual-hosted-style 訪問

在以下情況下,您可能需要為 S3 相容的備份儲存啟用這種新的定址方法

  1. 您想立即切換到這種新的訪問方式,這樣您就無需擔心 Amazon S3 路徑棄用計劃
  2. 您使用的 backupstore 只支援 virtual-hosted-style 的訪問,例如:Alibaba Cloud(Aliyun) OSS
  3. 您已配置 MINIO_DOMAIN 環境變數以啟用 MinIO 伺服器的 virtual-host-style 請求
  4. 這個錯誤 ...... error: AWS Error: SecondLevelDomainForbidden Please use virtual hosted style to access. ..... 被觸發。

啟用 virtual-hosted-style 訪問的方法

  1. 將值為 true 的新欄位 VIRTUAL_HOSTED_STYLE 新增到您的備份目標 secret。例如:

    apiVersion: v1
    kind: Secret
    metadata:
      name: s3-compatible-backup-target-secret
      namespace: longhorn-system
    type: Opaque
    data:
      AWS_ACCESS_KEY_ID: bG9uZ2hvcm4tdGVzdC1hY2Nlc3Mta2V5
      AWS_SECRET_ACCESS_KEY: bG9uZ2hvcm4tdGVzdC1zZWNyZXQta2V5
      AWS_ENDPOINTS: aHR0cHM6Ly9taW5pby1zZXJ2aWNlLmRlZmF1bHQ6OTAwMA==
      VIRTUAL_HOSTED_STYLE: dHJ1ZQ== # true
    
  2. 部署/更新(Deploy/update) secret,並在 Settings/General/BackupTargetSecret 中設定它。

NFS 備份儲存

要將 NFS 伺服器用作備份儲存,NFS 伺服器必須支援 NFSv4

目標 URL 應如下所示:

nfs://longhorn-test-nfs-svc.default:/opt/backupstore

Result: Longhorn 可以在 NFS 中儲存備份。

建立備份

Longhorn 中的 Backups 是叢集外備份儲存中的物件。快照的備份被複制到備份儲存,訪問備份儲存的端點是備份目標。

先決條件: 必須設定備份目標。有關更多資訊,請參閱設定備份目標。如果尚未設定 BackupTarget,則會出現錯誤。

要建立備份,

  1. 導航到 Volume 選單。
  2. 選擇要備份的卷。
  3. 單擊 Create Backup
  4. 新增適當的標籤並單擊 OK

Result: 備份已建立。要檢視它,請單擊頂部導航欄中的 Backup

從備份恢復

Longhorn 可以輕鬆地將備份恢復到一個卷。

還原備份時,預設情況下會建立一個同名的卷。如果已存在與備份同名的卷,則不會恢復備份。

要恢復備份,

  1. 導航到 Backup 選單
  2. 選擇您要恢復的備份,然後單擊 Restore Latest Backup
  3. Name 欄位中,選擇要恢復的卷
  4. 單擊 OK

Result: 恢復的卷在 Volume 頁面上可用。

為 Kubernetes StatefulSets 恢復卷

Longhorn 支援恢復備份,該特性的一個用例是恢復 Kubernetes StatefulSet 中使用的資料,這需要為備份的每個副本恢復一個卷。

要恢復,請按照以下說明操作。下面的示例使用一個 StatefulSet,其中一個卷附加到每個 Pod 和兩個副本。

  1. 連線到 Web 瀏覽器中的 Longhorn UI 頁面。在 Backup 選項卡下,選擇 StatefulSet 卷的名稱。單擊卷條目的下拉選單並恢復它。將卷命名為稍後可以輕鬆引用的 Persistent Volumes

    • 對需要恢復的每個卷重複此步驟。
    • 例如,如果使用具有名為 pvc-01apvc-02b 的卷的兩個副本恢復 StatefulSet,則恢復可能如下所示:
    Backup Name Restored Volume
    pvc-01a statefulset-vol-0
    pvc-02b statefulset-vol-1
  2. Kubernetes 中,為每個建立的 Longhorn 卷建立一個 Persistent Volume。將卷命名為稍後可以輕鬆引用的 Persistent Volume Claimsstorage 容量、numberOfReplicasstorageClassNamevolumeHandle 必須在下面替換。在這個例子中,我們在 Longhorn 中引用了 statefulset-vol-0statefulset-vol-1,並使用 longhorn 作為我們的 storageClassName

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: statefulset-vol-0
    spec:
      capacity:
        storage: <size> # must match size of Longhorn volume
      volumeMode: Filesystem
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Delete
      csi:
        driver: driver.longhorn.io # driver must match this
        fsType: ext4
        volumeAttributes:
          numberOfReplicas: <replicas> # must match Longhorn volume value
          staleReplicaTimeout: '30' # in minutes
        volumeHandle: statefulset-vol-0 # must match volume name from Longhorn
      storageClassName: longhorn # must be same name that we will use later
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: statefulset-vol-1
    spec:
      capacity:
        storage: <size>  # must match size of Longhorn volume
      volumeMode: Filesystem
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Delete
      csi:
        driver: driver.longhorn.io # driver must match this
        fsType: ext4
        volumeAttributes:
          numberOfReplicas: <replicas> # must match Longhorn volume value
          staleReplicaTimeout: '30'
        volumeHandle: statefulset-vol-1 # must match volume name from Longhorn
      storageClassName: longhorn # must be same name that we will use later
    
  3. namespace 中,將部署 StatefulSet,為每個 Persistent Volume 建立 PersistentVolume ClaimsPersistent Volume Claim 的名稱必須遵循以下命名方案:

    <name of Volume Claim Template>-<name of StatefulSet>-<index>
    

    StatefulSet Pod 是零索引(zero-indexed)的。
    在這個例子中,Volume Claim Template 的名字是 dataStatefulSet 的名字是 webapp
    並且有兩個副本,分別是索引 01

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: data-webapp-0
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 2Gi # must match size from earlier
    storageClassName: longhorn # must match name from earlier
    volumeName: statefulset-vol-0 # must reference Persistent Volume
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: data-webapp-1
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 2Gi # must match size from earlier
    storageClassName: longhorn # must match name from earlier
    volumeName: statefulset-vol-1 # must reference Persistent Volume
    
  4. 建立 StatefulSet:

    apiVersion: apps/v1beta2
    kind: StatefulSet
    metadata:
      name: webapp # match this with the PersistentVolumeClaim naming scheme
    spec:
      selector:
        matchLabels:
          app: nginx # has to match .spec.template.metadata.labels
      serviceName: "nginx"
      replicas: 2 # by default is 1
      template:
        metadata:
          labels:
            app: nginx # has to match .spec.selector.matchLabels
        spec:
          terminationGracePeriodSeconds: 10
          containers:
          - name: nginx
            image: k8s.gcr.io/nginx-slim:0.8
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: data
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: data # match this with the PersistentVolumeClaim naming scheme
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: longhorn # must match name from earlier
          resources:
            requests:
              storage: 2Gi # must match size from earlier
    

Result: 現在應該可以從 StatefulSet Pods 內部訪問恢復的資料。

在叢集上啟用 CSI 快照支援

先決條件

CSI 快照支援可用於 Kubernetes 版本 >= 1.17

Kubernetes 發行版負責部署快照控制器(snapshot controller)以及相關的自定義資源定義。

有關更多資訊,請參閱 CSI 卷快照

新增一個預設的 VolumeSnapshotClass

確保 Snapshot Beta CRD 的可用性。然後建立一個預設的 VolumeSnapshotClass

kind: VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1beta1
metadata:
  name: longhorn
driver: driver.longhorn.io
deletionPolicy: Delete

如果您在 Air Gap 環境中從以前的 Longhorn 版本進行更新

  1. 更新 csi-provisioner 映象到 longhornio/csi-provisioner:v1.6.0
  2. 更新 csi-snapshotter 映象到 longhornio/csi-snapshotter:v2.1.1

如果您的 Kubernetes 發行版未捆綁 Snapshot Controller

您可以通過執行以下步驟手動安裝這些元件。

請注意,下面提到的 snapshot controller YAML 檔案部署到 default 名稱空間中。

先決條件

對於一般用途,請在安裝之前使用適當的 namespace 更新 snapshot controller YAML

例如,在 vanilla Kubernetes 叢集上,在發出 kubectl create 命令之前,將名稱空間從 default 更新為 kube-system

安裝 Snapshot Beta CRDs

  1. https://github.com/kubernetes-csi/external-snapshotter/tree/release-4.0/client/config/crd 下載檔案
  2. 執行 kubectl create -f client/config/crd.
  3. 每個叢集執行一次。

安裝 Common Snapshot Controller

  1. https://github.com/kubernetes-csi/external-snapshotter/tree/release-4.0/deploy/kubernetes/snapshot-controller 下載檔案
  2. namespace 更新為適合您環境的值(例如:kube-system
  3. 執行 kubectl create -f deploy/kubernetes/snapshot-controller
  4. 每個叢集執行一次。

有關其他資訊,請參閱 kubernetes external-snapshotter git repo 中的 Usage 部分。

通過 CSI 建立備份

Longhorn 中的 Backups 是叢集外備份儲存(backupstore)中的物件,訪問備份儲存的端點是備份目標。

要以程式設計方式建立 backups,您可以使用通用的 Kubernetes CSI 快照機制。

先決條件: 需要在您的叢集上啟用 CSI snapshot 支援。
如果您的 kubernetes 發行版沒有提供 kubernetes snapshot controller
以及快照相關的自定義資源定義,您需要手動部署它們
更多資訊,參閱 Enable CSI Snapshot Support

通過 CSI Mechanism 建立備份

要使用 CSI 機制建立備份,請通過 kubectl 建立一個 Kubernetes VolumeSnapshot 物件。

Result:
已建立備份。VolumeSnapshot 物件的建立導致了 VolumeSnapshotContent Kubernetes 物件的建立。

VolumeSnapshotContent 是指其 VolumeSnapshotContent.snapshotHandle 欄位中名為 bs://backup-volume/backup-nameLonghorn backup

CSI Mechanism 工作原理

當使用 kubectl 建立 VolumeSnapshot 物件時,VolumeSnapshot.uuid 欄位用於標識 Longhorn snapshot 和關聯的 VolumeSnapshotContent 物件。

這將建立一個名為 snapshot-uuid 的新 Longhorn snapshot

然後啟動該 snapshotbackup,並返回 CSI request

然後建立一個名為 snapcontent-uuidVolumeSnapshotContent 物件。

CSI snapshotter sidecar 定期查詢 Longhorn CSI 外掛以評估備份狀態(backup status)。

備份完成後,VolumeSnapshotContent.readyToUse 標誌設定為 true

檢視備份

要檢視備份,請單擊頂部導航欄中的 Backup 並導航到 VolumeSnapshotContent.snapshotHandle 中提到的備份卷(backup-volume)。

VolumeSnapshot 示例

下面是一個示例 VolumeSnapshot 物件。source 需要指向應為其建立備份的 Longhorn volumePVC

volumeSnapshotClassName 欄位指向一個 VolumeSnapshotClass

我們建立了一個名為 longhorn 的預設類,它使用 Delete 作為它的 deletionPolicy

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: test-snapshot-pvc
spec:
  volumeSnapshotClassName: longhorn
  source:
    persistentVolumeClaimName: test-vol

如果您希望在刪除 VolumeSnapshot 時保留卷的關聯備份,請建立一個新的 VolumeSnapshotClass,並將 Retain 設定為 deletionPolicy

有關快照類的更多資訊,請參閱 VolumeSnapshotClasseskubernetes 文件。

通過 CSI 恢復備份

Longhorn 可以輕鬆地將備份恢復到一個卷。

要以程式設計方式恢復備份,您可以使用通用的 kubernetes csi 快照機制。

先決條件

需要在您的叢集上啟用 CSI 快照支援。

如果您的 Kubernetes 發行版未提供 Kubernetes snapshot controller 以及與快照相關的自定義資源定義,則您需要手動部署它們。

通過 VolumeSnapshot 物件恢復備份

建立一個 PersistentVolumeClaim 物件,其中 dataSource 欄位指向現有的 VolumeSnapshot 物件。

csi-provisioner 將獲取它並指示 Longhorn CSI driver 使用關聯備份(associated backup)中的資料來配置新卷。

您可以使用相同的機制來恢復尚未通過 CSI 機制建立的 Longhorn 備份。

下面是一個 PersistentVolumeClaim 示例。 dataSource 欄位需要指向現有的 VolumeSnapshot 物件。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-restore-snapshot-pvc
spec:
  storageClassName: longhorn
  dataSource:
    name: test-snapshot-pvc
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

還原沒有關聯 VolumeSnapshot 的備份

要恢復未通過 CSI 機制建立的 Longhorn 備份,您必須首先手動為備份建立 VolumeSnapshotVolumeSnapshotContent 物件。

建立一個 VolumeSnapshotContent 物件,並將 snapshotHandle 欄位設定為 bs://backup-volume/backup-name

backup-volumebackup-name 值可以從 Longhorn UIBackup 頁面檢索。

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotContent
metadata:
  name: test-existing-backup
spec:
  volumeSnapshotClassName: longhorn
  driver: driver.longhorn.io
  deletionPolicy: Delete
  source:
    # NOTE: change this to point to an existing backup on the backupstore
    snapshotHandle: bs://test-vol/backup-625159fb469e492e
  volumeSnapshotRef:
    name: test-snapshot-existing-backup
    namespace: default

建立關聯的 VolumeSnapshot 物件,並將 name 欄位設定為 test-snapshot-existing-backup,其中 source 欄位通過 volumeSnapshotContentName 欄位引用 VolumeSnapshotContent 物件。

這與建立 backup 不同,在這種情況下,source 欄位通過 persistentVolumeClaimName 欄位引用 PerstistentVolumeClaim

只能為 VolumeSnapshot 物件設定一種型別的引用。

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: test-snapshot-existing-backup
spec:
  volumeSnapshotClassName: longhorn
  source:
    volumeSnapshotContentName: test-existing-backup

現在您可以建立一個引用新建立的 VolumeSnapshot 物件的 PerstistentVolumeClaim 物件。

公眾號:黑客下午茶

相關文章