Longhorn,企业级云原生容器分布式存储 - 备份与恢复

Longhorn,企业级云原生容器分布式存储 - 备份与恢复

内容来源于官方 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 对象。

公众号:黑客下午茶

Longhorn,企业级云原生容器分布式存储 - 备份与恢复

上一篇:0823面试


下一篇:设计模式之模板方法