Transferir datos

Las transferencias de datos pueden producirse entre los siguientes elementos:

  1. Reclamación de volumen persistente (PVC) y almacenamiento de objetos
  2. Almacenamiento de objetos y almacenamiento de objetos (en GDC)

El almacenamiento de objetos en GDC es compatible con S3 y se denomina tipo s3 en los archivos YAML de Kubernetes.

Tipos de fuentes o destinos de datos

  1. Almacenamiento de objetos (denominado "s3"): almacenamiento de objetos presente en GDC
  2. Almacenamiento local (denominado "local"): almacenamiento en PVCs conectados

Copiar datos de un almacenamiento de objetos a otro

Asegúrate de que cumples los siguientes requisitos previos:

  • Un endpoint de S3 con permisos de lectura para la fuente y un endpoint de S3 con permisos de escritura para el destino.
  • Si no tienes permiso para crear segmentos con las credenciales, la transferencia fallará si el segmento de destino no existe. Asegúrate de que el segmento de destino exista.
  • Privilegios para crear trabajos y crear o leer secretos en tu clúster o espacio de nombres. Consulta el siguiente ejemplo de permisos.

Crear una tarea

Para crear un trabajo, sigue estos pasos:

  1. Crea un espacio de nombres:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: transfer-ns
    
  2. Crea las credenciales:

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

    Estas credenciales son las mismas que obtuviste en la sección de almacenamiento de objetos.

  3. Crea una cuenta de servicio que use tu transferencia y, a continuación, añade permisos a la cuenta para leer y escribir secretos mediante roles y enlaces de roles. No es necesario que añadas permisos si tu SA de espacio de nombres predeterminado o tu SA personalizado ya los tienen.

    ---
    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. Obtén los certificados de CA de tus sistemas de almacenamiento de objetos. Puedes obtener los mismos certificados de tu partner de asistencia.

    ---
    
    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. Opcional: Crea un LoggingTarget para ver los registros del servicio de transferencia en 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. Crea el trabajo:

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

Monitorizar la transferencia de datos

Una vez que hayas creado una instancia de Job, podrás monitorizar su estado mediante kubectl comandos, como kubectl describe. Para verificar la transferencia, enumera los objetos del contenedor de destino para validar que los datos se han transferido. La herramienta de transferencia de datos no tiene en cuenta la ubicación de los endpoints implicados en la transferencia.

Ejecuta lo siguiente:

kubectl describe transfer-job -n transfer-ns

El comando anterior te indica el estado del trabajo.

La tarea pide a un pod que transfiera los datos. Puedes obtener el nombre del pod y consultar los registros para ver si hay algún error durante la transferencia.

Para ver los registros de un pod, ejecuta lo siguiente:

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

Registros de tareas correctos:

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"

Ver los registros te permite consultar la velocidad de transferencia de datos, que no es la misma que el ancho de banda utilizado, los bytes transferidos, el número de archivos con errores y los archivos transferidos.

Copiar almacenamiento en bloques en almacenamiento de objetos

Asegúrate de que cumples los siguientes requisitos previos:

  • Un endpoint de S3 con un ID de clave de S3 y una clave de acceso secreta con al menos permisos de ESCRITURA en el segmento específico al que quieras transferir datos.
  • Un clúster que funcione y que tenga conectividad con el endpoint de S3.
  • Privilegios para crear trabajos y secretos en tu clúster.
  • Para la replicación del almacenamiento en bloque, un pod con un PersistentVolumeClaim (PVC) adjunto que quieras crear una copia de seguridad en el almacenamiento de objetos y privilegios para inspeccionar los trabajos y los PVCs en ejecución.
  • Para la replicación del almacenamiento en bloque, se necesita un periodo durante el cual no se escriba en el PersistentVolume (PV).
  • Para restaurar el almacenamiento en bloques desde un endpoint de almacenamiento de objetos, privilegios para asignar un PV con capacidad suficiente.

Para replicar un PV en el almacenamiento de objetos, debes adjuntar un volumen a un Pod. Durante la ventana de transferencia, el Pod no debe realizar ninguna escritura. Para evitar que el PV montado se desasocie del trabajo, el proceso de transferencia de datos ejecuta el trabajo de transferencia en la misma máquina que el pod y usa un montaje hostPath para exponer el volumen en el disco. Antes de realizar la transferencia, debes buscar el nodo en el que se está ejecutando el pod y metadatos adicionales, como el UID del pod y el tipo de PVC, para hacer referencia a la ruta adecuada del nodo. Debes sustituir estos metadatos en el archivo YAML de ejemplo que se indica en la sección siguiente.

Recopilar metadatos

Para recoger los metadatos necesarios para crear el trabajo de transferencia de datos, sigue estos pasos:

  1. Busca el nodo que tenga el pod programado:

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

    Registra el resultado de este comando como NODE_NAME para usarlo en el archivo YAML de la tarea de transferencia de datos.

  2. Busca el UID del pod:

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

    Registra el resultado de este comando como POD_UID para usarlo en el archivo YAML de la tarea de transferencia de datos.

  3. Busca el nombre del PVC:

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

    Registra el resultado de este comando como PVC_NAME para usarlo en el archivo YAML de la tarea de transferencia de datos.

  4. Busca el aprovisionador de almacenamiento de PVC:

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

    Registra el resultado de este comando como PROVISIONER_TYPE para usarlo en el archivo YAML de la tarea de transferencia de datos.

Crear secretos

Para replicar archivos en el almacenamiento de objetos entre clústeres, primero debes crear instancias de los secretos en tu clúster de Kubernetes. Debes usar claves coincidentes para que la herramienta pueda extraer las credenciales de los datos secretos.

Para realizar la transferencia en un espacio de nombres, consulta el siguiente ejemplo de creación de secretos en un espacio de nombres transfer:

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

Crear la tarea

Con los datos que ha recogido en la sección anterior, cree un trabajo con la herramienta de transferencia de datos. La tarea de transferencia de datos tiene un montaje hostPath que hace referencia a la ruta del PV de interés y un nodeSelector para el nodo correspondiente.

A continuación, se muestra un ejemplo de un trabajo de transferencia de datos:

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

Al igual que con la transferencia de datos de S3, debes crear un secreto que contenga las claves de acceso del endpoint de destino en el clúster de Kubernetes. Además, el trabajo de transferencia de datos debe ejecutarse con una cuenta de servicio que tenga los privilegios adecuados para leer el secreto del servidor de la API. Monitoriza el estado de la transferencia con los comandos estándar de kubectl que operan en la tarea.

Tenga en cuenta los siguientes detalles al transferir almacenamiento en bloques a almacenamiento de objetos:

  • De forma predeterminada, los enlaces simbólicos se siguen y se replican en el almacenamiento de objetos, pero se realiza una copia profunda en lugar de una superficial. Al restaurarse, se destruyen los enlaces simbólicos.
  • Al igual que con la replicación de almacenamiento de objetos, la clonación en un subdirectorio del segmento es destructiva. Asegúrate de que el contenedor esté disponible exclusivamente para tu volumen.

Restaurar de almacenamiento de objetos a almacenamiento en bloques

Asignar un PV

Para restaurar el almacenamiento en bloque desde un endpoint de almacenamiento de objetos, sigue estos pasos:

  1. Asigna un volumen persistente al destino de la restauración. Usa un PVC para asignar el volumen, como se muestra en el siguiente ejemplo:

    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. Comprueba el estado del PVC:

    kubectl get pvc restore-pvc -n restore-ns
    

    Cuando el PVC está en estado Bound, se puede usar en el pod que lo rehidrata.

  3. Si un conjunto con estado consume finalmente el PV, debes hacer coincidir los PVCs del conjunto con estado renderizados. Los pods que produce StatefulSet consumen los volúmenes hidratados. En el siguiente ejemplo se muestran plantillas de reclamación de volumen en un StatefulSet llamado ss.

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "default"
          resources:
            requests:
              storage: 1Gi
    
  4. Preasigna PVCs con nombres como ss-pvc-name-0 y ss-pvc-name-1 para asegurarte de que los pods resultantes consuman los volúmenes preasignados.

Hidratar el PV

Una vez que el PVC se haya vinculado a un PV, inicia el trabajo para rellenar el 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

Una vez que la tarea ha terminado de ejecutarse, los datos del contenedor de almacenamiento de objetos se insertan en el volumen. Otro pod puede consumir los datos usando los mismos mecanismos estándar para montar un volumen.