データ転送

データ転送は、次の間で発生する可能性があります。

  1. 永続ボリューム クレーム(PVC)とオブジェクト ストレージ
  2. オブジェクト ストレージとオブジェクト ストレージ(GDC 内)

GDC のオブジェクト ストレージは S3 互換で、Kubernetes YAML では s3 タイプと呼ばれます。

データソースと転送先のタイプ

  1. オブジェクト ストレージ(「s3」と呼ばれる): GDC に存在するオブジェクト ストレージ
  2. ローカル ストレージ(「local」と呼ばれる): 接続された PVC 上のストレージ

オブジェクト ストレージからオブジェクト ストレージへのコピー

次の前提条件を満たしていることを確認してください。

  • ソースに対する読み取り権限を持つ S3 エンドポイントと、転送先に対する書き込み権限を持つ s3 エンドポイント。
  • 認証情報にバケット作成権限がない場合、転送先バケットが存在しないと転送は失敗します。その場合は、転送先バケットが存在することを確認してください。
  • クラスタまたは Namespace 内でジョブを作成し、Secret を作成または読み取る権限。権限の例については、以下をご覧ください。

データ転送を設定する

データ転送を設定する手順は次のとおりです。

転送 Namespace を作成する

転送ジョブを実行する Namespace を作成します。

apiVersion: v1
kind: Namespace
metadata:
  name: NAMESPACE

認証情報の構成

転送用の認証情報を準備します。転送シナリオに最も適したオプションを選択してください。

GDC から GDC への転送

同じ GDC ユニバース内で完全に発生する転送の場合、Secret はすでに存在します。この方法は、異なるユニバース間の転送ではなく、単一のユニバース内の転送にのみ使用できます。

  1. S3 認証情報 Secret を取得するには、バケットへのアクセス権を付与するの手順に沿って操作します。

  2. 転送ジョブの転送先 Namespace にサービス アカウント(SA)を作成します。次に、クロス Namespace RoleBinding を使用して、このアカウントが転送元と転送先の両方の Namespace で Secret を読み取れるように権限を追加します。

    ---
    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. 転送先 Namespace に認証情報を作成します。

    ---
    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)を作成し、ロールと RoleBinding を使用して Secret を読み書きする権限をアカウントに追加します。デフォルトの Namespace 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 を使用して 1 回限りのオペレーションとして実行することも、CronJob を使用して繰り返し実行するようにスケジュールすることもできます。

ユースケースに最適な方法を選択してください。

1 回限りのジョブを作成する

この構成は、1 回限りの手動データ転送に使用します。

---
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 を作成する

この構成を使用すると、固定スケジュールで転送先バケットを転送元バケットと継続的に同期できます。

---
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
---

データ転送をモニタリングする

ジョブをインスタンス化したら、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 キー ID とシークレット アクセスキーを持つ S3 エンドポイント。少なくとも、データを転送する専用バケットに対する書き込み権限が必要です。
  • S3 エンドポイントに接続された、動作中のクラスタ。
  • クラスタ内でジョブと Secret を作成する権限。
  • ブロック ストレージのレプリケーションの場合、オブジェクト ストレージにバックアップする PersistentVolumeClaim(PVC)が接続された Pod と、実行中のジョブと PVC を検査する権限。
  • ブロック ストレージのレプリケーションの場合、PersistentVolume(PV)への書き込みが行われない期間。
  • オブジェクト ストレージ エンドポイントからブロック ストレージを復元する場合、十分な容量の PV を割り当てる権限。

PV をオブジェクト ストレージにレプリケートするには、既存の Pod にボリュームを接続する必要があります。転送期間中、Pod は書き込みを実行できません。マウントされた PV がジョブから切り離されないように、データ転送プロセスでは、Pod と同じマシンで転送ジョブを実行し、hostPath マウントを使用してディスク上のボリュームを公開します。転送の準備として、まず Pod が実行されているノードと、Pod UID や PVC タイプなどの追加のメタデータを特定して、ノード上の適切なパスを参照する必要があります。このメタデータは、次のセクションで説明するサンプル YAML ファイルに置き換える必要があります。

メタデータを収集する

データ転送ジョブの作成に必要なメタデータを収集する手順は次のとおりです。

  1. スケジュールされた Pod を持つノードを見つけます。

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

    このコマンドの出力を NODE_NAME として 記録し、データ転送ジョブの YAML ファイルで使用します。

  2. Pod UID を見つけます。

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

    このコマンドの出力を POD_UID として記録し、データ転送ジョブの YAML ファイルで 使用します。

  3. PVC 名を見つけます。

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

    このコマンドの出力を PVC_NAME として記録し、データ転送ジョブの YAML ファイルで 使用します。

  4. PVC ストレージ プロビジョナーを見つけます。

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

    このコマンドの出力を PROVISIONER_TYPEとして記録し、データ転送ジョブの YAML ファイルで使用します。

Secret を作成する

クラスタ間でファイルをオブジェクト ストレージにレプリケートするには、まず Kubernetes クラスタ内に Secret をインスタンス化する必要があります。ツールが認証情報をプルするには、Secret データに一致する鍵を使用する必要があります。

既存の Namespace で転送を行うには、transfer Namespace に 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

ジョブを作成する

前のセクションで収集したデータを使用して、データ転送ツールでジョブを作成します。データ転送ジョブには、目的の PV のパスを参照する hostPath マウントと、関連するノードの 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 を読み取るのに十分な権限を持つサービス アカウントで実行する必要があります。ジョブで動作する標準の kubectl コマンドを使用して、転送のステータスをモニタリングします。

ブロック ストレージをオブジェクト ストレージに転送する場合は、次の点に注意してください。

  • デフォルトでは、シンボリック リンクはオブジェクト ストレージに追従してレプリケートされますが、浅いコピーではなくディープコピーが実行されます。復元時に、シンボリック リンクは破棄されます。
  • オブジェクト ストレージのレプリケーションと同様に、バケットのサブディレクトリへのクローン作成は破壊的です。バケットがボリューム専用であることを確認してください。

オブジェクト ストレージからブロック ストレージに復元する

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 にバインドされたら、ジョブを開始して 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

ジョブの実行が完了すると、オブジェクト ストレージ バケットのデータがボリュームに入力されます。別の Pod は、ボリュームのマウントに同じ標準メカニズムを使用してデータを使用できます。