データ転送

データ転送は次の間で行うことができます。

  1. Persistent Volume Claim(PVC)とオブジェクト ストレージ
  2. オブジェクト ストレージとオブジェクト ストレージ(GDC 内)

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

データソース/宛先の種類

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

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

次の前提条件を満たしていることを確認します。

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

ジョブの作成

ジョブを作成する手順は次のとおりです。

  1. Namespace を作成します。

    apiVersion: v1
    kind: Namespace
    metadata:
      name: transfer-ns
    
  2. 認証情報を作成します。

    ---
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: src-secret
      namespace: transfer-ns
    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: transfer-ns
    data:
      access-key-id: NkFDTUg3WDBCVDlQMVpZMU5MWjU= # base 64 encoded version of key
      access-key: VkRkeWJsbFgzb2FZanMvOVpnSi83SU5YUjk3Y0Q2TUdxZ2d4Q3dpdw== # base 64 encoded version of secret key
    ---
    

    これらの認証情報は、オブジェクト ストレージ セクションで取得したものと同じです。

  3. 転送で使用されるサービス アカウント(SA)を作成し、ロールとロール バインディングを使用してシークレットの読み取りと書き込みを行う権限をアカウントに追加します。デフォルトの名前空間 SA またはカスタム SA にこれらの権限がすでに付与されている場合は、権限を追加する必要はありません。

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: transfer-service-account
      namespace: transfer-ns
    ---
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: transfer-ns
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    
    ---
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-secrets-rolebinding
      namespace: transfer-ns
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: transfer-ns
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    
    ---
    
  4. オブジェクト ストレージ システムの CA 証明書を取得します。同じ証明書は AO/PA から取得できます。

    ---
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: src-cert
      namespace: transfer-ns
    data:
      ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUpHM2psOFZhTU85a1FteGdXUFl3N3d3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF5TVRVd01USXlNakZhRncweQpNekExTVRZd01USXlNakZhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWI== # base 64 encoded version of certificate
    
    ---
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: dst-cert
      namespace: transfer-ns
    data:
      ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUtoaEJXWWo3VGZlUUZWUWo0U0RpckV3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF6TURZeU16TTROVEJhRncweQpNekEyTURReU16TTROVEJhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWIzRFFF== # base 64 encoded version of certificate. Can be same OR different than source certificate.
    
    ---
    
    
  5. 省略可: Loki で転送サービスのログを表示する LoggingTarget を作成します。

    apiVersion: logging.gdc.goog/v1
    kind: LoggingTarget
    metadata:
      namespace: transfer-ns # 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
    
  6. ジョブを作成します。

    ---
    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: transfer-job
      namespace: transfer-ns
    spec:
      template:
        spec:
          serviceAccountName: transfer-service-account #service account created earlier
          containers:
            - name: storage-transfer-pod #
              image: gcr.io/private-cloud-staging/storage-transfer:latest
              imagePullPolicy: Always #will always pull the latest image
              command:
                - /storage-transfer
              args:
                - '--src_endpoint=objectstorage.zone1.google.gdch.test' #Your endpoint here
                - '--dst_endpoint=objectstorage.zone1.google.gdch.test' #Your endpoint here
                - '--src_path=aecvd-bucket1' #Please use Fully Qualified Name
                - '--dst_path=aklow-bucket2' #Please use Fully Qualified Name
                - '--src_credentials=transfer-ns/src-secret' #Created earlier
                - '--dst_credentials=transfer-ns/dst-secret' #Created earlier
                - '--dst_ca_certificate_reference=transfer-ns/dst-cert' #Created earlier
                - '--src_ca_certificate_reference=transfer-ns/src-cert' #Created earlier
                - '--src_type=s3'
                - '--dst_type=s3'
                - '--bandwidth_limit=10M' #Optional of the form '10K', '100M', '1G' bytes per second
          restartPolicy: OnFailure #Will restart on failure.
    ---
    

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

Job をインスタンス化した後、kubectl describe などの kubectl コマンドを使用してステータスをモニタリングできます。転送を確認するには、移行先バケット内のオブジェクトを一覧表示して、データが転送されたことを検証します。データ転送ツールは、転送に関与するエンドポイントの場所を認識しません。

以下のコマンドを実行します。

kubectl describe transfer-job -n transfer-ns

上記のコマンドは、ジョブのステータスを示します。

ジョブは、データを転送するよう Pod に指示します。Pod の名前を取得し、ログを確認して、転送中にエラーが発生していないかどうかを確認できます。

Pod ログを表示するには、次のコマンドを実行します。

kubectl logs transfer-job-<pod_id_suffix_obtained_from_describe_operation_on_job> -n transfer-ns

成功したジョブのログ:

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

PV をオブジェクト ストレージに複製するには、既存の Pod にボリュームをアタッチする必要があります。転送期間中、Pod は書き込みを実行してはなりません。マウントされた PV が Job から切り離されないように、データ転送プロセスでは、Pod と同じマシンで転送 Job を実行し、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 クラスタ内でシークレットをインスタンス化する必要があります。ツールが認証情報を取得するには、シークレット データに一致する鍵を使用する必要があります。

既存の 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 データ転送と同様に、宛先エンドポイントのアクセスキーを含む Secret を Kubernetes クラスタに作成する必要があります。また、API サーバーから Secret を読み取るのに十分な権限を持つサービス アカウントでデータ転送ジョブを実行する必要があります。Job で動作する標準の 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 は、ハイドレートされた Volume を使用します。次の例は、ss という名前の StatefulSet のボリューム クレーム テンプレートを示しています。

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "default"
          resources:
            requests:
              storage: 1Gi
    
  4. ss-pvc-name-0ss-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

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