All Products
Search
Document Center

Container Service for Kubernetes:Back up and restore applications with kubectl

Last Updated:Oct 10, 2026

If you cannot access Backup Center from the Container Service for Kubernetes (ACK) console due to permission restrictions, or need to automate disaster recovery, use kubectl instead. Deploy the BackupLocation, ApplicationBackup, BackupSchedule, ApplicationRestore, and DeleteRequest custom resources (CRs) in the backup and restore clusters to migrate applications between clusters.

Prerequisites

Ensure that the following conditions are met:

Usage notes

  • Keep migrate-controller up to date. See Components.

  • Use DeleteRequest to remove backup and restore jobs. kubectl delete does not remove associated backup data. Use a DeleteRequest CR instead. See Step 4: Delete backup and restore resources.

  • Do not remove parameters from the example YAML files. Removing required fields causes backup and restore to fail.

  • BackupLocation resources cannot be deleted from Backup Center because repositories may be shared across clusters.

Step 1: Create a backup repository

A backup repository (BackupLocation) defines the Object Storage Service (OSS) bucket that stores backup data. Create the same BackupLocation on both the backup and restore clusters so they share the same data.

  1. Create backuplocation.yaml:

    apiVersion: csdr.alibabacloud.com/v1beta1
    kind: BackupLocation
    metadata:
      name: <your-backup-repository-name>   # Required. Must follow Kubernetes naming conventions
      namespace: csdr
    spec:
      backupSyncPeriod: 0s
      config:
        network: internal   # Required. internal: access over the internal network; all
                            # associated clusters and the OSS bucket must be in the same region
                            # public: access over the Internet; no region restriction
        region: cn-beijing  # Required. Region where the OSS bucket is located
      objectStorage:
        bucket: <cnfs-oss-your-bucket-name>   # Required. Must start with cnfs-oss-; create in advance
        prefix: <your-subdirectory-name>       # Optional: store backups in this subdirectory
      provider: alibabacloud

    No configuration is required for the other parameters. Keep the default values.

  2. Apply the manifest on both clusters:

    kubectl apply -f backuplocation.yaml
  3. Verify the repository is available on each cluster:

    kubectl describe backuplocation <your-backup-repository-name> -n csdr

    The repository is ready when Phase shows Available:

    ...
    Status:
      Last Validation Time:  2022-12-08T04:00:22Z
      Message:               success by csdr-controller
      Phase:                 Available

    Available confirms the cluster can access the OSS bucket.

Step 2: Create a backup job

Backup Center supports two backup types:

  • Application Backup: Backs up Kubernetes resources (such as StatefulSets and Deployments) with their Persistent Volumes (PVs).

  • Data Protection: Backs up volume data only, without application resources. The backed-up resources are limited to Persistent Volume Claims (PVCs) and PVs.

See Scenarios for Application Backup and Data Protection.

Each type supports on-demand and scheduled backups.

Application backup

On-demand backup

  1. Create applicationbackup.yaml in the backup cluster:

    Important

    Configure either includedResources or excludedResources, not both. When both are empty, all resource types are backed up.

    For console-created backup jobs, includeClusterResources defaults to false.
    apiVersion: csdr.alibabacloud.com/v1beta1
    kind: ApplicationBackup
    metadata:
      annotations:
        # Required. Information about the backup repository that stores this backup.
        # The value must match the backup repository configuration.
        csdr.alibabacloud.com/backuplocations: >-
          {"name":"<your-backup-repository-name>","region":"cn-beijing","bucket":"<cnfs-oss-your-bucket-name>","prefix":"<your-subdirectory-name>","provider":"alibabacloud"}
      name: <your-application-backup-name>   # Required. Name of the on-demand backup
      namespace: csdr
    spec:
      includedNamespaces:
        - default                # Required. Namespaces to include in the backup
      includedResources:
        - statefulset            # Optional. Resource types to back up
      excludedResources:         # Optional. Configuring this parameter together with includedResources
        - deployment             # causes unexpected results. Configure only one of them.
                                 # If both are empty, all resource types are backed up.
      labelSelector:
        matchLabels:
          app: mysql-sts         # Optional. Only resources with this label are backed up
      includeClusterResources: false   # Optional. false: only cluster-level resources referenced
                                       # by selected namespace resources are backed up
                                       # (such as ClusterRoles and CRDs)
                                       # true: all cluster-level resources are backed up
      pvBackup:
        defaultPvBackup: false   # Required. Whether to back up PVs, that is, whether to
                                 # enable data backup:
                                 # false: back up application resources only
                                 # true: back up application resources and PVs
      storageLocation: <your-backup-repository-name>
                                 # Required. Name of the backup repository.
                                 # Note: If your cluster already uses Velero, join the
                                 # DingTalk user group (Group Number: 35532895) for assistance.
      ttl: 720h0m0s              # Required. Retention period; range: 24h0m0s to
                                 # 1572864h0m0s. Backup data cannot be restored
                                 # after the retention period expires.

    No configuration is required for the other parameters. Keep the default values.

  2. Apply the manifest in the backup cluster:

    kubectl apply -f applicationbackup.yaml
  3. Check the backup status:

    kubectl describe applicationbackup <your-application-backup-name> -n csdr

    The backup is complete when Phase changes from Inprogress to Completed:

    ...
    Status:
      Completion Timestamp:  2022-12-05T15:02:35Z
      Expiration:            2023-01-04T15:02:25Z
      Message:               success
      Phase:                 Completed

Scheduled backup

  1. Create backupschedule.yaml in the backup cluster:

    apiVersion: csdr.alibabacloud.com/v1beta1
    kind: BackupSchedule
    metadata:
      annotations:
        # Required. Information about the backup repository that stores this backup.
        # The value must match the backup repository configuration.
        csdr.alibabacloud.com/backuplocations: >-
          {"name":"<your-backup-repository-name>","region":"cn-beijing","bucket":"<cnfs-oss-your-bucket-name>","prefix":"<your-subdirectory-name>","provider":"alibabacloud"}
      name: <your-backup-schedule-name>   # Required. Name of the scheduled backup plan
      namespace: csdr
    spec:
      schedule: 1 4 * * *   # Required. Cron expression:
                             # ┌── minute (0–59)
                             # │ ┌── hour (0–23)
                             # │ │ ┌── day of month (1–31)
                             # │ │ │ ┌── month (1–12)
                             # │ │ │ │ ┌── day of week (0–6, Sunday=0)
                             # │ │ │ │ │
                             # 1 4 * * *  → runs at 04:01 every day
                             # For more cron examples, see How to specify a backup schedule.
      template:
        includedNamespaces:
          - default              # Required. Namespaces to include in the backup
        includedResources:
          - statefulset          # Optional. Resource types to back up
        excludedResources:       # Optional. Configuring this parameter together with includedResources
          - deployment           # causes unexpected results. Configure only one of them.
                                 # If both are empty, all resource types are backed up.
        labelSelector:
          matchLabels:
            app: mysql-sts       # Optional. Only resources with this label are backed up
        includeClusterResources: false   # Optional
        pvBackup:
          defaultPvBackup: true   # Required. Whether to back up PVs, that is, whether to
                                  # enable data backup:
                                  # true: back up application resources and PVs
                                  # false: back up application resources only
        storageLocation: <your-backup-repository-name>
                                   # Required. Name of the backup repository.
                                   # Note: If your cluster already uses Velero, join the
                                   # DingTalk user group (Group Number: 35532895) for assistance.
        ttl: 720h0m0s              # Required. Retention period; range: 24h0m0s to
                                   # 1572864h0m0s. Backup data cannot be restored
                                   # after the retention period expires.

    No configuration is required for the other parameters. Keep the default values.

    See How to specify a backup schedule.

  2. Apply the manifest in the backup cluster:

    kubectl apply -f backupschedule.yaml
  3. Verify the schedule is active:

    kubectl describe backupschedule <your-backup-schedule-name> -n csdr

    The schedule is running when Phase shows Enabled:

    ...
    Status:
      Last Backup:          2022-12-07T20:01:11Z
      Last Processed Time:  2022-12-08T13:05:37Z
      Phase:                Enabled
  4. List the point-in-time backups created by the schedule:

    kubectl get applicationbackup -n csdr | grep <your-backup-schedule-name>

    Each scheduled run creates a timestamped ApplicationBackup resource:

    <your-backup-schedule-name>-20221205225845   2d22h
    <your-backup-schedule-name>-20221206040104   2d17h
    <your-backup-schedule-name>-20221207040137   41h
    <your-backup-schedule-name>-20221208040111   17h

    Note these names—you need them to create a restore task.

Data protection

Data Protection backs up volume data (PVCs and PVs) only. Use kind: ApplicationBackup with backupType: PvBackup (a fixed value).

On-demand backup

  1. Create applicationbackup.yaml in the backup cluster:

    Important

    If both pvcList and storageClassList are specified, storageClassList is ignored. If neither is specified, all PVs in the specified namespace are backed up.

    apiVersion: csdr.alibabacloud.com/v1beta1
    kind: ApplicationBackup
    metadata:
      annotations:
        # Required. Information about the backup repository that stores this backup.
        # The value must match the backup repository configuration.
        csdr.alibabacloud.com/backuplocations: >-
          {"name":"<your-backup-repository-name>","region":"cn-beijing","bucket":"<cnfs-oss-your-bucket-name>","prefix":"<your-subdirectory-name>","provider":"alibabacloud"}
      name: <your-application-backup-name>   # Required. Name of the on-demand backup
      namespace: csdr
    spec:
      backupType: PvBackup   # Required. Fixed value for Data Protection
      includedNamespaces:
        - default      # Required. Namespaces to include in the backup
      pvBackup:
        # Optional. Option 1: specify PVs by PVC name. If you also specify storageClassList,
        # storageClassList is ignored. Configure only one of the two parameters.
        pvcList:
          - name: essd-pvc-0
            namespace: default
          - name: essd-pvc-1
            namespace: default
        # Optional. Option 2: specify PVs by storage class. This parameter is ignored if you
        # also specify pvcList. Configure only one of the two parameters.
        storageClassList:
          - disk-essd
          - disk-ssd
        # If neither pvcList nor storageClassList is set, all PVs in the namespace are backed up.
      storageLocation: <your-backup-repository-name>
                       # Required. Name of the backup repository.
                       # Note: If your cluster already uses Velero, join the
                       # DingTalk user group (Group Number: 35532895) for assistance.
      ttl: 720h0m0s    # Required. Retention period; range: 24h0m0s to
                       # 1572864h0m0s. Backup data cannot be restored
                       # after the retention period expires.
  2. Apply the manifest in the backup cluster:

    kubectl apply -f applicationbackup.yaml
  3. Check the backup status:

    kubectl describe applicationbackup <your-application-backup-name> -n csdr

    Expected output when complete:

    ...
    Status:
      Completion Timestamp:  2025-03-25T08:20:24Z
      Expiration:            2025-04-24T08:18:03Z
      Message:               success
      Phase:                 Completed

Scheduled backup

  1. Create backupschedule.yaml in the backup cluster:

    apiVersion: csdr.alibabacloud.com/v1beta1
    kind: BackupSchedule
    metadata:
      annotations:
        # Required. Information about the backup repository that stores this backup.
        # The value must match the backup repository configuration.
        csdr.alibabacloud.com/backuplocations: >-
          {"name":"<your-backup-repository-name>","region":"cn-beijing","bucket":"<cnfs-oss-your-bucket-name>","prefix":"<your-subdirectory-name>","provider":"alibabacloud"}
      name: <your-backup-schedule-name>   # Required. Name of the scheduled backup plan
      namespace: csdr
    spec:
      schedule: 1 4 * * *      # Required. Backup interval in cron format
      template:
        backupType: PvBackup   # Required. Fixed value for Data Protection
        includedNamespaces:
          - default            # Required. Namespaces to include in the backup
        pvBackup:
          # Optional. Specify PVs by PVC name. If you also specify storageClassList,
          # storageClassList is ignored. Configure only one of the two parameters.
          pvcList:
            - name: essd-pvc-0
              namespace: default
            - name: essd-pvc-1
              namespace: default
          # Optional. Specify PVs by storage class. This parameter is ignored if you also
          # specify pvcList. Configure only one of the two parameters.
          storageClassList:
            - disk-essd
            - disk-ssd
        storageLocation: <your-backup-repository-name>   # Required. Backup repository name
        ttl: 720h0m0s          # Required. Retention period; range: 24h0m0s to
                               # 1572864h0m0s. Backup data cannot be restored
                               # after the retention period expires.
  2. Apply the manifest in the backup cluster:

    kubectl apply -f backupschedule.yaml
  3. Verify the schedule is active:

    kubectl describe backupschedule <your-backup-schedule-name> -n csdr

    Expected output when active:

    ...
    Status:
      Last Backup:  2025-03-25T09:24:38Z
      Phase:        Enabled

Step 3: Create a restore task

  1. Create applicationrestore.yaml in the restore cluster:

    appRestoreOnly, preserveNodePorts, includedResources, and excludedResources apply to Application Backup only and are ignored in Data Protection.
    To find PVC names and data types, run kubectl describe applicationbackup <your-application-backup-name> -n csdr and check status.resourceList.dataResource.pvcBackupInfo. dataType shows FileSystem or Snapshot; nameSpace and pvcName identify the PVC. In convertedarg, convertToStorageClassType, namespace, and persistentVolumeClaim are required. namespace is the namespace of the persistent volume claim and persistentVolumeClaim is its name. convertToAccessModes is an optional list of target access modes.
    Important

    To avoid unexpected restore results, configure only one of includedResources and excludedResources. If both are empty, all backed-up resource types are restored.

    apiVersion: csdr.alibabacloud.com/v1beta1
    kind: ApplicationRestore
    metadata:
      annotations:
        # Required. Information about the backup repository that stores this backup.
        # The value must match the backup repository configuration.
        csdr.alibabacloud.com/backuplocations: >-
          {"name":"<your-backup-repository-name>","region":"cn-beijing","bucket":"<cnfs-oss-your-bucket-name>","prefix":"<your-subdirectory-name>","provider":"alibabacloud"}
      name: <your-application-restore-name>   # Required. Name of the restore task
      namespace: csdr
    spec:
      backupName: <your-application-backup-name>   # Required. The backup to restore. When you restore
                                                    # from a scheduled backup plan, specify
                                                    # the timestamped name, for example:
                                                    # <your-backup-schedule-name>-20221205225845
      includedNamespaces:
        - default             # Required. Namespaces to restore; leave blank to restore all backed-up namespaces
      appRestoreOnly: false   # Optional. Application Backup only; ignored in Data Protection. For
                              # a backup that includes PV data, specifies whether to restore
                              # applications only, without PVCs, PVs, and their data:
                              # false (default): restore application resources and PV data
                              # true: restore application resources only. To change the data
                              # source of the restored application, create the PVCs and PVs
                              # in advance, and set this parameter to true.
      preserveNodePorts: true # Optional. Whether to preserve the NodePort of the
                              # application. When the backup cluster and the restore cluster
                              # are the same, the default is false.
                              # false: assign random NodePort values to avoid conflicts
                              #        with existing applications of the same type
                              # true: preserve original NodePort values (use when
                              #       restoring to a different cluster)
      includedResources:
        - statefulset         # Optional. Application Backup only; resource types to restore
      excludedResources:
        - secret              # Optional. Application Backup only; resource types to skip
      namespaceMapping:
        <source-namespace>: <target-namespace>   # Optional. Remap namespace during restore;
                                                  # target namespace is created if it
                                                  # doesn't exist
      imageRegistryMapping:
        <old-image-registry>: <new-image-registry>   # Optional. Remap the image registry for all
                                                       # application images whose address starts
                                                       # with the source address. The key is a
                                                       # registry prefix, not a full image path.
                                                       # For example, map
                                                       # registry.cn-beijing.aliyuncs.com/my-registry/
                                                       # to registry.cn-hangzhou.aliyuncs.com/my-registry/
                                                       # to restore nginx:v1 from Beijing to Hangzhou.
                                                       # If not set, the image settings in the
                                                       # applications remain unchanged.
      convertedarg:           # Optional. StorageClass conversions for file system-type
                              # volumes. Source volume types include OSS, File Storage
                              # NAS (NAS), Cloud Parallel File Storage (CPFS), local
                              # storage, and other file system types. The current version
                              # supports only Cloud Disk or File Storage NAS storage classes
                              # as conversion targets.
        - convertToStorageClassType: alicloud-disk-topology-alltype   # Required. Target StorageClass
                                                                       # (must exist in cluster)
          convertToAccessModes:   # Optional. List of target access modes
            - ReadWriteOnce   # Required when converting PVs with ReadWriteMany or
                              # ReadOnlyMany access modes to a Cloud Disk StorageClass,
                              # to avoid the risk of forced disk detachment
          namespace: nas      # Required. Namespace of the PVC
          persistentVolumeClaim: pvc-nas     # Required. Name of the PVC
        - convertToStorageClassType: alicloud-disk-topology-alltype
          namespace: oss
          persistentVolumeClaim: pvc-oss

    No configuration is required for the other parameters. Keep the default values.

  2. Apply the manifest in the restore cluster:

    kubectl apply -f applicationrestore.yaml
  3. Check the restore status:

    kubectl describe applicationrestore <your-application-restore-name> -n csdr

    The restore is complete when Phase changes from Inprogress to Completed:

    ...
    Status:
      Completion Timestamp:  2022-12-05T15:52:19Z
      Phase:                 Completed
      Start Timestamp:       2022-12-05T15:52:09Z

Step 4: Delete backup and restore resources

Important

Do not use kubectl delete to remove ApplicationBackup or ApplicationRestore resources. kubectl delete does not remove associated data. Use a DeleteRequest CR instead.

Delete a scheduled backup plan

Delete the BackupSchedule resource to stop a schedule and prevent future backups:

kubectl delete backupschedule <your-backup-schedule-name> -n csdr

Delete a backup job or restore task

  1. Create deleterequest.yaml in the cluster where the resource resides:

    Important
    • Deleting a backup job does not affect the data that has been backed up to the backup repository.

    • Deleting a restore task does not affect the restored resources.

    apiVersion: csdr.alibabacloud.com/v1beta1
    kind: DeleteRequest
    metadata:
      name: <object-name>-dbr   # Required. Append -dbr to the name of the resource being deleted
      namespace: csdr
    spec:
      deleteObjectName: <object-name>         # Required. Name of the ApplicationBackup or
                                               # ApplicationRestore resource to delete
      deleteObjectType: "Backup"              # Required. "Backup": deletes the ApplicationBackup job
                                               # and its associated resources. "Restore": deletes
                                               # the ApplicationRestore task and its
                                               # associated resources

    No configuration is required for the other parameters. Keep the default values.

  2. Apply the delete request:

    kubectl apply -f deleterequest.yaml
  3. Verify the deletion. Both the target resource and the DeleteRequest CR are removed automatically. For a backup job:

    kubectl get applicationbackup <your-application-backup-name> -n csdr

    Expected output:

    Error from server (NotFound): applicationbackups.csdr.alibabacloud.com "your-application-backup-name" not found
    kubectl get deleterequest <your-application-backup-name>-dbr -n csdr

    Expected output:

    Error from server (NotFound): deleterequests.csdr.alibabacloud.com "your-application-backup-name-dbr" not found

    For a restore task:

    kubectl get applicationrestore <your-application-restore-name> -n csdr

    Expected output:

    Error from server (NotFound): applicationrestores.csdr.alibabacloud.com "your-application-restore-name" not found
    kubectl get deleterequest <your-application-restore-name>-dbr -n csdr

    Expected output:

    Error from server (NotFound): deleterequests.csdr.alibabacloud.com "your-application-restore-name-dbr" not found

Next steps