排定備份週期

本教學課程說明如何使用 Cloud Scheduler 和 Cloud Run 函式,為 Filestore 執行個體排定備份作業。

為 Cloud Scheduler 和 Cloud Run 函式建立用戶端服務帳戶

  1. 如果尚未啟用,請在 Google Cloud 控制台中點選「啟用 Cloud Shell」

  2. 建立用戶端服務帳戶,Cloud Scheduler 會以該帳戶身分執行,叫用 Cloud Run 函式。在本範例中,請使用 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 Run 函式會以該帳戶身分執行,以便呼叫 Filestore 端點。在本範例中,我們將帳戶命名為 backupagent,並將顯示名稱設為「Service Account for 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 Run 函式的用戶端服務帳戶

    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 SOURCE_INSTANCE_LOCATION=fs-location
    export SOURCE_INSTANCE_NAME=instance-id
    export SHARE_NAME=file-share-name
    

    更改下列內容:

    • fs-location,來源 Filestore 執行個體所在的區域或地區。
    • instance-id,其中包含來源 Filestore 執行個體的執行個體 ID。
    • file-share-name,並指定執行個體提供的 NFS 檔案共用區名稱。
  • 設定 Filestore 備份的環境變數:

    export BACKUP_REGION=backup-region
    

    backup-region 替換為要儲存備份的區域。

建立用於建立備份的函式

  1. 前往 Google Cloud 控制台的 Cloud Run functions 頁面。

    前往 Cloud Run 函式頁面

  2. 按一下「Write a function」(編寫函式),然後依下列方式設定函式:

    • 設定
      • 服務名稱:在本範例中,我們將函式命名為 fsbackup
      • 「區域」:在本範例中,請選取 us-central1
      • 執行階段:從選單中選取 Cloud Run 函式完全支援的任何 Python 3 執行階段。
    • 觸發條件
      • 本範例不需要設定觸發條件。
    • 「驗證」:選取 Require authentication
    • 「Ingress」(輸入流量):選取 All
    • 容器、磁碟區、網路與安全性
      • 前往「安全性」分頁,然後從選單中選取 Service Account for FS Backups-GCF (backupagent@$PROJECT_ID.iam.gserviceaccount.com)。
  3. 按一下「建立」,然後繼續進行下列設定:

    • 函式進入點:輸入 create_backup
    • requirements.txt 檔案中新增下列依附元件:

      functions-framework==3.*
      google-auth==2.29.0
      requests==2.31.0
      

      視您的用途而定,您可能需要指定其他依附元件及其對應的版本號碼。詳情請參閱「預先安裝的套件」。

    • 使用內嵌編輯器,將下列 Python 程式碼範例複製到 main.py 檔案中:

      建立備份

      這個程式碼範例會建立名為 mybackup- 的備份,並附加建立時間。

      PROJECT_ID = 'project-id'
      SOURCE_INSTANCE_LOCATION = 'fs-location'
      SOURCE_INSTANCE_NAME = 'instance-id'
      SOURCE_FILE_SHARE_NAME = 'file-share-name'
      BACKUP_REGION = 'backup-region'
      
      import functions_framework
      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")
      
      @functions_framework.http
      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_LOCATION, 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 執行個體的專案 ID。 Google Cloud
      • fs-location,其中包含來源 Filestore 執行個體的區域。
      • instance-id 替換為來源 Filestore 執行個體名稱。
      • file-share-name 替換為檔案共用名稱。
      • backup-region 替換為儲存備份的區域。
      1. 按一下「測試」

        Cloud Shell 會開啟新的分頁工作階段。如果成功,系統會傳回下列訊息:

        Backup creation has begun!
        
      2. 按一下「儲存並重新部署」,然後等待部署完成。

      3. 切換回先前的 Cloud Shell 分頁。

      刪除備份

      這個程式碼範例會刪除超過預先定義時間範圍的備份。

      您一次只能刪除一個來源執行個體的備份。詳情請參閱「備份」。

      設定這個函式的方式與建立備份時使用的函式相同,但需進行下列修改:

      • 函式名稱deletefsbackup
      • 進入點delete_backup
      PROJECT_ID = 'project-id'
      BACKUP_REGION = 'region'
      BACKUP_RETENTION_TIME_HRS = hours
      
      import functions_framework
      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
      
      @functions_framework.http
      def delete_backup(request):
          now = time.time()
          backup_list = []
          trigger_run_url = "https://file.googleapis.com/v1/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:
              backup_list.extend(data['backups'])
              while "nextPageToken" in data.keys():
                  nextPageToken = data['nextPageToken']
                  trigger_run_url_next = "https://file.googleapis.com/v1/projects/{}/locations/{}/backups?pageToken={}".format(PROJECT_ID, BACKUP_REGION, nextPageToken)
                  r = authed_session.get(trigger_run_url_next)
                  data = r.json()
                  backup_list.extend(data['backups'])
          for i in backup_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")))
              i['backup_timestamp'] = backup_time
          sorted_backup_list = sorted(backup_list, key=lambda d: d['backup_timestamp'])
          oldest_backup = sorted_backup_list[0]
          if now - oldest_backup['backup_timestamp'] > retention_seconds:
              print(oldest_backup['name'] + " is older than the indicated retention time.")
              r = authed_session.delete("https://file.googleapis.com/v1/{}".format(oldest_backup['name']))
              data = r.json()
              print(data)
              if r.status_code == requests.codes.ok:
                  print(str(r.status_code) + ": Deleting " + oldest_backup['name'] + " in the background.")
              else:
                  raise RuntimeError(data['error'])
              return "Backup deletion has begun!"
          return "All backups are within the indicated retention period."
      

      更改下列內容:

      • project-id 替換為備份的專案 ID。 Google Cloud
      • 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. roles/file.editor 角色授予 Cloud Run 函式的用戶端服務帳戶,以便呼叫 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/run.invoker 角色。執行下列 run services add-iam-policy-binding 指令:

    建立備份

    gcloud run services add-iam-policy-binding fsbackup \
        --member serviceAccount:$SCHEDULER_CLIENT_SA \
        --role roles/run.invoker \
        --region=us-central1
    

    現在只有 Cloud Scheduler 的用戶端服務帳戶可以叫用 fsbackup

    刪除備份

    gcloud run services add-iam-policy-binding deletefsbackup \
        --member serviceAccount:$SCHEDULER_CLIENT_SA \
        --role roles/run.invoker
    

    現在只有 Cloud Scheduler 的用戶端服務帳戶可以叫用 deletefsbackup

建立 Cloud Scheduler 工作,在指定時間觸發函式

建立備份

  1. 在本教學課程的範例中,假設您想在每個工作日的晚上 10 點安排備份作業,請使用 scheduler jobs create http 指令:

    gcloud scheduler jobs create http fsbackupschedule \
        --schedule "0 22 * * 1-5" \
        --http-method=GET \
        --uri=https://fsbackup-$PROJECT_NUMBER.us-central1.run.app \
        --oidc-service-account-email=$SCHEDULER_CLIENT_SA \
        --location=us-central1
    

    --schedule 標記用於指定工作執行頻率,格式為 unix-cron。詳情請參閱「設定 Cron 工作時間表」。

    每個執行個體每小時最多可建立六個備份。

  2. 啟動上一個步驟中建立的 Cloud Scheduler 工作。在本範例中,請使用 scheduler jobs runs 指令立即執行:

    gcloud scheduler jobs run fsbackupschedule
    

    執行指令後,fsbackupschedule 工作會立即叫用 fsbackup 函式,然後在工作暫停前,每週一到週五晚上 10 點再次叫用該函式。

  3. 檢查 fsbackup 函式的記錄檔,確認函式是否正常執行並傳回 status 200

    如要在 Google Cloud 控制台中查看記錄,請使用記錄檔探索工具:

    1. 前往 Google Cloud 控制台的「Logs Explorer」頁面:

      前往「Logs Explorer」(記錄檔探索工具)

      如果您是使用搜尋列尋找這個頁面,請選取子標題為「Logging」的結果

      「Query results」(查詢結果) 窗格會顯示最近的記錄檔。

  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. 以本教學課程的範例來說,如果您想在每個工作日的晚上 10 點排定備份刪除作業,請使用 scheduler jobs create http 指令:

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

    --schedule 標記用於指定工作執行頻率,格式為 unix-cron。詳情請參閱「設定 Cron 工作時間表」。

    與相同來源執行個體相關聯的備份 delete 作業一次只能執行一個。詳情請參閱「備份」。

  2. 啟動上一個步驟中建立的 Cloud Scheduler 工作。在我們的範例中,我們會使用 scheduler jobs runs 指令立即執行:

    gcloud scheduler jobs run deletefsbackupschedule
    

    執行指令後,deletefsbackupschedule 工作會立即叫用 deletefsbackup 函式,然後在工作暫停前,每週一到週五晚上 10 點再次叫用該函式。

  3. 檢查 deletefsbackup 函式的記錄檔,確認函式是否正常執行並傳回 status 200

    如要在 Google Cloud 控制台中查看記錄,請使用記錄檔探索工具:

    1. 前往 Google Cloud 控制台的「Logs Explorer」頁面:

      前往「Logs Explorer」(記錄檔探索工具)

      如果您是使用搜尋列尋找這個頁面,請選取子標題為「Logging」的結果

      「Query results」(查詢結果) 窗格會顯示最近的記錄檔。

  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
    

備份配額不足警告

如果排定備份作業可能會導致備份配額用盡,建議您設定備份配額用量偏低警示。 這樣一來,系統會在備份配額不足時通知你。