データ転送

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

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

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

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

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

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

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

  • ソースに対する読み取り権限を持つ S3 エンドポイントと、転送先に対する書き込み権限を持つ s3 エンドポイント。
  • 認証情報にバケット作成権限がない場合、転送先バケットが存在しないと転送は失敗します。その場合は、転送先バケットが存在することを確認してください。
  • クラスタまたは Namespace 内でジョブを作成し、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)を作成し、ロールとロール バインディングを使用して Secret を読み書きする権限をアカウントに追加します。デフォルトの Namespace 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. 省略可: LoggingTarget を作成して、Loki で転送サービスのログを表示します。

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

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

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

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

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 エンドポイントに接続された動作中のクラスタ。
  • クラスタ内でジョブと 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-0ss-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 は、ボリュームのマウントに同じ標準メカニズムを使用してデータを使用できます。