Volúmenes persistentes y aprovisionamiento dinámico de GKE

En esta página se ofrece una descripción general de los volúmenes persistentes (PVs), las reclamaciones de volumen persistente (PVCs) y las clases de almacenamiento en Google Kubernetes Engine (GKE). Se centra en el almacenamiento respaldado por discos persistentes de Compute Engine.

Aprenderás a crear, gestionar y solucionar problemas de almacenamiento persistente de forma eficaz en tus clústeres de GKE para garantizar la seguridad de los datos, la alta disponibilidad y el rendimiento óptimo.

Esta página está dirigida a especialistas en almacenamiento que crean y asignan almacenamiento, y que configuran y gestionan la seguridad, la protección, el acceso y los permisos de los datos. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas de usuario habituales de GKE.Google Cloud

PersistentVolumes

Los recursos PersistentVolume se usan para gestionar el almacenamiento duradero en un clúster. En GKE, un PersistentVolume suele estar respaldado por un disco persistente.

Puedes usar otras soluciones de almacenamiento, como NFS. Filestore es una solución de NFS enGoogle Cloud. Para saber cómo configurar una instancia de Filestore como solución de PV de NFS para tus clústeres de GKE, consulta el artículo Acceder a instancias de Filestore con el controlador CSI de Filestore en la documentación de Filestore.

Kubernetes gestiona el ciclo de vida de PersistentVolume. Un PersistentVolume se puede aprovisionar de forma dinámica, por lo que no tienes que crear ni eliminar manualmente el almacenamiento subyacente.

Los recursos PersistentVolume son recursos de clúster que existen independientemente de los pods. Esto significa que el disco y los datos representados por un PersistentVolume siguen existiendo a medida que cambia el clúster y se eliminan y se vuelven a crear pods. Los recursos de PersistentVolume se pueden aprovisionar de forma dinámica a través de PersistentVolumeClaims o los puede crear explícitamente un administrador del clúster.

Para obtener más información sobre los recursos de PersistentVolume, consulta la documentación sobre los volúmenes persistentes de Kubernetes y la referencia de la API Persistent Volumes.

PersistentVolumeClaims

Un PersistentVolumeClaim es una solicitud y una reclamación de un recurso PersistentVolume. Los objetos PersistentVolumeClaim solicitan un tamaño, un modo de acceso y un StorageClass específicos para el PersistentVolume. Si existe o se puede aprovisionar un PersistentVolume que satisfaga la solicitud, el PersistentVolumeClaim se vincula a ese PersistentVolume.

Los pods usan reclamaciones como volúmenes. El clúster inspecciona la reclamación para encontrar el volumen enlazado y lo monta en el pod.

La portabilidad es otra de las ventajas de usar PersistentVolumes y PersistentVolumeClaims. Puedes usar fácilmente la misma especificación de pod en diferentes clústeres y entornos, ya que PersistentVolume es una interfaz para el almacenamiento de respaldo real.

StorageClasses

Las implementaciones de volúmenes, como el controlador de interfaz de almacenamiento de contenedor (CSI) para Persistent Disk en Compute Engine, se configuran mediante recursos StorageClass.

GKE crea un StorageClass predeterminado que usa el tipo de disco persistente balanceado (ext4). El valor predeterminado StorageClass se usa cuando un PersistentVolumeClaim no especifica un StorageClassName. Puedes sustituir el valor predeterminado StorageClass por el que quieras. Para obtener instrucciones, consulta Cambiar el StorageClass predeterminado.

Puedes crear tus propios recursos StorageClass para describir diferentes clases de almacenamiento. Por ejemplo, las clases pueden asignarse a niveles de calidad del servicio o a políticas de copia de seguridad. En otros sistemas de almacenamiento, este concepto se denomina "perfiles".

Si usas un clúster con grupos de nodos de Windows, debes crear un StorageClass y especificar un StorageClassName en el PersistentVolumeClaim, ya que el tipo de sistema de archivos predeterminado (ext4) no es compatible con Windows. Si usas un disco persistente de Compute Engine, debes usar NTFS como tipo de almacenamiento de archivos.

Cuando definas un StorageClass, debes indicar un aprovisionador. En GKE, te recomendamos que uses uno de los siguientes provisionadores:

Aprovisionar PersistentVolumes de forma dinámica

La mayoría de las veces, no es necesario configurar directamente objetos PersistentVolume ni crear discos persistentes de Compute Engine. En su lugar, puedes crear un PersistentVolumeClaim y Kubernetes aprovisionará automáticamente un disco persistente.

El siguiente manifiesto describe una solicitud de un disco con 30 gibibytes (GiB) de almacenamiento cuyo modo de acceso permite que un solo nodo lo monte como lectura y escritura. También crea un pod que consume el PersistentVolumeClaim como volumen.

# pvc-pod-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi
  storageClassName: standard-rwo
---
kind: Pod
apiVersion: v1
metadata:
  name: pod-demo
spec:
  volumes:
    - name: pvc-demo-vol
      persistentVolumeClaim:
       claimName: pvc-demo
  containers:
    - name: pod-demo
      image: nginx
      resources:
        limits:
          cpu: 10m
          memory: 80Mi
        requests:
          cpu: 10m
          memory: 80Mi
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: pvc-demo-vol

Cuando creas este objeto PersistentVolumeClaim con kubectl apply -f pvc-pod-demo.yaml, Kubernetes crea dinámicamente un objeto PersistentVolume correspondiente.

Como la clase de almacenamiento standard-rwo usa el modo de vinculación de volúmenes WaitForFirstConsumer, el PersistentVolume no se creará hasta que se programe un pod para consumir el volumen.

En el siguiente ejemplo se muestra el PersistentVolume creado.

apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: pd.csi.storage.gke.io
  finalizers:
  - kubernetes.io/pv-protection
  - external-attacher/pd-csi-storage-gke-io
  name: pvc-c9a44c07-cffa-4cd8-b92b-15bac9a9b984
  uid: d52af557-edf5-4f96-8e89-42a3008209e6
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 30Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc-demo
    namespace: default
    uid: c9a44c07-cffa-4cd8-b92b-15bac9a9b984
  csi:
    driver: pd.csi.storage.gke.io
    csi.storage.k8s.io/fstype: ext4
    volumeAttributes:
      storage.kubernetes.io/csiProvisionerIdentity: 1660085000920-8081-pd.csi.storage.gke.io
    volumeHandle: projects/xxx/zones/us-central1-c/disks/pvc-c9a44c07-cffa-4cd8-b92b-15bac9a9b984
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.gke.io/zone
          operator: In
          values:
          - us-central1-c
  persistentVolumeReclaimPolicy: Delete
  storageClassName: standard-rwo
  volumeMode: Filesystem
status:
  phase: Bound

Si no has sustituido la clase de almacenamiento standard-rwo, este PersistentVolume se basa en un disco persistente de Compute Engine nuevo y vacío.

Eliminar almacenamiento persistente

De forma predeterminada, al eliminar un objeto PersistentVolumeClaim de volúmenes aprovisionados dinámicamente, como los discos persistentes de Compute Engine, se eliminan tanto el objeto PersistentVolume como el disco subyacente. Este comportamiento se controla mediante la política de recuperación de StorageClass y PersistentVolume, que puede configurarse con el valor predeterminado Delete o con Retain. Para obtener más información, consulta la documentación de Kubernetes sobre Reclaiming (Recuperación).

Para evitar o mitigar la pérdida de datos al eliminar el almacenamiento persistente, te recomendamos que habilites Backup for GKE y que programes copias de seguridad periódicas de tu clúster de GKE, incluidas las cargas de trabajo implementadas y sus datos.

Gestionar el almacenamiento persistente durante la eliminación de clústeres

Cuando se elimina un clúster de GKE, GKE conserva los recursos PersistentVolumeDelete o Retain.

Para quitar recursos de PersistentVolume al eliminar un clúster, puedes eliminar manualmente el espacio de nombres de los recursos de PersistentVolumeClaim, lo que activará la eliminación de los objetos de PersistentVolume con la política de Delete. También puedes eliminar recursos PersistentVolumeClaim concretos. Sin embargo, GKE no espera a que se completen estas actividades de eliminación antes de empezar a eliminar el clúster. Por lo tanto, si eliminas un espacio de nombres y, a continuación, eliminas el clúster, es posible que no se eliminen los recursos PersistentVolume con políticas Delete.

Después de eliminar un clúster, puedes ver los recursos PersistentVolume restantes en la consola Google Cloud .

Para ver los recursos que no se utilizan, como los recursos PersistentVolume, puedes consultar las recomendaciones de recursos inactivos.

Modos de acceso

Los recursos PersistentVolume admiten los siguientes modos de acceso:

  • ReadWriteOnce: el volumen puede montarse como de lectura y escritura en un solo nodo.
  • ReadOnlyMany: muchos nodos pueden montar el volumen en modo de solo lectura.
  • ReadWriteMany: el volumen se puede montar como de lectura y escritura en muchos nodos. Los recursos de PersistentVolume que se basan en discos persistentes de Compute Engine no admiten este modo de acceso.
  • ReadWriteOncePod: el volumen solo puede montarse como lectura y escritura en un solo pod.

Usar discos persistentes de Compute Engine como ReadOnlyMany

ReadWriteOnce es el caso práctico más habitual de los discos persistentes y funciona como modo de acceso predeterminado para la mayoría de las aplicaciones. Los discos persistentes de Compute Engine también admiten el modo ReadOnlyMany, de forma que muchas aplicaciones o muchas réplicas de la misma aplicación pueden usar el mismo disco al mismo tiempo. Un ejemplo de caso práctico es servir contenido estático en varias réplicas.

Para obtener instrucciones, consulta el artículo Usar discos persistentes con varios lectores.

Usar discos persistentes preexistentes como PersistentVolumes

Los recursos PersistentVolume aprovisionados dinámicamente están vacíos cuando se crean. Si tienes un disco persistente de Compute Engine con datos, puedes introducirlo en tu clúster creando manualmente un recurso PersistentVolume correspondiente. El disco persistente debe estar en la misma zona que los nodos del clúster.

Consulta este ejemplo de cómo crear un volumen persistente respaldado por un disco persistente preexistente.

Despliegues y StatefulSets

Puedes usar plantillas PersistentVolumeClaim o VolumeClaim en controladores de nivel superior, como Deployments o StatefulSets, respectivamente.

Las implementaciones se han diseñado para aplicaciones sin estado, por lo que todas las réplicas de una implementación comparten el mismo PersistentVolumeClaim. Como los pods de réplica creados son idénticos entre sí, solo los volúmenes con el modo ReadWriteMany pueden funcionar en esta configuración.

Tampoco se recomiendan las implementaciones con una réplica que use un volumen ReadWriteOnce. Esto se debe a que la estrategia de implementación predeterminada crea un segundo pod antes de eliminar el primer pod en una recreación. Es posible que la implementación falle por un interbloqueo, ya que el segundo pod no se puede iniciar porque el volumen ReadWriteOnce ya está en uso y el primer pod no se eliminará porque el segundo aún no se ha iniciado. En su lugar, usa un StatefulSet con volúmenes ReadWriteOnce.

StatefulSets es el método recomendado para implementar aplicaciones con estado que requieren un volumen único por réplica. Si usas StatefulSets con plantillas PersistentVolumeClaim, puedes tener aplicaciones que se escalen automáticamente con PersistentVolumeClaims únicos asociados a cada réplica de Pod.

Discos persistentes regionales

Los discos persistentes regionales son recursos multizonales que replican datos entre dos zonas de la misma región y se pueden usar de forma similar a los discos persistentes zonales. En caso de interrupción zonal o si los nodos de un clúster de una zona no se pueden programar, Kubernetes puede conmutar por error las cargas de trabajo a otra zona mediante el volumen. Puedes usar discos persistentes regionales para crear soluciones de alta disponibilidad para cargas de trabajo con estado en GKE. Debes asegurarte de que tanto la zona principal como la de conmutación por error tengan suficiente capacidad de recursos para ejecutar la carga de trabajo.

Los discos persistentes SSD regionales son una opción para aplicaciones como las bases de datos, que requieren tanto alta disponibilidad como alto rendimiento. Para obtener más información, consulta la comparación del rendimiento del almacenamiento en bloque.

Al igual que los discos persistentes zonales, los discos persistentes regionales se pueden aprovisionar dinámicamente según sea necesario o bien el administrador del clúster puede aprovisionarlos manualmente con antelación. Para saber cómo añadir discos persistentes regionales, consulta Aprovisionar discos persistentes regionales.

Zonas de los discos persistentes

Los discos persistentes de zona son recursos de zona y los discos persistentes regionales son recursos multizonales. Cuando añades almacenamiento persistente a tu clúster, a menos que se especifique una zona, GKE asigna el disco a una sola zona. GKE elige la zona de forma aleatoria. Una vez que se aprovisiona un disco persistente, todos los pods que hagan referencia al disco se programan en la misma zona que el disco persistente. Sin embargo, los pods o las implementaciones no reconocen de forma inherente la zona de los discos persistentes preexistentes. Para asegurarse de que los pods se programan correctamente con discos persistentes preexistentes, utilice métodos de colocación zonal, como nodeAffinity, en las especificaciones de su pod o de su implementación para orientarlos a las zonas adecuadas.

Modo de vinculación de volúmenes WaitForFirstConsumer

Si aprovisionas dinámicamente un disco persistente en tu clúster, te recomendamos que definas el WaitForFirstConsumer modo de enlace de volumen en tu StorageClass. Esta opción indica a Kubernetes que aprovisione un disco persistente en la misma zona en la que se programa el pod. Respeta las restricciones de programación de pods, como la antiafinidad y los selectores de nodos. La antiafinidad de zonas permite que los pods de StatefulSet se distribuyan entre zonas junto con los discos correspondientes.

A continuación, se muestra un ejemplo de StorageClass para aprovisionar discos persistentes de zona que define WaitForFirstConsumer:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-balanced
  csi.storage.k8s.io/fstype: ext4
volumeBindingMode: WaitForFirstConsumer

Para ver un ejemplo de uso de discos persistentes regionales, consulta Aprovisionar discos persistentes regionales.

Siguientes pasos