Set up a backup repository for dual-zone buckets

This page describes how to configure backup repositories for Google Distributed Cloud (GDC) air-gapped dual-zone buckets. This lets you maintain high availability for critical data and applications while minimizing downtime in the event of a zone failure. This page covers steps to create dual-zone buckets, copy bucket secrets, and set up backup repositories in multiple zones.

This page is for IT administrators within the platform administrator group who are responsible for managing resources within their organization, and application developers within the application operator group who are responsible for developing and maintaining applications in a GDC universe.

For more information, see Audiences for GDC air-gapped documentation.

Before you begin

Before using backup and restore services for GDC dual-zone buckets, you must have the following:

  • An environment provisioned with a minimum of two zones.
  • Access to the global org client or global root client.
    • If your workload is provisioned inside a project, use the global org client.
    • If your workload is provisioned at the root, use the global root client.
  • The global-project-bucket-admin role, which is required to create dual-zone buckets.

Create a dual-zone bucket

To create a dual-zone bucket, you'll first need to create a project resource for the bucket to reside in. To create a project, follow these steps:

  1. Create a project resource in a global org cluster:

    apiVersion: resourcemanager.global.gdc.goog/v1
    kind: Project
    metadata:
      namespace: platform
      name: PROJECT_NAME
      labels:
        object.gdc.goog/tenant-category: user
    

    Replace the following:

    • PROJECT_NAME: the name of the project.
  2. Create a dual-zone bucket:

    apiVersion: object.global.gdc.goog/v1
    kind: Bucket
    metadata:
      name: BUCKET_NAME
      namespace: PROJECT_NAME
    spec:
      location: LOCATION_TYPE
      description: DESCRIPTION
      storageClass: Standard
    

    Replace the following:

    • BUCKET_NAME: the name of the bucket.
    • LOCATION_TYPE: the type of replication. For synchronous replication, the value is syncz1z2. For asynchronous replication, the value is asyncz1z2.
    • DESCRIPTION: a text description of the bucket.
  3. Create a service account and an Identity and Access Management (IAM) role binding to grant the required permissions for the bucket:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: BUCKET_NAME-sa
      namespace: PROJECT_NAME
    ---
    apiVersion: iam.global.gdc.goog/v1
    kind: IAMRoleBinding
    metadata:
      namespace: PROJECT_NAME
      name: BUCKET_NAME-admin-binding
    spec:
      roleRef:
        apiGroup: iam.global.gdc.goog
        kind: IAMRole
        name: project-bucket-object-admin
      subjects:
        - kind: ServiceAccount
          name: BUCKET_NAME-sa
          namespace: PROJECT_NAME
    
  4. Wait for the bucket status to show ready.

Copy the bucket secret to both zones

After the bucket and the required permissions are configured, a secret is generated in a global org cluster which can be identified by its annotations.

  1. Check that a secret has been generated with the annotation of the bucket:

    export BUCKET_SECRET=$(kubectl get secret -n PROJECT_NAME -o jsonpath="{range .items[*]}{.metadata.name}{':'}{.metadata.annotations['object\.gdc\.goog/subject']}{'\n'}{end}" | grep :BUCKET_NAME | cut -f1 -d :)
    
  2. Retrieve the secret contents:

    kubectl get secret -n PROJECT_NAME BUCKET_SECRET -o yaml > bucket_secret.yaml
    
  3. Create the same secret in the management cluster of the org in zone-1 and zone-2. Make sure to clear resourceVersion, uid, and creationTimeStamp from the YAML file to prevent creation errors:

    # zone-1
    kubectl apply -f bucket_secret.yaml
    
    # zone-2
    kubectl apply -f bucket_secret.yaml
    

Create backup repositories

After the bucket and secrets are configured, create a backup repository in zone-1 and zone-2.

  1. To get bucket details like FQDN and endpoints, use the following command in a global org cluster. Extract fullyQualifiedName and zonalEndpoints from the output:

    kubectl get buckets.object.global.gdc.goog -n PROJECT_NAME BUCKET_NAME -o yaml
    
  2. To create a read-write-backup repository in zone-1 in the management cluster, use the following command. Ensure to use the zonal endpoint of zone-1:

    apiVersion: backup.gdc.goog/v1
    kind: BackupRepository
    metadata:
      annotations:
        backup.gdc.goog/dz-bucket: "true"
        backup.gdc.goog/dz-bucket-info-namespace: PROJECT_NAME
      finalizers:
      - backup.gdc.goog/sentinel-finalizer
      generation: 1
      name: BACKUP_REPOSITORY_NAME
    spec:
      endpoint: ENDPOINT
      force: false
      importPolicy: ReadWrite
      s3Options:
        bucket: BUCKET_FULL_NAME
        forcePathStyle: true
        region: zone2
      secretReference:
        name: BUCKET_SECRET
        namespace: PROJECT_NAME
      type: S3
    

    Replace the following:

    • BACKUP_REPOSITORY_NAME: the name of the backup repository.
    • ENDPOINT: the zonal endpoint of zone-1.
    • BUCKET_FULL_NAME: the name of the fully qualified bucket.
    • BUCKET_SECRET: the secret of the bucket.
  3. Check the backup repository for successful creation:

    kubectl get backuprepositories.backup.gdc.goog BACKUP_REPOSITORY_NAME
    
  4. Annotate the backup repository with dual-zone bucket annotations:

    kubectl -n PROJECT_NAME annotate --overwrite backuprepositories.backup.gdc.goog BACKUP_REPOSITORY_NAME backup.gdc.goog/dz-bucket="true"
    
    kubectl -n PROJECT_NAME annotate --overwrite backuprepositories.backup.gdc.goog BACKUP_REPOSITORY_NAME backup.gdc.goog/dz-bucket-info-namespace=PROJECT_NAME
    
  5. Create a read-only repository in zone-2 in the management cluster. Use the zonal endpoint of zone-2 for this command:

    apiVersion: backup.gdc.goog/v1
    kind: ClusterBackupRepository
    metadata:
      annotations:
        backup.gdc.goog/dz-bucket: "true"
        backup.gdc.goog/dz-bucket-info-namespace: PROJECT_NAME
      finalizers:
      - backup.gdc.goog/sentinel-finalizer
      generation: 1
      name: BACKUP_REPOSITORY_NAME
    spec:
      endpoint: ENDPOINT
      force: false
      importPolicy: ReadOnly
      s3Options:
        bucket: BUCKET_FULL_NAME
        forcePathStyle: true
        region: zone2
      secretReference:
        name: BUCKET_SECRET
        namespace: PROJECT_NAME
      type: S3
    
  6. Check the backup repository for successful creation:

    kubectl get backuprepositories.backup.gdc.goog BACKUP_REPOSITORY_NAME
    
  7. Annotate the underlying backup repository resource with the following annotations:

    kubectl -n PROJECT_NAME annotate --overwrite backuprepositories.backup.gdc.goog BACKUP_REPOSITORY_NAME backup.gdc.goog/dz-bucket="true"
    
    kubectl -n PROJECT_NAME annotate --overwrite backuprepositories.backup.gdc.goog BACKUP_REPOSITORY_NAME backup.gdc.goog/dz-bucket-info-namespace=PROJECT_NAME
    

Back up workloads to the backup repositories

After backup repositories are configured, follow the steps to back up and restore your workloads.

Next steps