Daten übertragen

Datenübertragungen können zwischen den folgenden Elementen erfolgen:

  1. PersistentVolumeClaim (PVC) und Objektspeicher
  2. Objektspeicher und Objektspeicher (in GDC)

Der Objektspeicher auf GDC ist S3-kompatibel und wird in Kubernetes-YAMLs als Typ s3 bezeichnet.

Arten von Datenquellen/-zielen

  1. Objektspeicher (als „s3“ bezeichnet): Objektspeicher auf GDC
  2. Lokaler Speicher (als „lokal“ bezeichnet): Speicher auf angehängten PVCs

Von Objektspeicher zu Objektspeicher kopieren

Prüfen Sie, ob die folgenden Voraussetzungen erfüllt sind:

  • Ein S3-Endpunkt mit Leseberechtigungen für die Quelle und ein S3-Endpunkt mit Schreibberechtigungen für das Ziel.
  • Wenn Sie mit den Anmeldedaten keine Berechtigung zum Erstellen von Buckets haben, schlägt die Übertragung fehl, wenn der Ziel-Bucket nicht vorhanden ist. Prüfen Sie, ob der Ziel-Bucket vorhanden ist.
  • Berechtigungen zum Erstellen von Jobs und zum Erstellen oder Lesen von Secrets in Ihrem Cluster oder Namespace. Im Folgenden finden Sie ein Beispiel für Berechtigungen.

Job erstellen

So erstellen Sie einen Job:

  1. Erstellen Sie einen Namespace:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: transfer-ns
    
  2. Anmeldedaten erstellen:

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

    Diese Anmeldedaten sind dieselben, die Sie im Abschnitt zum Objektspeicher erhalten haben.

  3. Erstellen Sie ein Dienstkonto, das für die Übertragung verwendet wird, und fügen Sie dem Konto dann Berechtigungen zum Lesen und Schreiben von Secrets mithilfe von Rollen und Rollenbindungen hinzu. Sie müssen keine Berechtigungen hinzufügen, wenn Ihre Standard-Namespace-SA oder benutzerdefinierte SA bereits diese Berechtigungen hat.

    ---
    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. Rufen Sie die CA-Zertifikate für Ihre Objektspeichersysteme ab. Sie können dieselben Zertifikate von Ihrem AO/PA erhalten.

    ---
    
    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. Optional: Erstellen Sie ein LoggingTarget, um Logs des Transferdienstes in Loki aufzurufen.

    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. Erstellen Sie den Job:

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

Datenübertragung überwachen

Nachdem Sie den Job instanziiert haben, können Sie seinen Status mit kubectl-Befehlen wie kubectl describe überwachen. Um die Übertragung zu überprüfen, listen Sie die Objekte in Ihrem Ziel-Bucket auf, um zu prüfen, ob Ihre Daten übertragen wurden. Das Tool für die Datenübertragung ist unabhängig vom Speicherort der am Transfer beteiligten Endpunkte.

Führen Sie den folgenden Befehl aus:

kubectl describe transfer-job -n transfer-ns

Der vorherige Befehl gibt den Status des Jobs an.

Der Job fordert einen Pod auf, die Daten zu übertragen. Sie können den Namen des Pods abrufen und die Logs ansehen, um festzustellen, ob während der Übertragung Fehler aufgetreten sind.

Führen Sie den folgenden Befehl aus, um Pod-Logs aufzurufen:

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

Logs für erfolgreiche Jobs:

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"

Wenn Sie sich die Protokolle ansehen, können Sie die Datenübertragungsgeschwindigkeit sehen. Diese ist nicht identisch mit der verwendeten Bandbreite, den verschobenen Bytes, der Anzahl der Dateien mit Fehlern und den verschobenen Dateien.

Blockspeicher in Objektspeicher kopieren

Prüfen Sie, ob die folgenden Voraussetzungen erfüllt sind:

  • Ein S3-Endpunkt mit einer S3-Schlüssel-ID und einem geheimen Zugriffsschlüssel mit mindestens WRITE-Berechtigungen für den dedizierten Bucket, in den Sie Daten übertragen möchten.
  • Ein funktionierender Cluster mit Verbindung zum S3-Endpunkt.
  • Berechtigungen zum Erstellen von Jobs und Secrets in Ihrem Cluster.
  • Für die Replikation von Blockspeicher benötigen Sie einen Pod mit einem angehängten PersistentVolumeClaim (PVC), den Sie im Objektspeicher sichern möchten, sowie Berechtigungen zum Prüfen laufender Jobs und PVCs.
  • Für die Replikation des Blockspeichers ist ein Zeitraum erforderlich, in dem keine Schreibvorgänge auf das PersistentVolume (PV) erfolgen.
  • Für die Wiederherstellung von Blockspeicher von einem Objektspeicher-Endpunkt sind Berechtigungen zum Zuweisen eines PV mit ausreichender Kapazität erforderlich.

Wenn Sie ein PV in den Objektspeicher replizieren möchten, müssen Sie ein Volume an einen vorhandenen Pod anhängen. Während des Übertragungszeitraums darf der Pod keine Schreibvorgänge ausführen. Damit das bereitgestellte PV nicht vom Job getrennt wird, wird der Übertragungsjob auf demselben Computer wie der Pod ausgeführt. Außerdem wird ein hostPath-Mount verwendet, um das Volume auf der Festplatte verfügbar zu machen. Zur Vorbereitung der Übertragung müssen Sie zuerst den Knoten finden, auf dem der Pod ausgeführt wird, sowie zusätzliche Metadaten wie die Pod-UID und den PVC-Typ, um auf den entsprechenden Pfad auf dem Knoten zu verweisen. Sie müssen diese Metadaten in die Beispiel-YAML-Datei einfügen, die im folgenden Abschnitt beschrieben wird.

Metadaten erfassen

So erfassen Sie die Metadaten, die zum Erstellen des Datenübertragungsjobs erforderlich sind:

  1. Suchen Sie den Knoten mit dem geplanten Pod:

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

    Notieren Sie die Ausgabe dieses Befehls als NODE_NAME, um sie in der YAML-Datei des Datenübertragungsjobs zu verwenden.

  2. Suchen Sie die Pod-UID:

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

    Notieren Sie die Ausgabe dieses Befehls als POD_UID, um sie in der YAML-Datei des Datenübertragungsjobs zu verwenden.

  3. Suchen Sie den PVC-Namen:

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

    Notieren Sie die Ausgabe dieses Befehls als PVC_NAME, um sie in der YAML-Datei des Datenübertragungsjobs zu verwenden.

  4. Suchen Sie den PVC-Speicherbereitsteller:

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

    Notieren Sie die Ausgabe dieses Befehls als PROVISIONER_TYPE, die in der YAML-Datei des Datenübertragungsjobs verwendet werden soll.

Secrets erstellen

Wenn Sie Dateien in Objektspeicher über Cluster hinweg replizieren möchten, müssen Sie zuerst die Secrets in Ihrem Kubernetes-Cluster instanziieren. Sie müssen übereinstimmende Schlüssel für die vertraulichen Daten verwenden, damit das Tool die Anmeldedaten abrufen kann.

Wenn Sie die Übertragung in einem vorhandenen Namespace durchführen möchten, sehen Sie sich das folgende Beispiel zum Erstellen von Secrets im Namespace transfer an:

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 erstellen

Erstellen Sie mit den Daten, die Sie im vorherigen Abschnitt erhoben haben, einen Job mit dem Tool zur Datenübertragung. Der Datenübertragungsjob hat eine hostPath-Bereitstellung, die auf den Pfad für das relevante persistente Volume verweist, und eine nodeSelector für den relevanten Knoten.

Im Folgenden sehen Sie ein Beispiel für einen Datenübertragungsjob:

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

Wie beim S3-Datenübertragungsvorgang müssen Sie im Kubernetes-Cluster ein Secret mit den Zugriffsschlüsseln für den Zielendpunkt erstellen. Der Datenübertragungsjob muss mit einem Dienstkonto ausgeführt werden, das über ausreichende Berechtigungen zum Lesen des Secrets vom API-Server verfügt. Überwachen Sie den Status der Übertragung mit Standardbefehlen für kubectl, die für den Job ausgeführt werden.

Beachten Sie beim Übertragen von Blockspeicher in Objektspeicher die folgenden Details:

  • Standardmäßig werden symbolische Links verfolgt und in den Objektspeicher repliziert. Es wird jedoch eine tiefe anstelle einer flachen Kopie ausgeführt. Beim Wiederherstellen werden Symlinks zerstört.
  • Wie bei der Objekt-Speicherreplikation ist das Klonen in ein Unterverzeichnis des Buckets destruktiv. Achten Sie darauf, dass der Bucket ausschließlich für Ihr Volume verfügbar ist.

Aus Objektspeicher in Blockspeicher wiederherstellen

PV zuweisen

So stellen Sie Blockspeicher über einen Objektspeicher-Endpunkt wieder her:

  1. Weisen Sie dem Ziel der Wiederherstellung ein nichtflüchtiges Volume zu. Verwenden Sie einen PVC, um das Volume zuzuweisen, wie im folgenden Beispiel gezeigt:

    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. Prüfen Sie den Status des PVC:

    kubectl get pvc restore-pvc -n restore-ns
    

    Sobald sich der PVC im Status Bound befindet, kann er im Pod verwendet werden, in dem er rehydriert wird.

  3. Wenn ein StatefulSet das PV schließlich nutzt, müssen Sie die gerenderten StatefulSet-PVCs abgleichen. Die Pods, die von StatefulSet erstellt werden, verwenden die hydrierten Volumes. Das folgende Beispiel zeigt Vorlagen für Volume-Ansprüche in einem StatefulSet namens ss.

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "default"
          resources:
            requests:
              storage: 1Gi
    
  4. Weisen Sie PVCs mit Namen wie ss-pvc-name-0 und ss-pvc-name-1 vorab zu, damit die resultierenden Pods die vorab zugewiesenen Volumes verwenden.

PV mit Wasser versorgen

Nachdem der PVC an ein PV gebunden wurde, starten Sie den Job, um das PV zu füllen:

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

Nach Abschluss des Jobs werden die Daten aus dem Objektspeicher-Bucket in das Volume übertragen. Ein separater Pod kann die Daten über dieselben Standardmechanismen zum Einbinden eines Volumes nutzen.