Use the Terraform CLI to declaratively manage application backup and restoration across ACK clusters. This approach deploys custom resources (CRs) — BackupLocation, ApplicationBackup, BackupSchedule, ApplicationRestore, and DeleteRequest — without manual console or kubectl operations.
Prerequisites
Before you begin, ensure that you have:
-
An ACK cluster running Kubernetes 1.18 or later. See Create an ACK managed cluster.
-
migrate-controller installed with the required permissions. See Install migrate-controller and grant permissions. Alternatively, use Terraform to install the component. See Use Terraform to manage add-ons.
-
An Object Storage Service (OSS) bucket whose name starts with
cnfs-oss-. See Use Terraform to manage OSS and alicloud_oss_bucket. -
(If backing up volumes) Elastic Compute Service (ECS) snapshots and Cloud Backup activated. See Activate OSS, Activate ECS snapshots, and Activate Cloud Backup.
Usage notes
-
Do not run
kubectl deleteto remove backup or restoration tasks. Related cloud resources may not be fully deleted. To delete resources correctly, see Step 5: Delete resources. -
Keep migrate-controller updated to the latest version. See Manage components.
-
Do not remove any parameters from the sample code in the following steps. Missing parameters can prevent backups from being restored.
Step 1: Connect to a cluster
Use the Terraform Kubernetes provider to connect to your cluster via a KubeConfig file. For details about the provider, see Kubernetes Provider.
-
Create a Terraform working directory.
-
In the directory, create a configuration file named
csdr.tfand add the following content:provider "kubernetes" { config_path = "~/.kube/config" } -
Initialize the Terraform runtime environment:
terraform init
Step 2: Create a backup vault
A backup vault (BackupLocation CR) defines where backups are stored in OSS and how your cluster accesses the bucket.
-
Add the following resource block to
csdr.tf, replacing the placeholder values:Parameter Required Description nameYes Name of the backup vault. Must comply with Kubernetes naming conventions. networkYes Network mode for accessing the OSS bucket. internal: all clusters must be in the same region as the bucket.public: no region restrictions.regionYes Region where the OSS bucket resides. bucketYes OSS bucket name. Must start with cnfs-oss-.prefixNo Subdirectory in the OSS bucket. If specified, backups are stored in that subdirectory. providerYes Cloud provider. Set to alibabacloud.resource "kubernetes_manifest" "backuplocation-demo" { manifest = { apiVersion = "csdr.alibabacloud.com/v1beta1" kind = "BackupLocation" metadata = { name = "<your-backup-vault-name>" # Must comply with Kubernetes naming conventions namespace = "csdr" } spec = { backupSyncPeriod = "0s" config = { network = "internal" # "internal": bucket and clusters must be in the same region # "public": no region restrictions region = "cn-beijing" # Region where the OSS bucket resides } objectStorage = { bucket = "<cnfs-oss-your-bucket-name>" # Must start with cnfs-oss- prefix = "<sub-directory>" # Optional: stores backups in this subdirectory } provider = "alibabacloud" } } # Wait until the backup vault is ready before proceeding wait { fields = { "status.phase" = "Available" } } timeouts { create = "10m" } } -
Preview the changes:
terraform plan -
Apply the configuration to create the backup vault:
terraform apply
Step 3: Create a backup task
ACK supports two backup modes: instant backup (runs once on demand) and scheduled backup (runs on a cron schedule).
Create an instant backup task
-
Add the following resource block to
csdr.tf, replacing the placeholder values:If your ACK cluster uses Velero, join DingTalk group 35532895 for technical support.
Parameter Required Description csdr.alibabacloud.com/backuplocationsYes The backup vault annotation. Must match the BackupLocation configuration exactly. nameYes Name of the instant backup task. includedNamespacesYes Namespaces to back up. includedResourcesNo Resource types to include. Specify only one of includedResourcesorexcludedResources. If both are empty, all resource types are backed up.excludedResourcesNo Resource types to exclude. See the note for includedResources.matchLabelsNo Labels of the resources to back up. includeClusterResourcesNo Controls cluster-scoped resources. true: all cluster-scoped resources.falseor unset: only those referenced by the specified namespaces. Default in the ACK console:false.defaultPvBackupNo true: back up applications and volumes.false: back up applications only.storageLocationYes Name of the backup vault (BackupLocation). ttlYes Backup validity period. Format: 720h0m0s. Valid range:24h0m0sto1572864h0m0s. Expired backups cannot be restored.resource "kubernetes_manifest" "applicationbackup-demo" { manifest = { apiVersion = "csdr.alibabacloud.com/v1beta1" kind = "ApplicationBackup" metadata = { name = "<your-backup-task-name>" namespace = "csdr" annotations = { # Must match the backup vault configuration exactly "csdr.alibabacloud.com/backuplocations" = "{\"name\":\"<your-backup-vault-name>\",\"region\":\"cn-beijing\",\"bucket\":\"<cnfs-oss-your-bucket-name>\",\"prefix\":\"<sub-directory>\",\"provider\":\"alibabacloud\"}" } } spec = { includedNamespaces = ["default", "default1"] # Namespaces to back up # Specify only one of includedResources or excludedResources. # If both are empty, all resource types are backed up. includedResources = ["statefulset"] excludedResources = ["excludedResources"] labelSelector = { matchLabels = { "app" = "mysql-sts" # Optional: back up only resources with these labels } } pvBackup = { defaultPvBackup = "false" # "true": back up apps and volumes; "false": apps only } storageLocation = "<your-backup-vault-name>" # Must match the BackupLocation name ttl = "720h0m0s" # Backup validity period. Format: 720h0m0s # Valid range: 24h0m0s to 1572864h0m0s # Expired backups cannot be restored # includeClusterResources controls whether cluster-scoped resources are included: # "true" — include all cluster-scoped resources (StorageClasses, CRDs, webhooks, etc.) # "false" — include only cluster-scoped resources referenced by the specified namespaces # (for example, if a pod uses a service account with a cluster role, # that cluster role is automatically included) # Unset — same behavior as "false" when namespace filtering is used includeClusterResources = "false" } } # Uncomment to wait for backup completion (recommended for scripted workflows). # Backup duration depends on the number of applications and volume data size. #wait { # fields = { # "status.phase" = "Completed" # } #} #timeouts { # create = "60m" #} } -
Preview the changes:
terraform plan -
Create the instant backup task:
terraform apply
Create a scheduled backup task
-
Add the following resource block to
csdr.tf, replacing the placeholder values:Parameter Required Description csdr.alibabacloud.com/backuplocationsYes The backup vault annotation. Must match the BackupLocation configuration exactly. nameYes Name of the scheduled backup task. scheduleYes Backup frequency as a cron expression. Format: minute hour day-of-month month day-of-week. Example:"1 4 * * *"runs at 04:01 every day.includedNamespacesYes Namespaces to back up. includedResourcesNo Resource types to include. Specify only one of includedResourcesorexcludedResources. If both are empty, all resource types are backed up.excludedResourcesNo Resource types to exclude. See the note for includedResources.matchLabelsNo Labels of the resources to back up. includeClusterResourcesNo Controls cluster-scoped resources. true: all cluster-scoped resources.falseor unset: only those referenced by the specified namespaces.defaultPvBackupYes true: back up applications and volumes.false: back up applications only.storageLocationYes Name of the backup vault (BackupLocation). ttlYes Backup validity period. Format: 720h0m0s. Valid range:24h0m0sto1572864h0m0s. -
Preview the changes:
terraform plan -
Create the scheduled backup task:
terraform apply
Manage scheduled backup tasks
Find backups created by a schedule
Use a label selector to list all backups generated by a specific scheduled task:
data "kubernetes_resources" "list-applicationbackup" {
api_version = "csdr.alibabacloud.com/v1beta1"
kind = "ApplicationBackup"
namespace = "csdr"
label_selector = "csdr/schedule-name=<your-schedule-name>"
}
output "applicationbackup-name" {
value = data.kubernetes_resources.list-applicationbackup.objects
}
Modify a scheduled backup task
To change backup parameters such as the schedule frequency:
-
Set
spec.pausedto"true"to pause the schedule, then update the desired parameters. Example — pause the schedule and change the backup frequency: -
Preview the changes:
terraform plan -
Apply the updated configuration:
terraform applyA successful update returns:
kubernetes_manifest.backupschedule-demo: Modifying... kubernetes_manifest.backupschedule-demo: Modifications complete after 1s Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Step 4: Create a restoration task
A restoration task (ApplicationRestore CR) restores applications from a backup into the target cluster, optionally remapping namespaces and converting StorageClasses.
-
Add the following resource block to
csdr.tf, replacing the placeholder values:Parameter Required Description csdr.alibabacloud.com/backuplocationsYes The backup vault annotation. Must match the BackupLocation configuration. nameYes Name of the restoration task. appRestoreOnlyNo true: restore only applications (not persistent volume claims (PVCs), persistent volumes (PVs), or volume data); manually create PVCs and PVs before restoring.false: restore applications and volume data. Default:false.preserveNodePortsNo true: retain the original NodePort values.false: reassign NodePorts to random ports. If the backup cluster and restore cluster use the same NodePort, set this parameter tofalse.includedNamespacesYes Namespaces to restore. If empty, all backed-up namespaces are restored. includedResourcesNo Resource types to include. Specify only one of includedResourcesorexcludedResources.excludedResourcesNo Resource types to exclude. backupNameYes Name of the backup to restore from. For scheduled backups, specify a point-in-time backup name, such as <your-schedule-name>-20221205225845.namespaceMappingNo Maps <backup-namespace>to<target-namespace>. If the target namespace does not exist, it is created automatically.convertedargNo StorageClass conversion list for FileSystem-type volumes (OSS, NAS, CPFS, local). Each entry specifies convertToStorageClassType(target StorageClass; must be disk or NAS and must exist in the cluster),namespace, andpersistentVolumeClaim. Runkubectl -ncsdr describe <backup-name>to identify eligible PVCs.ImportantReadWriteMany volumes cannot be converted to disk. For ReadOnlyMany volumes, ensure replicas are not simultaneously mounted on multiple nodes.
resource "kubernetes_manifest" "applicationrestore-demo" { manifest = { apiVersion = "csdr.alibabacloud.com/v1beta1" kind = "ApplicationRestore" metadata = { name = "<your-restoration-task-name>" namespace = "csdr" annotations = { "csdr.alibabacloud.com/backuplocations" = "{\"name\":\"<your-backup-vault-name>\",\"region\":\"cn-beijing\",\"bucket\":\"<cnfs-oss-your-bucket-name>\",\"prefix\":\"<sub-directory>\",\"provider\":\"alibabacloud\"}" } } spec = { # "false": restore applications and volume data (default) # "true": restore applications only; manually create PVCs and PVs beforehand appRestoreOnly = "false" # "true": retain the original NodePort values from the backup # "false": reassign NodePorts to random ports (use when backup and target clusters share the same NodePort) preserveNodePorts = "true" includedNamespaces = ["default", "default1"] includedResources = ["statefulset"] excludedResources = ["excludedResources"] # StorageClass conversion for FileSystem-type volumes (OSS, NAS, CPFS, local volumes). # Run `kubectl -ncsdr describe <backup-name>` and check # status.resourceList.dataResource.pvcBackupInfo to find PVCs eligible for conversion. # Important: ReadWriteMany volumes cannot be converted to disk. # For ReadOnlyMany volumes converted to disk, ensure replicas are not mounted on multiple nodes simultaneously. convertedarg = [ { convertToStorageClassType = "alicloud-disk-topology-alltype" # Target StorageClass (must exist in the cluster; disk or NAS only) namespace = "default" persistentVolumeClaim = "pvc-nas" }, { convertToStorageClassType = "alicloud-disk-topology-alltype" namespace = "default1" persistentVolumeClaim = "pvc-oss" } ] # The backup to restore from. # For scheduled backups, specify a point-in-time backup name, for example: # "<your-schedule-name>-20221205225845" backupName = "<your-backup-task-name>" # Maps a namespace in the backup to a different namespace in the target cluster. # If the target namespace does not exist, it is created automatically. namespaceMapping = { "<backup-namespace>" = "<target-namespace>" } } } # Uncomment to wait for restoration completion (recommended for scripted workflows). # Restoration duration depends on the number of applications and volume data size. #wait { # fields = { # "status.phase" = "Completed" # } #} #timeouts { # create = "60m" #} } -
Preview the changes:
terraform plan -
Create the restoration task:
terraform apply
Step 5: Delete resources
The backup vault (BackupLocation) cannot be deleted because other clusters may depend on it.
Delete a scheduled backup task
Run terraform destroy to remove the BackupSchedule resource and stop the schedule.
Delete a backup task or restoration task
Use a DeleteRequest CR to safely remove backup or restoration tasks and their associated cloud resources.
Deleting a backup task does not affect the backups already created. Deleting a restoration task does not affect the data already restored.
-
Add the following resource block to
csdr.tf:Parameter Required Description nameYes Name of the deletion request. Format: <ApplicationBackup-name>-dbrto delete a backup task, or<ApplicationRestore-name>-dbrto delete a restoration task.deleteObjectNameYes Name of the resource to delete. deleteObjectTypeYes "Backup": deletes the ApplicationBackup CR and related resources."Restore": deletes the ApplicationRestore CR and related resources.resource "kubernetes_manifest" "deleterequest-demo" { manifest = { apiVersion = "csdr.alibabacloud.com/v1beta1" kind = "DeleteRequest" metadata = { name = "<object-name>-dbr" # Format: <ApplicationBackup-or-ApplicationRestore-name>-dbr namespace = "csdr" } spec = { deleteObjectName = "<object-name>" # Name of the backup or restoration task to delete deleteObjectType = "Backup" # "Backup": deletes ApplicationBackup and related resources # "Restore": deletes ApplicationRestore and related resources } } } -
Preview the changes:
terraform plan -
Apply the deletion:
terraform applyAfter the system deletes the target resource, it also deletes the DeleteRequest CR automatically.