Manage backup vaults, schedules, and cross-cluster restoration in ACK via Terraform custom resources.
Prerequisites
Before you begin, ensure that you have:
-
An ACK managed cluster running Kubernetes 1.18 or later.
-
migrate-controller installed with required permissions. Or install it with Terraform.
-
An OSS bucket whose name starts with
cnfs-oss-. Use Terraform to manage OSS and alicloud_oss_bucket. -
(If backing up volumes) Elastic Compute Service (ECS) snapshots and Cloud Backup activated. Activate OSS, Activate ECS snapshots, and Activate Cloud Backup.
Usage notes
-
Do not run
kubectl deleteto remove backup or restoration tasks — cloud resources may not be fully cleaned up. See Step 5: Delete resources. -
Keep migrate-controller updated. See Manage components.
-
Do not remove parameters from the sample code below. Missing parameters may prevent backup restoration.
Step 1: Connect to a cluster
Use the Terraform Kubernetes provider to connect to your cluster via a KubeConfig file.
-
Create a Terraform working directory.
-
In the directory, create a file named
csdr.tf:provider "kubernetes" { config_path = "~/.kube/config" } -
Initialize Terraform:
terraform init
Step 2: Create a backup vault
A backup vault (BackupLocation CR) specifies the OSS bucket and access method for backups.
-
Add the following to
csdr.tf, replacing placeholders: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 for backup storage. 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 -
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 to
csdr.tf, replacing placeholders: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 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 to
csdr.tf, replacing placeholders: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
List backups from a specific schedule:
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 parameters such as schedule frequency:
-
Set
spec.pausedto"true"to pause the schedule, then update parameters. Example: -
Preview the changes:
terraform plan -
Apply the updated configuration:
terraform applyExpected output:
kubernetes_manifest.backupschedule-demo: Modifying... kubernetes_manifest.backupschedule-demo: Modifications complete after 1s Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Data protection (PvBackup)
Set backupType to PvBackup to back up volume data only. Specify pvcList to back up specific PVCs, or storageClassList to back up volumes of specific StorageClasses. If you set both, storageClassList is ignored. If you set neither, all volumes in the included namespaces are backed up.
Create an instant PvBackup task
-
Add the following to
csdr.tf, adjusting values as needed:resource "kubernetes_manifest" "applicationbackup-demo" { manifest = { apiVersion = "csdr.alibabacloud.com/v1beta1" kind = "ApplicationBackup" metadata = { name = "<yourApplicationBackupName>" namespace = "csdr" annotations = { "csdr.alibabacloud.com/backuplocations" = "{\"name\":\"<yourBackuplocationName>\",\"region\":\"cn-beijing\",\"bucket\":\"<cnfs-oss-yourBucketName>\",\"prefix\":\"<subDir>\",\"provider\":\"alibabacloud\"}" } } spec = { backupType = "PvBackup" includedNamespaces = ["default","default1"] pvBackup = { pvcList = [ { namespace = "default", name = "pvc-nas" }, { namespace = "default1", name = "pvc-oss" } ] storageClassList = ["disk-essd","disk-ssd"] } storageLocation = "<yourBackuplocationName>" ttl = "720h0m0s" } } } -
Generate the resource plan:
terraform plan -
Create the instant backup task:
terraform apply
Create a PvBackup schedule
-
Add the following to
csdr.tf, adjusting values as needed:resource "kubernetes_manifest" "backupschedule-demo" { manifest = { apiVersion = "csdr.alibabacloud.com/v1beta1" kind = "BackupSchedule" metadata = { name = "<yourBackupScheduleName>" namespace = "csdr" annotations = { "csdr.alibabacloud.com/backuplocations" = "{\"name\":\"<yourBackuplocationName>\",\"region\":\"cn-beijing\",\"bucket\":\"<cnfs-oss-yourBucketName>\",\"prefix\":\"<subDir>\",\"provider\":\"alibabacloud\"}" } } spec = { schedule = "1 4 * * *" template = { includedNamespaces = ["default","default1"] pvBackup = { pvcList = [ { namespace = "default", name = "pvc-nas" }, { namespace = "default1", name = "pvc-oss" } ] storageClassList = ["disk-essd","disk-ssd"] } storageLocation = "<yourBackuplocationName>" ttl = "720h0m0s" } } } } -
Generate the resource plan and apply:
terraform plan terraform apply
Step 4: Create a restoration task
A restoration task (ApplicationRestore CR) restores applications from a backup, with optional namespace remapping and StorageClass conversion.
-
Add the following to
csdr.tf, replacing placeholders: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. Set tofalsewhen both clusters share the same NodePort.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>. Nonexistent target namespaces are 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 and stop the schedule.
Delete a backup task or restoration task
Use a DeleteRequest CR to safely remove backup or restoration tasks and associated cloud resources.
Deleting a backup task does not affect existing backups. Deleting a restoration task does not affect restored data.
-
Add the following 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 deleting the target resource, the system also deletes the DeleteRequest CR.