安排备份


本教程介绍如何使用 Cloud Scheduler 和 Cloud Functions 为 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. 启用 Artifact Registry, Cloud Build, Filestore, Cloud Functions, Cloud Logging, Pub/Sub, Cloud Run, and Cloud Scheduler API。

    启用 API

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

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

    转到“项目选择器”

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

  9. 启用 Artifact Registry, Cloud Build, Filestore, Cloud Functions, Cloud Logging, Pub/Sub, Cloud Run, and Cloud Scheduler API。

    启用 API

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

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

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

  1. 如果您尚未在 Google Cloud 控制台中执行此操作,请点击激活 Cloud Shell

  2. 创建 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"
    
  3. 创建一个 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_LOCATION=fs-location
    export INSTANCE_NAME=instance-id
    export SHARE_NAME=datafile-share-name
    

    替换以下内容:

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

    export FS_BACKUP_LOCATION=region
    

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

创建用于创建备份的函数

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

    转到 Cloud Functions 页面

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

    • 基础配置
      • 环境:在此示例中,请选择 2nd gen,这是默认值。
      • 函数名称:在此示例中,我们将函数命名为 fsbackup
      • 区域:在此示例中,请选择 us-central1
    • 触发器
      • 触发器类型:从菜单中选择 HTTPS
      • 鉴别:选择 Require authentication
    • 运行时、构建、连接和安全设置
      • 运行时 > 运行时服务帐号 > 服务帐号:从菜单中选择 Service Account for FS Backups-GCF (backupagent@$PROJECT_ID.iam.gserviceaccount.com)。
      • 连接 > 入站流量设置:选择 Allow all traffic
  3. 点击 Next,然后继续配置,如下所示:

    • 运行时:从菜单中选择 Python 3.8Cloud Functions 完全支持的更高版本。
    • 源代码Inline editor
    • 入口点:输入 create_backup
    • 将以下依赖项添加到您的 requirements.txt 文件中:

      google-auth==2.29.0
      requests==2.31.0
      

      根据您的用例,您可能需要指定其他依赖项及其相应的版本号。如需了解详情,请参阅预安装软件包

    • 使用内嵌编辑器将以下 Python 代码示例复制到 main.py 文件中:

      创建备份

      1. 此代码示例会创建一个名为 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/v1/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'])
          return "Backup creation has begun!"
      

      替换以下内容:

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

        Cloud Shell 中会打开一个新标签页会话。在该文件中,如果成功,将返回以下消息:

        Function is ready to test.
        
      2. 点击部署并等待部署完成。

      3. 切换回之前的 Cloud Shell 标签页。

      删除备份

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

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

      • 函数名称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)
      
      retention_seconds = BACKUP_RETENTION_TIME_HRS * 60 * 60
      
      def delete_backup(request):
          now = time.time()
          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.")
              return "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'])
          return "Backup deletion has begun!"
      

      替换以下内容:

      • 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 的客户端服务帐号授予要使用的函数的 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

    删除备份

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

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

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

  1. 在本教程中,如果您想安排每个工作日晚上 10 点备份,可以使用 scheduler jobs create http 命令:

    gcloud 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 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,然后点击关闭以删除项目。

后续步骤