Kubernetes官方的external-snapshotter组件只支持基本的快照管理能力,例如:创建快照、删除快照。而阿里云Storage-Snapshot-Manager对官方组件功能进行了扩展,满足云盘快照的更多需求。本文介绍如何使用Storage-Snapshot-Manager组件在ACK集群中创建云盘定时快照、云盘快照策略及使用快照恢复云盘。

前提条件

说明 您在使用集群过程中,请注意以下限制:
  • 默认情况下,每个集群中最多可包含100个节点。如果您需要添加更多节点,请提交工单申请。
  • 添加已有云服务器时,请确保您的专有网络中的ECS实例已经绑定一个弹性公网IP(EIP),或者相应VPC已经配置了NAT网关。您需要确保相应节点能正常访问公网,否则,添加云服务器会失败。

背景信息

Storage-Snapshot-Manager组件的安装与升级由storage-operator组件管理。更多信息,请参见组件介绍

通过控制台自动配置Storage-Snapshot-Manager组件

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 在集群管理页左侧导航栏中,选择运维管理 > 组件管理
  5. 单击存储页签,在storage-operator组件区域单击安装
    控制台会通过storage-operator自动配置Storage-Snapshot-Manager组件。

通过kubectl命令手动配置Storage-Snapshot-Manager组件

步骤一:配置Storage-Snapshot-Manager组件

说明 Storage-Operator组件不会管理手动部署的Storage-Snapshot-Manager组件,请手动升级Storage-Snapshot-Manager组件到新版本。关于storage-operator版本信息,请参见storage-operator
  1. 执行以下命令创建Deployment。
    kubectl apply -f deployment.yaml
    Deployment模板示例如下所示:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: storage-snapshot-manager
      namespace: kube-system
      labels:
        app: storage-snapshot-manager
    spec:
      selector:
        matchLabels:
          app: storage-snapshot-manager
      template:
        metadata:
          labels:
            app: storage-snapshot-manager
        spec:
          tolerations:
            - operator: "Exists"
          priorityClassName: system-node-critical
          serviceAccount: admin
          hostNetwork: true
          hostPID: true
          containers:
          - name: storage-snapshot-manager
            image: registry.${regionId}.aliyuncs.com/acs/storage-snapshot-manager:v1.18.8.0-81508da-aliyun
            imagePullPolicy: Always
            env:
            - name: SNAPSHOT_CLASS
              value: ""
            volumeMounts:
            - name: date-config
              mountPath: /etc/localtime
          volumes:
          - name: date-config
            hostPath:
              path: /etc/localtime
  2. 执行以下命令查看Storage-Snapshot-Manager组件是否启动。
    kubectl get pods -nkube-system | grep storage-snapshot-manager | grep Running

    预期输出:

    NAME         READY   STATUS     RESTARTS   AGE         IP                NODE              NOMINATED NODE   READINESS GATES
    storage-***  1/1     Running    0          6d17h       192.168.XX.XX     virtual-kubelet   <none>           <none>

步骤二:创建VolumeSnapshotClass实例

  1. 执行以下命令创建VolumeSnapshotClass实例。
    kubectl apply -f volume-snapshot-class.yaml
    VolumeSnapshotClass实例模板示例如下所示:
    apiVersion: snapshot.storage.k8s.io/v1beta1 
    deletionPolicy: Delete 
    driver: diskplugin.csi.alibabacloud.com 
    kind: VolumeSnapshotClass 
    metadata: 
      name: default-snapclass 
    parameters: 
      retentionDays: "1" 
  2. 执行以下命令查看VolumeSnapshotClass是否正常创建。
    kubectl get sc | grep default-snapclass

    预期输出:

    NAME                DRIVER                            DELETIONPOLICY   AGE
    default-snapclass   diskplugin.csi.alibabacloud.com   Delete           9d

    当提示以上类似信息时表示VolumeSnapshotClass已创建成功。

步骤三:创建VolumeSnapshotPolicy CRD

  1. 执行以下命令创建CRD。
    kubectl create -f volumesnapshotcrd.yaml
    创建CRD的模板示例如下所示:
    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: volumesnapshotpolicies.storage.alibabacloud.com
    spec:
      group: storage.alibabacloud.com
      versions:
      - name: v1beta1
        served: true
        storage: true
        schema:
          openAPIV3Schema:
            description: VolumeSnapshotPolicy is the Schema for the VolumeSnapshotPolicy API
            properties:
              apiVersion:
                description: 'APIVersion defines the versioned schema of this representation
                        of an object. Servers should convert recognized schemas to the latest
                        internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
                type: string
              kind:
                description: 'Kind is a string value representing the REST resource this
                        object represents. Servers may infer this from the endpoint the client
                        submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
                type: string
              metadata:
                type: object
              spec:
                description: VolumeSnapshotPolicySpec defines the desired Specification of VolumeSnapshotPolicy
                properties:
                  pvcSelector:
                    description: pvcSelector select pvcs which suppose to apply VolumeSnapshotPolicy 
                    type: object
                    properties:
                      matchLabels:
                        x-kubernetes-preserve-unknown-fields: true
                        description: matchLabels select multi pvcs by match pvc labels 
                        type: object
                  volumeSnapshotNamespaces:
                    description: volumeSnapshotNamespaces defines which namespace should VolumeSnapshot be created
                    type: array
                    items:
                      type: string
                  retentionDays:
                    description: retentionDays is days to save snapshot
                    format: int64
                    type: integer
                  snapshotSchedule:
                    type: object
                    description: snapshotSchedule defines generate rules that how to generate VolumeSnapshot 
                    properties:
                      repeatOnce:
                        description: repeatOnce defines only generate snapshot once
                        type: boolean
                      repeatWeekdays:
                        description: RepeatWeekdays is a list of days in a week to create disk snapshot
                        type: array
                        items:
                            type: string
                      timePoints:
                        description: TimePoints is a list of hours in a day to create disk snapshot
                        type: array
                        items:
                            type: string
                type: object
            type: object
        subresources:
          status: {}
      scope: Cluster
      names:
        kind: VolumeSnapshotPolicy
        plural: volumesnapshotpolicies
        shortNames:
        - vsp
  2. 执行以下命令查看CRD是否已正确创建。
    kubectl get crd volumesnapshotpolicies.storage.alibabacloud.com

    预期输出:

    NAME                                                 CREATED AT
    volumesnapshotpolicies.storage.alibabacloud.com      2021-03-09T03:26:42Z

    当提示以上类似信息时表示CRD已创建成功。

步骤四:添加云产品访问权限

对于托管版集群,请按照以下步骤操作。

  1. 使用具有RAM权限的账号登录RAM管理控制台
  2. 选择左侧导航栏的权限管理 > 权限策略管理
  3. 权限策略管理页面单击创建权限策略
  4. 新建自定义权限策略页面配置自定义权限策略。
    1. 新建自定义权限策略页面,填写策略名称(例如StorageSnapshotManager),并在配置模式区域选择脚本配置
    2. 将以下内容添加到策略内容中。
      {
                  "Effect": "Allow",
                  "Action": [
                      "ecs:DescribeInstances",
                      "ecs:CreateAutoSnapshotPolicy",
                      "ecs:DeleteAutoSnapshotPolicy",
                      "ecs:DescribeSnapshots",
                      "ecs:ApplyAutoSnapshotPolicy",
                      "ecs:ModifyAutoSnapshotPolicy",
                      "ecs:DescribeAutoSnapshotPolicyEX"
                  ],
                  "Resource": [
                      "*"
                  ],
                  "Condition": {}
      }
    3. 单击确定

对于专有版集群,请按照以下步骤操作。

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 集群信息页面,单击集群资源页签,单击Worker RAM角色右侧链接。
  5. 在RAM角色基本信息的权限管理页签,单击KubernetesWorkerRole-***的权限策略名称。
  6. 单击修改策略内容
  7. 修改策略内容面板增加以下内容后,单击确定
    {
                "Effect": "Allow",
                "Action": [
                    "ecs:DescribeInstances",
                    "ecs:CreateAutoSnapshotPolicy",
                    "ecs:DeleteAutoSnapshotPolicy",
                    "ecs:DescribeSnapshots",
                    "ecs:ApplyAutoSnapshotPolicy",
                    "ecs:ModifyAutoSnapshotPolicy",
                    "ecs:DescribeAutoSnapshotPolicyEX"
                ],
                "Resource": [
                    "*"
                ],
                "Condition": {}
    }
    说明 多个策略内容需要用半角逗号(,)分隔。

创建云盘快照及快照策略

  1. 执行以下命令创建PV。
    kubectl apply -f pv.yaml

    以下为创建PV的pv.yaml示例文件。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: csi-pv-snapshot-policy
      labels:
        app: nginx
        alicloud-pvname: static-disk-pv-snapshot-policy
    spec:
      capacity:
        storage: 25Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      csi:
        driver: diskplugin.csi.alibabacloud.com
        volumeHandle: <your-disk-id>
  2. 执行以下命令创建PVC。
    kubectl apply -f pvc.yaml

    以下为创建PV的pvc.yaml示例文件。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: csi-pvc-snapshot-policy
      labels:
        app: nginx
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 25Gi
      selector:
        matchLabels:
          alicloud-pvname: static-disk-pv-snapshot-policy
  3. 创建Pod并关联创建的PV及PVC。
    kubectl apply -f pod.yaml

    以下为创建Pod的pod.yaml示例文件。

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web-policy
    spec:
      selector:
        matchLabels:
          app: nginx-policy
      serviceName: "nginx"
      template:
        metadata:
          labels:
            app: nginx-policy
        spec:
          containers:
          - name: nginx-policy
            image: nginx
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: pvc-disk
              mountPath: /data
          volumes:
            - name: pvc-disk
              persistentVolumeClaim:
                claimName: csi-pvc-snapshot-policy

    当Pod启动之后,Storage-Snapshot-Manager组件会自动将PV对应的<your-disk-id>与VolumeSnapshotPolicy进行关联,并按照策略生成快照。

  4. 创建VolumeSnapshotPolicy实例。

    执行以下命令创建定时快照类型实例。

    kubectl apply -f VolumeSnapshotPolicy.yaml
    以下为创建定时快照类型VolumeSnapshotPolicy实例的VolumeSnapshotPolicy.yaml示例文件。
    apiVersion: storage.alibabacloud.com/v1alpha1
    kind: VolumeSnapshotPolicy
    metadata:
      name: volumesnapshotpolicy1
    spec:
     pvcSelector:
      matchLabels:
       app: nginx1
     reclaimPolicy: Delete
     retentionDays: 1
     snapshotSchedule:
       repeatWeekdays: ["1", "2"]
      timePoints: ["11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]
    说明 部分参数说明如下:
    • pvcSelector:快照策略覆盖的PVC,通过PVC Labels指定。
    • retentionDays:自动快照创建保留天数,当为-1时表示永久保存。repeatOnce不支持该参数。
    • snapshotSchedule.repeatWeekdays:一周内自动创建快照的时间点(天),可设置为1~7。
    • snapshotSchedule.timePoints:一天内自动创建快照的时间点(小时),可设置为0~23。

    在集群创建VolumeSnapshotPolicy实例时,ECS控制台会在对应ECS服务上自动创建快照策略。

  5. 查看定时快照策略是否生效。
    1. 登录ECS管理控制台
    2. 在左侧导航栏,选择存储与快照 > 快照
    3. 单击自动快照策略页签,查看快照策略是否已关联执行云盘。
      自动快照策略
  6. 执行以下命令通过VolumeSnapshotPolicy CRD修改快照策略。
    说明 修改快照策略时请注意以下事项:
    • 修改快照策略会影响该策略关联的所有云盘,请谨慎修改。
    • 建议不要在ECS管理控制台进行策略修改,所有的修改请通过CRD操作,否则将会更新快照创建时间。
    kubectl edit volumesnapshotpolicy volumesnapshotpolicy1

使用生成的快照进行云盘恢复

绑定定时快照策略之后,会在集群中看到自动创建的快照。

  1. 执行以下命令查看集群中创建的快照。
    kubectl get volumesnapshot

    预期输出:

    NAME          READYTOUSE   RESTORESIZE   DELETIONPOLICY   DRIVER                            VOLUMESNAPSHOTCLASS   VOLUMESNAPSHOT     AGE
    s-uf6221***   true         41943040      Delete           diskplugin.csi.alibabacloud.com   default-snapclass     s-uf6221***        7m40s
    s-uf65y0***   true         41943040      Delete           diskplugin.csi.alibabacloud.com   default-snapclass     s-uf65y0***        7m40s
    s-uf6a83***   true         41943040      Delete           diskplugin.csi.alibabacloud.com   default-snapclass     s-uf6a83***        7m40s
    s-uf6fmp***   true         41943040      Delete           diskplugin.csi.alibabacloud.com   default-snapclass     s-uf6fmp***        7m40s
  2. 执行以下命令使用任意一个volumesnapshot进行云盘的恢复。
    kubectl apply -f VolumeSnapshot.yaml

    以下为创建多个云盘快照类型VolumeSnapshotPolicy实例的VolumeSnapshot.yaml示例文件,以s-uf6221***为例:

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web-restore
    spec:
      selector:
        matchLabels:
          app: nginx
      serviceName: "nginx"
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
        spec:
          hostNetwork: true
          containers:
          - name: nginx
            image: nginx
            command: ["sh", "-c"]
            args: ["sleep 10000"]
            volumeMounts:
            - name: disk-ssd
              mountPath: /data
      volumeClaimTemplates:
      - metadata:
          name: disk-ssd
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: alicloud-disk-ssd
          resources:
            requests:
              storage: 20Gi
          dataSource:
            name: s-uf6221***
            kind: VolumeSnapshot
            apiGroup: snapshot.storage.k8s.io

    Pod启动后,云盘快照数据恢复到应用中。

常见问题

回答:云盘自动快照策略只会在重启和VolumeSnapshotPolicy创建时建立,如遇到这种情况,请删除位于kube-system命名空间下Storage-Snapshot-Manager组件的Pod,使其自动重启,便可创建出新的云盘自动快照策略。
回答:PVC一旦创建快照之后,便会为PVC添加finalizers:snapshot.storage.kubernetes.io/pvc-as-source-protection,除非删除所有关联PVC的VolumeSnapshot及VolumeSnapshotContent,否则PVC便会一直无法删除。