安排备份


本教程介绍如何使用 Cloud Scheduler 和 Cloud Functions 安排基本 HDD 和基本 SSD 层级 Filestore 实例的备份。

目标

  • 为 Cloud Scheduler 创建一个客户端服务帐号,该帐号具有调用 Cloud Functions 函数所需的凭据。
  • 创建一个客户端服务账号,供具有调用 Filestore 端点的凭据的 Cloud Functions 函数使用。
  • 创建一个用以创建(或删除)文件共享备份的 Cloud Functions 函数。
  • 创建一项 Cloud Scheduler 作业,用于定期运行创建备份(或删除备份)函数。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 Cloud Scheduler, Cloud Functions, and Filestore API。

    启用 API

  5. 安装 Google Cloud CLI。
  6. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  7. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  8. 确保您的 Google Cloud 项目已启用结算功能

  9. 启用 Cloud Scheduler, Cloud Functions, and Filestore API。

    启用 API

  10. 安装 Google Cloud CLI。
  11. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  12. 如果您的项目中没有 Filestore 实例,则必须先创建 一个 Filestore 实例。

为 Cloud Scheduler 和 Cloud Functions 函数创建客户端服务账号

  1. 创建 Cloud Scheduler 用于调用 Cloud Functions 函数的客户端服务账号运行身份。在此示例中,请使用 iam service-accounts create 命令将帐号命名为 schedulerunner,并将显示名称设置为“Service Account for FS Backups-Scheduler”:

    gcloud iam service-accounts create schedulerunner \
        --display-name="Service Account for FS Backups-Scheduler"
    
  2. 创建一个 Cloud Functions 运行身份用以调用 Filestore 端点的客户端服务账号。在此示例中,我们将账号命名为 backupagent,并将显示名设置为“FS Backups-GCF 的服务账号”:

    gcloud iam service-accounts create backupagent \
        --display-name="Service Account for FS Backups-GCF"
    

    您可以运行 iam service-accounts list 命令来检查服务帐号是否已创建:

    gcloud iam service-accounts list
    

    该命令会返回如下内容:

    NAME                                         EMAIL                                                   DISABLED
    Service Account for FS Backups-GCF           backupagent@$PROJECT_ID.iam.gserviceaccount.com         False
    Service Account for FS Backups-Scheduler     schedulerunner@$PROJECT_ID.iam.gserviceaccount.com      False
    

设置环境变量

在本地环境中设置以下环境变量:

  • Google Cloud 项目 ID 和项目:

    export PROJECT_ID=`gcloud config get-value core/project`
    export PROJECT_NUMBER=`gcloud projects describe $PROJECT_ID --format='value(projectNumber)'`
    
  • Cloud Scheduler 服务代理和 Cloud Scheduler 和 Cloud Functions 的客户端服务帐号

    export SCHEDULER_SA=service-$PROJECT_NUMBER@gcp-sa-cloudscheduler.iam.gserviceaccount.com
    export SCHEDULER_CLIENT_SA=schedulerunner@$PROJECT_ID.iam.gserviceaccount.com
    export GCF_CLIENT_SA=backupagent@$PROJECT_ID.iam.gserviceaccount.com
    
  • 您的 Filestore 实例:

    export FS_ZONE=zone
    export INSTANCE_NAME=instance-id
    export SHARE_NAME=datafile-share-name
    

    替换以下内容:

    • zone 替换为 Filestore 实例所在的可用区。
    • instance-id 替换为 Filestore 实例的 ID。
    • file-share-name 替换为您为从实例提供的 NFS 文件共享所指定的名称。
  • 为 Filestore 备份设置环境变量:

    export FS_BACKUP_LOCATION=region
    

    region 替换为要存储备份的区域。

创建用于创建备份的函数

  1. 在 Google Cloud 控制台中,转到 Cloud Functions 页面。

    转到 Cloud Functions 页面

  2. 点击创建函数并按如下所示配置函数:

    • 基础配置
      • 函数名称:在此示例中,我们将函数命名为 fsbackup
      • 区域:在本示例中,我们使用 us-central1
    • 触发器
      • 触发器类型HTTP
      • 身份验证Require authentication
    • 运行时、构建和连接设置
      • 运行时服务账号Service Account for FS Backups-GCF (backupagent@$PROJECT_ID.iam.gserviceaccount.com)。
      • 入站流量设置Allow all traffic
    • 源代码Inline editor
    • 运行时Python 3.7
    • 入口点create_backup
    • requirements.txt 中,添加以下依赖项

      google-auth==1.19.2
      requests==2.24.0
      
    • 将以下 Python 代码示例复制到 main.py 内嵌编辑器中:

      创建备份

      此代码示例会创建附加有创建时间的 mybackup- 备份。

      PROJECT_ID = 'project-id'
      SOURCE_INSTANCE_ZONE = 'filestore-zone'
      SOURCE_INSTANCE_NAME = 'filestore-name'
      SOURCE_FILE_SHARE_NAME = 'file-share-name'
      BACKUP_REGION = 'backup-region'
      
      import google.auth
      import google.auth.transport.requests
      from google.auth.transport.requests import AuthorizedSession
      import time
      import requests
      import json
      
      credentials, project = google.auth.default()
      request = google.auth.transport.requests.Request()
      credentials.refresh(request)
      authed_session = AuthorizedSession(credentials)
      
      def get_backup_id():
          return "mybackup-" + time.strftime("%Y%m%d-%H%M%S")
      
      def create_backup(request):
          trigger_run_url = "https://file.googleapis.com/v1beta1/projects/{}/locations/{}/backups?backupId={}".format(PROJECT_ID, BACKUP_REGION, get_backup_id())
          headers = {
            'Content-Type': 'application/json'
          }
          post_data = {
            "description": "my new backup",
            "source_instance": "projects/{}/locations/{}/instances/{}".format(PROJECT_ID, SOURCE_INSTANCE_ZONE, SOURCE_INSTANCE_NAME),
            "source_file_share": "{}".format(SOURCE_FILE_SHARE_NAME)
          }
          print("Making a request to " + trigger_run_url)
          r = authed_session.post(url=trigger_run_url, headers=headers, data=json.dumps(post_data))
          data = r.json()
          print(data)
          if r.status_code == requests.codes.ok:
            print(str(r.status_code) + ": The backup is uploading in the background.")
          else:
            raise RuntimeError(data['error'])
      

      替换以下内容:

      • project-id 替换为来源 Filestore 实例的 Google Cloud 项目 ID。
      • filestore-zone 替换为来源 Filestore 实例的可用区。
      • filestore-name 替换为来源 Filestore 实例的名称。
      • file-share-name 替换为文件共享的名称。
      • backup-region 替换为存储备份的地区。

      删除备份

      此代码示例会删除早于预定义时段的备份。

      按照与创建备份函数相同的方式配置此函数,但以下情况除外:

      • 函数名称deletefsbackups
      • 入口点delete_backup
      PROJECT_ID = 'project-id'
      BACKUP_REGION = 'region'
      BACKUP_RETENTION_TIME_HRS = hours
      
      import google.auth
      import google.auth.transport.requests
      from google.auth.transport.requests import AuthorizedSession
      import time
      import requests
      import json
      
      credentials, project = google.auth.default()
      request = google.auth.transport.requests.Request()
      credentials.refresh(request)
      authed_session = AuthorizedSession(credentials)
      
      now = time.time()
      retention_seconds = BACKUP_RETENTION_TIME_HRS * 60 * 60
      
      def delete_backup(request):
          list = []
          trigger_run_url = "https://file.googleapis.com/v1beta1/projects/{}/locations/{}/backups".format(PROJECT_ID, BACKUP_REGION)
          r = authed_session.get(trigger_run_url)
          data = r.json()
          if not data:
              print("No backups to delete.")
          else:
              list.extend(data['backups'])
              while 'nextPageToken' in data.keys():
                  nextPageToken = data['nextPageToken']
                  trigger_run_url_next = "https://file.googleapis.com/v1beta1/projects/{}/locations/{}/backups?pageToken={}".format(PROJECT_ID, BACKUP_REGION, nextPageToken)
                  r = authed_session.get(trigger_run_url_next)
                  data = r.json()
                  list.extend(data['backups'])
          for i in list:
              backup_time = i['createTime']
              backup_time = backup_time[:-4]
              backup_time = float(time.mktime(time.strptime(backup_time, "%Y-%m-%dT%H:%M:%S.%f")))
              if now - backup_time > retention_seconds:
                  print("Deleting " + i['name'] + " in the background.")
                  r = authed_session.delete("https://file.googleapis.com/v1beta1/{}".format(i['name']))
                  data = r.json()
                  print(data)
                  if r.status_code == requests.codes.ok:
                    print(str(r.status_code) + ": Deleting " + i['name'] + " in the background.")
                  else:
                    raise RuntimeError(data['error'])
      

      替换以下内容:

      • project-id 替换为备份的 Google Cloud 项目 ID。
      • region 替换为备份所在的地区。
      • hours 替换为保留备份的小时数。例如,如果您要将备份保留 10 天,请输入 240

将 IAM 角色分配给客户端服务账号

  1. 将 Cloud Scheduler 服务代理添加到 Cloud Scheduler 客户端服务帐号的 IAM 政策(角色为 roles/cloudscheduler.serviceAgent)。这样,服务代理就可以模拟客户端服务帐号,以便调用创建备份的函数。运行 iam service-accounts add-iam-policy-binding 命令:

    gcloud iam service-accounts add-iam-policy-binding $SCHEDULER_CLIENT_SA \
        --member=serviceAccount:$SCHEDULER_SA \
        --role=roles/cloudscheduler.serviceAgent
    
  2. 为 Cloud Functions 的客户端服务帐号提供 roles/file.editor 角色,以便它可以调用 Filestore 端点。运行 projects add-iam-policy-binding 命令:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member=serviceAccount:$GCF_CLIENT_SA \
        --role=roles/file.editor
    
  3. 向 Cloud Scheduler 的客户端服务帐号授予 fsbackup 函数的 roles/cloudfunctions.invoker 角色。运行以下 functions add-iam-policy-binding 命令:

    gcloud functions add-iam-policy-binding fsbackup \
        --member serviceAccount:$SCHEDULER_CLIENT_SA \
        --role roles/cloudfunctions.invoker
    

    现在,只有 Cloud Scheduler 的客户端服务帐号可以调用 fsbackup

创建 Cloud Scheduler 作业,以便按指定的时间表触发 fsbackup 函数

  1. 在本本教程的示例中,如果您希望安排每个工作日晚上 10 点进行备份,则可以使用 scheduler jobs create http 命令:

    gcloud beta scheduler jobs create http fsbackupschedule \
        --schedule "0 22 * * 1-5" \
        --http-method=GET \
        --uri=https://us-central1-$PROJECT_ID.cloudfunctions.net/fsbackup \
        --oidc-service-account-email=$SCHEDULER_CLIENT_SA    \
        --oidc-token-audience=https://us-central1-$PROJECT_ID.cloudfunctions.net/fsbackup
    

    --schedule 标志用于使用 unix-cron 格式指定作业运行的频率。如需了解详情,请参阅配置 Cron 作业时间表

  2. 启动上一步中创建的 Cloud Scheduler 作业。在我们的示例中,使用 scheduler jobs runs 命令:

    gcloud scheduler jobs run fsbackupschedule
    

    fsbackupschedule 作业会在您执行该命令后立即调用“fsbackups”函数,并在每个工作日晚上 10 点再次调用该函数,直到作业暂停为止。

  3. 检查 fsbackups 函数的日志以查看该函数执行是否正确并返回 status 200

  4. 检查是否使用 backups list 命令创建了备份:

    gcloud beta filestore backups list
    

    该命令会返回类似如下的内容:

    NAME                      LOCATION     SRC_INSTANCE                        SRC_FILE_SHARE  STATE
    mybackup-20201123-184500  us-central1  us-central1-c/instances/nfs-server  vol1            READY
    

备份配额过低提醒

如果您在安排备份时实施备份配额,可能会用尽备份配额,我们建议您设置备份配额过低提醒。这样,您会在备份配额即将用尽时收到通知。

清理

完成本教程后,您可以清理您创建的资源,让它们停止使用配额,以免产生费用。以下部分介绍如何删除或关闭这些资源。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。

如需删除项目,请执行以下操作:

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤