轉移資料

資料轉移作業可以在下列項目之間進行:

  1. 永久磁碟區要求 (PVC) 和物件儲存空間
  2. 物件儲存空間和物件儲存空間 (位於 GDC 內)

GDC 的物件儲存空間與 S3 相容,在 Kubernetes YAML 中稱為 s3 類型。

資料來源和目的地類型

  1. 物件儲存空間 (稱為「s3」):GDC 上的物件儲存空間
  2. 本機儲存空間 (稱為「local」):附加 PVC 上的儲存空間

從物件儲存空間複製到物件儲存空間

請確認您已完成下列事前準備事項:

  • 具備來源讀取權限的 S3 端點,以及具備目的地寫入權限的 S3 端點。
  • 如果憑證不具備 bucket 建立權限,且目的地 bucket 不存在,移轉作業就會失敗。如果發生這種情況,請確認目的地 bucket 是否存在。
  • 在叢集或命名空間內建立 Job,以及建立或讀取 Secret 的權限。如需權限範例,請參閱下文。

設定資料移轉作業

如要設定資料轉移,請完成下列步驟:

建立轉移命名空間

建立轉移工作執行的命名空間:

apiVersion: v1
kind: Namespace
metadata:
  name: NAMESPACE

設定憑證

準備好要轉移的憑證。請按照最符合您轉移情境的選項操作。

GDC 對 GDC 移轉

如果轉移完全在同一個 GDC 宇宙中進行,則密鑰已存在。請注意,這個方法僅適用於單一宇宙內的轉移,不適用於不同宇宙之間的轉移。

  1. 如要取得 S3 憑證密鑰,請按照操作說明授予值區存取權。

  2. 在遷移工作的目的地命名空間中建立服務帳戶 (SA)。接著,使用跨命名空間的 RoleBindings 新增權限,允許這個帳戶讀取來源和目的地命名空間中的密鑰。

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: transfer-service-account
      namespace: DESTINATION_NAMESPACE
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: SOURCE_NAMESPACE
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-source-secrets-rolebinding
      namespace: SOURCE_NAMESPACE
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: DESTINATION_NAMESPACE
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: DESTINATION_NAMESPACE
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-dest-secrets-rolebinding
      namespace: DESTINATION_NAMESPACE
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: DESTINATION_NAMESPACE
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    ---
    

從 GDC 轉移至非 GDC 方案

如果轉移作業涉及外部系統,您必須明確指定存取憑證。

  1. 在目的地命名空間中建立憑證:

    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: src-secret
      namespace: NAMESPACE
    data:
      access-key-id: NkFDTUg3WDBCVDlQMVpZMU5MWjU= # base 64 encoded version of key
      access-key: VkRkeWJsbFgzb2FZanMvOVpnSi83SU5YUjk3Y0Q2TUdxZ2d4Q3dpdw== # base 64 encoded version of secret key
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: dst-secret
      namespace: NAMESPACE
    data:
      access-key-id: NkFDTUg3WDBCVDlQMVpZMU5MWjU= # base 64 encoded version of key
      access-key: VkRkeWJsbFgzb2FZanMvOVpnSi83SU5YUjk3Y0Q2TUdxZ2d4Q3dpdw== # base 64 encoded version of secret key
    ---
    
  2. 建立移轉作業使用的服務帳戶 (SA),然後使用角色和角色繫結,將讀取及寫入密鑰的權限新增至該帳戶。如果預設命名空間 SA 或自訂 SA 已具備這些權限,則不需要新增權限。

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: transfer-service-account
      namespace: NAMESPACE
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: NAMESPACE
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-secrets-rolebinding
      namespace: NAMESPACE
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: NAMESPACE
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    ---
    

取得 CA 憑證

取得物件儲存系統的 CA 憑證。您可以按照擷取信任組合的指示,從 AO 或 PA 取得相同憑證。

---

apiVersion: v1
kind: Secret
metadata:
  name: src-cert
  namespace: NAMESPACE
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUpHM2psOFZhTU85a1FteGdXUFl3N3d3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF5TVRVd01USXlNakZhRncweQpNekExTVRZd01USXlNakZhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWI== # base 64 encoded version of certificate

---

apiVersion: v1
kind: Secret
metadata:
  name: dst-cert
  namespace: NAMESPACE
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUtoaEJXWWo3VGZlUUZWUWo0U0RpckV3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF6TURZeU16TTROVEJhRncweQpNekEyTURReU16TTROVEJhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWIzRFFF== # base 64 encoded version of certificate. Can be same OR different than source certificate.

---

(選用) 建立 LoggingTarget

建立 LoggingTarget,即可在 Loki 中查看轉移服務記錄。

apiVersion: logging.gdc.goog/v1
kind: LoggingTarget
metadata:
  namespace: NAMESPACE # Same namespace as your transfer job
  name: logtarg1
spec:
  # Choose matching pattern that identifies pods for this job
  # Optional
  # Relationship between different selectors: AND
  selector:

    # Choose pod name prefix(es) to consider for this job
    # Observability platform will scrape all pods
    # where names start with specified prefix(es)
    # Should contain [a-z0-9-] characters only
    # Relationship between different list elements: OR
    matchPodNames:
      - transfer-job # Choose the prefix here that matches your transfer job name
  serviceName: transfer-service

建立轉移工作負載

您可以使用 Job 執行一次性轉移作業,也可以使用 CronJob 排定重複執行轉移作業。

請選擇最符合您用途的方法:

建立一次性工作

這項設定適用於單次手動資料移轉。

---
apiVersion: batch/v1
kind: Job
metadata:
  name: transfer-job
  namespace: NAMESPACE
spec:
  template:
    spec:
      serviceAccountName: transfer-service-account # The service account created in the previous step
      containers:
        - name: storage-transfer-pod
          image: gcr.io/private-cloud-staging/storage-transfer:latest
          imagePullPolicy: Always
          command:
            - /storage-transfer
          args:
            # The S3 endpoints for your source and destination
            - '--src_endpoint=SRC_ENDPOINT'
            - '--dst_endpoint=DST_ENDPOINT'
            # The Fully Qualified Names (FQN) of the buckets
            - '--src_path=SRC_BUCKET_FQN/'
            - '--dst_path=DST_BUCKET_FQN/'
            # Cross-namespace mapping: point directly to the live credentials using NAMESPACE/SECRET_NAME
            - '--src_credentials=NAMESPACE/SRC_SECRET_NAME'
            - '--dst_credentials=NAMESPACE/DST_SECRET_NAME'
            # Point to the CA certificate Secret created in the destination namespace
            - '--src_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
            - '--dst_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
            - '--src_type=s3'
            - '--dst_type=s3'
            - '--bandwidth_limit=BANDWIDTH_LIMIT' # Optional. Examples: '10K', '100M', '1G'
      restartPolicy: OnFailure
---

建立排程 CronJob

使用這項設定,即可讓目的地 bucket 持續按照固定時間表與來源 bucket 同步。

---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: transfer-cronjob
  namespace: NAMESPACE
spec:
  schedule: "0 * * * *"  # Runs at the top of every hour. Adjust the cron schedule as needed.
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 5
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: transfer-service-account # The service account created in the previous step
          containers:
            - name: storage-transfer-pod
              image: gcr.io/private-cloud-staging/storage-transfer:latest
              imagePullPolicy: Always
              command:
                - /storage-transfer
              args:
                # The S3 endpoints for your source and destination
                - '--src_endpoint=SRC_ENDPOINT'
                - '--dst_endpoint=DST_ENDPOINT'
                # The Fully Qualified Names (FQN) of the buckets
                - '--src_path=SRC_BUCKET_FQN/'
                - '--dst_path=DST_BUCKET_FQN/'
                # Cross-namespace mapping: point directly to the live credentials using NAMESPACE/SECRET_NAME
                - '--src_credentials=NAMESPACE/SRC_SECRET_NAME'
                - '--dst_credentials=NAMESPACE/DST_SECRET_NAME'
                # Point to the CA certificate Secret created in the destination namespace
                - '--src_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
                - '--dst_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
                - '--src_type=s3'
                - '--dst_type=s3'
                - '--bandwidth_limit=BANDWIDTH_LIMIT' # Optional. Examples: '10K', '100M', '1G'
          restartPolicy: OnFailure
---

監控資料轉移作業

例項化 Job 後,您可以使用 kubectl 指令 (例如 kubectl describe) 監控其狀態。如要驗證轉移作業,請列出目的地值區內的物件,確認資料已轉移。資料移轉工具與參與移轉的端點位置無關。

執行下列指令,檢查工作負載的狀態:

# If you created a one-time Job:
kubectl describe job transfer-job -n NAMESPACE

# If you created a scheduled CronJob:
kubectl describe cronjob transfer-cronjob -n NAMESPACE

上述指令會顯示工作狀態。

這項工作會提示 Pod 轉移資料。你可以取得 Pod 的名稱,並查看記錄檔,確認轉移期間是否發生任何錯誤。

如要查看 Pod 記錄,請執行下列指令:

# 1. First, find the exact pod name generated by your Job
kubectl get pods -n NAMESPACE | grep transfer

# 2. Then, view the logs for that specific pod
kubectl logs POD_NAME -n NAMESPACE

成功的工作記錄:

DEBUG : Starting main for transfer
I0607 21:34:39.183106       1 transfer.go:103]  "msg"="Starting transfer "  "destination"="sample-bucket" "source"="/data"
2023/06/07 21:34:39 NOTICE: Bandwidth limit set to {100Mi 100Mi}
I0607 21:34:49.238901       1 transfer.go:305]  "msg"="Job finished polling "  "Finished"=true "Number of Attempts"=2 "Success"=true
I0607 21:34:49.239675       1 transfer.go:153]  "msg"="Transfer completed."  "AvgSpeed"="10 KB/s" "Bytes Moved"="10.0 kB" "Errors"=0 "Files Moved"=10 "FilesComparedAtSourceAndDest"=3 "Time since beginning of transfer"="1.0s"

查看記錄可瞭解資料移轉速度,這與使用的頻寬、移轉的位元組數、發生錯誤的檔案數和移轉的檔案數不同。

將區塊儲存空間複製到物件儲存空間

請確認您符合下列先決條件:

  • S3 端點,以及具有至少「寫入」權限的 S3 金鑰 ID 和私密存取金鑰,可存取要移轉資料的專屬值區。
  • 可連線至 S3 端點的正常運作叢集。
  • 在叢集中建立 Job 和 Secret 的權限。
  • 如要複製區塊儲存空間,您需要附加 PersistentVolumeClaim (PVC) 的 Pod,並將其備份至物件儲存空間,以及檢查執行中 Job 和 PVC 的權限。
  • 如要複製區塊儲存空間,必須在一段時間內停止對 PersistentVolume (PV) 進行寫入作業。
  • 如要從物件儲存空間端點還原區塊儲存空間,請具備分配 PV 的權限,且 PV 容量充足。

如要將 PV 複製到物件儲存空間,必須將磁碟區附加至現有 Pod。在轉移期間,Pod 不得執行任何寫入作業。為避免從 Job 中卸載已掛接的 PV,資料移轉程序會在與 Pod 相同的機器上執行移轉 Job,並使用 hostPath 掛接將磁碟上的磁碟區公開。為準備轉移作業,您必須先找出 Pod 執行的節點,以及 Pod UID 和 PVC 類型等其他中繼資料,以便參照節點上的適當路徑。您必須將這項中繼資料代入下一節所述的 YAML 範例檔案。

收集中繼資料

如要收集建立資料移轉工作所需的中繼資料,請完成下列步驟:

  1. 找出排定 Pod 的節點:

    kubectl get pod POD_NAME -o jsonpath='{.spec.nodeName}'
    

    請記錄這項指令的輸出內容,做為資料移轉作業 YAML 檔案中使用的 NODE_NAME。

  2. 找出 Pod UID:

    kubectl get pod POD_NAME -o 'jsonpath={.metadata.uid}'
    

    請記錄這項指令的輸出內容,做為資料移轉作業 YAML 檔案中使用的 POD_UID。

  3. 找出 PVC 名稱:

    kubectl get pvc www-web-0 -o 'jsonpath={.spec.volumeName}'
    

    請記錄這項指令的輸出內容,做為資料移轉作業 YAML 檔案中使用的 PVC_NAME。

  4. 找出 PVC 儲存空間佈建器:

    kubectl get pvc www-web-0 -o jsonpath='{.metadata.annotations.volume\.v1\.kubernetes\.io\/storage-provisioner}'
    

    請記錄這項指令的輸出內容,做為資料移轉工作 YAML 檔案中使用的 PROVISIONER_TYPE。

建立密鑰

如要跨叢集將檔案複製到物件儲存空間,您必須先在 Kubernetes 叢集中例項化密碼。您必須使用相符的金鑰,工具才能從 Secret 資料中提取憑證。

如要在現有命名空間中執行轉入作業,請參閱以下範例,瞭解如何在 transfer 命名空間中建立 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: src-secret
  namespace: transfer
data:
  access-key-id: c3JjLWtleQ== # echo -n src-key| base64 -w0
  access-key: c3JjLXNlY3JldA== # echo -n src-secret| base64 -w0
---
apiVersion: v1
kind: Secret
metadata:
  name: dst-secret
  namespace: transfer
data:
  access-key-id: ZHN0LWtleQ== # echo -n dst-key| base64 -w0
  access-key: ZHN0LXNlY3JldA== # echo -n dst-secret| base64 -w0

建立 Job

使用上一節收集的資料,透過資料移轉工具建立工作。資料轉移作業具有 hostPath 掛接,可參照感興趣的 PV 路徑,以及相關節點的 nodeSelector。

以下是資料移轉工作的範例:

apiVersion: batch/v1
kind: Job
metadata:
  name: transfer-job
  namespace: transfer
spec:
  template:
    spec:
      nodeSelector: NODE_NAME
      serviceAccountName: data-transfer-sa
      containers:
      - name: storage-transfer-pod
        image: storage-transfer
        command:
        - /storage-transfer
        args:
        - --dst_endpoint=https://your-dst-endpoint.com
        - --src_path=/pvc-data
        - --dst_path=transfer-dst-bucket
        - --dst_credentials=transfer/dst-secret
        - --src_type=local
        - --dst_type=s3
      volumeMounts:
      - mountPath: /pvc-data
        name: pvc-volume
      volumes:
      - name: pvc-volume
      hostPath:
        path: /var/lib/kubelet/pods/POD_UID/volumes/PROVISIONER_TYPE/PVC_NAME
      restartPolicy: Never

與 S3 資料移轉相同,您必須在 Kubernetes 叢集中建立包含目的地端點存取金鑰的 Secret,且資料移轉作業必須透過服務帳戶執行,該帳戶須具備足夠的權限,才能從 API 伺服器讀取 Secret。使用對 Job 執行的標準 kubectl 指令,監控移轉狀態。

將區塊儲存空間資料轉移至物件儲存空間時,請注意下列細節:

  • 根據預設,符號連結會追蹤並複製到物件儲存空間,但會執行深層而非淺層副本。還原時,系統會毀損符號連結。
  • 與物件儲存空間複製作業一樣,複製到 bucket 的子目錄會造成破壞性影響。確認 bucket 專供磁碟區使用。

從物件儲存空間還原至區塊儲存空間

分配 PV

如要從物件儲存端點還原區塊儲存空間,請按照下列步驟操作:

  1. 在還原作業中,將永久磁碟區分配給目標。使用 PVC 配置磁碟區,如下列範例所示:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: restore-pvc
      namespace: restore-ns
    spec:
      storageClassName: "default"
      accessModes:
    ReadWriteOnce
      resources:
        requests:
          storage: 1Gi # Need sufficient capacity for full restoration.
    
  2. 檢查 PVC 的狀態:

    kubectl get pvc restore-pvc -n restore-ns
    

    PVC 處於 Bound 狀態後,即可在重新補水的 Pod 中使用。

  3. 如果 StatefulSet 最終會耗用 PV,您必須比對已算繪的 StatefulSet PVC。StatefulSet 產生的 Pod 會耗用已補水的磁碟區。以下範例顯示名為 ss 的 StatefulSet 中的磁碟區聲明範本。

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "default"
          resources:
            requests:
              storage: 1Gi
    
  4. 預先配置名為 ss-pvc-name-0 和 ss-pvc-name-1 的 PVC,確保產生的 Pod 會耗用預先配置的磁碟區。

為 PV 補水

PVC 繫結至 PV 後,請啟動 Job 來填入 PV:

apiVersion: batch/v1
kind: Job
metadata:
  name: transfer-job
  namespace: transfer
spec:
  template:
    spec:
      serviceAccountName: data-transfer-sa
      volumes:
      - name: data-transfer-restore-volume
        persistentVolumeClaim:
          claimName: restore-pvc
      containers:
      - name: storage-transfer-pod
        image: storage-transfer
        command:
        - /storage-transfer
        args:
        - --src_endpoint=https://your-src-endpoint.com
        - --src_path=/your-src-bucket
        - --src_credentials=transfer/src-secret
        - --dst_path=/restore-pv-mnt-path
        - --src_type=s3
        - --dst_type=local
      volumeMounts:
      - mountPath: /restore-pv-mnt-path
        name: data-transfer-restore-volume

工作執行完畢後,物件儲存空間 bucket 中的資料會填入磁碟區。另一個 Pod 可以使用相同的標準機制掛接磁碟區,進而取用資料。