Aprovisiona y usa SSD locales mixtas para el almacenamiento en bloque sin procesar y efímero

En este documento, se muestra cómo aprovisionar y particionar SSD locales en Google Kubernetes Engine (GKE) para admitir cargas de trabajo que requieren un sistema de archivos de almacenamiento efímero estándar y un almacenamiento en bloque sin procesar sin formato en el mismo nodo.

Usa esta configuración para aplicaciones con estado y bases de datos altamente optimizadas. Estas cargas de trabajo suelen requerir acceso directo al disco para aumentar el rendimiento, pero también necesitan almacenamiento de archivos efímero estándar para sidecars, registros o cachés de contenedores. Si usas la capacidad de SSD local mixta, puedes reducir la sobrecarga de administración del clúster y maximizar el uso del hardware, ya que no necesitas dedicar nodos separados ni discos completos exclusivamente a la infraestructura de bloques sin procesar.

Cuando creas un clúster o un grupo de nodos con capacidad de SSD local mixta, GKE particiona cada SSD local conectado físicamente de la siguiente manera:

  • Almacenamiento efímero: La capacidad efímera solicitada se divide de manera equitativa entre las SSD locales y se combina para proporcionar el almacenamiento de archivos efímero estándar del nodo. Cuando la capacidad efímera se particiona en varios SSD locales, el almacenamiento se combina en un arreglo RAID-0. Puedes acceder al almacenamiento efímero con volúmenes emptyDir estándar.
  • Almacenamiento en bloques sin procesar: El resto de la capacidad física de cada disco se presenta al nodo como dispositivos de almacenamiento en bloques sin procesar distintos y sin formato.

Este documento está dirigido a administradores y operadores de plataformas, y a DevOps que deseen optimizar el uso del hardware y el rendimiento del almacenamiento en GKE para cargas de trabajo especializadas.

Consideraciones

Además de las limitaciones de SSD locales de Compute Engine, revisa las siguientes consideraciones específicas de GKE antes de configurar modos de SSD locales mixtos:

  • Compatibilidad con Autopilot: Los clústeres de GKE Autopilot no admiten el almacenamiento efímero y de bloques sin procesar mixto. Para aprender a usar SSDs locales para el almacenamiento efímero estándar en Autopilot, consulta SSDs locales en clústeres de Autopilot.
  • ComputeClasses personalizadas: las ComputeClasses personalizadas no admiten la configuración de SSD locales mixtas.
  • Sistema operativo: El modo de SSD local mixto solo se admite en imágenes de nodos de Linux (Container-Optimized OS y Ubuntu). Los grupos de nodos de Windows Server no son compatibles.
  • Eventos de mantenimiento: No recomendamos usar SSD locales como almacenamiento en bloque sin procesar para VMs Z3 o Z4D optimizadas para almacenamiento. Es posible que los datos de estas VMs no sobrevivan a los eventos de mantenimiento. Para obtener más información, consulta Aprovisiona y usa el almacenamiento en bloque sin procesar respaldado por SSD locales.
  • E/S compartida: Debido a que tanto el arreglo RAID-0 efímero como las particiones de bloques sin procesar de destino dependen de las mismas SSD físicas subyacentes, las operaciones intensivas en una partición lógica pueden afectar la capacidad de procesamiento de la otra. Para obtener información sobre los límites máximos de capacidad de procesamiento, consulta Rendimiento de SSD locales.
  • Precios: Cuando usas modos mixtos para particionar la capacidad de SSD local, pagas por la capacidad física total de SSD local conectada al nodo, independientemente de cuánta capacidad se asigne al almacenamiento efímero en comparación con el almacenamiento en bloque sin procesar. Para obtener más información, consulta Precios de SSD locales.
  • Configuración manual: Para usar el almacenamiento en bloque sin procesar respaldado por SSD local, debes configurar los dispositivos de forma manual, ya que GKE no formatea ni activa las particiones de bloques sin procesar. También eres responsable de administrar la capacidad de los nodos y controlar las posibles interrupciones de las cargas de trabajo ubicadas en el mismo lugar. El uso de un objeto PersistentVolume local proporciona una programación de Pods integrada. Si tus cargas de trabajo no requieren que los datos persistan durante el ciclo de vida del Pod o si no tienen necesidades de rendimiento especializadas, usa la configuración de SSD local completamente efímera en su lugar. La configuración completamente efímera es adecuada para la mayoría de los casos de uso.
  • Intercambio de memoria de nodo: Puedes combinar la capacidad de SSD local mixta con el intercambio de memoria de nodo usando el perfil de disco de arranque o el perfil de SSD local efímero. El perfil de SSD local dedicado no es compatible con la capacidad de SSD local mixta. Para obtener más información, consulta Intercambio de memoria de nodo con capacidad mixta de SSD local.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Para usar Google Cloud CLI en esta tarea, instala y, luego, inicializa la gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando gcloud components update para obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos de este documento.

Para usar esta función, los nodos de GKE deben ejecutar la versión 1.37.0-gke.3570000 o una posterior.

Roles obligatorios

Para obtener los permisos que necesitas para crear clústeres y grupos de nodos con capacidad de SSD local mixta, pídele a tu administrador que te otorgue el rol de IAM de administrador de Kubernetes Engine (roles/container.admin) en tu proyecto. Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

También puedes obtener los permisos necesarios a través de roles personalizados o cualquier otro rol predefinido.

Crea un clúster o un grupo de nodos con almacenamiento de SSD local mixto

Puedes asignar capacidad efímera y reservar particiones de bloques sin procesar con la propiedad capacity de la marca --ephemeral-storage-local-ssd.

Crea tu clúster o grupo de nodos especificando el subcampo capacity con la marca --ephemeral-storage-local-ssd.

Si tu tipo de máquina permite una cantidad configurable de SSD locales, también debes especificar el subcampo count. Si tu tipo de máquina tiene una cantidad fija de SSD locales, por ejemplo, tipos -lssd, puedes omitir el subcampo count porque GKE calcula automáticamente el recuento de discos en función de la forma de la VM.

Crea un clúster con almacenamiento de SSD local mixto

Para crear un clúster nuevo, usa el comando gcloud container clusters create. Esta configuración se aplica solo al grupo de nodos predeterminado. Si los grupos de nodos posteriores necesitan almacenamiento mixto de SSD locales, especifica la marca --ephemeral-storage-local-ssd cuando crees el grupo de nodos. La cantidad máxima de discos que puedes conectar varía según el tipo de máquina y la región.

Si la versión de tu clúster es anterior a 1.37.0-gke.3570000, agrega una de las siguientes marcas a los siguientes comandos de creación de clústeres:

  • La marca --cluster-version=<var>VERSION</var> con <var>VERSION</var> establecida en 1.37.0-gke.3570000 o una versión posterior, o bien
  • La marca --release-channel=rapid

Para los tipos de máquinas con un recuento de SSD locales configurable, ejecuta lo siguiente:

gcloud container clusters create CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --ephemeral-storage-local-ssd count=NUMBER_OF_DISKS,capacity=CAPACITY

En el caso de los tipos de máquinas con un recuento fijo de SSD locales, ejecuta lo siguiente:

gcloud container clusters create CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --ephemeral-storage-local-ssd capacity=CAPACITY

Reemplaza lo siguiente:

  • CLUSTER_NAME: Es el nombre del clúster que deseas crear.
  • MACHINE_TYPE: Es el tipo de máquina que se usará. Para obtener una lista de los tipos de máquinas compatibles, consulta Compatibilidad con series de máquinas. No puedes usar SSD locales con el tipo de máquina e2-medium predeterminado, ya que los tipos de máquinas de núcleo compartido no los admiten.
  • NUMBER_OF_DISKS: En el caso de los tipos de máquinas con un recuento de SSD locales configurable, es la cantidad de discos SSD locales que se aprovisionarán en cada nodo.
  • CAPACITY: Es la capacidad total de SSD locales que se formatearán para el almacenamiento efímero. Este valor debe ser mayor que 0 y estrictamente menor que la capacidad física total del SSD local (recuento de discos × tamaño por disco), por ejemplo, 200GB. Ten en cuenta lo siguiente:

    • El valor no se puede cambiar después de crear el clúster.
    • GKE reserva parte de esta capacidad para el uso del sistema, por lo que el almacenamiento efímero asignable es inferior a CAPACITY. Para obtener más información, consulta Reserva de almacenamiento efímero local.

Crea un grupo de nodos con almacenamiento de SSD local mixto

Para agregar un grupo de nodos a un clúster existente, usa el comando gcloud container node-pools create.

Si la versión de tu grupo de nodos es anterior a 1.37.0-gke.3570000, debes hacer lo siguiente:

  • Agrega la marca --node-version=<var>VERSION</var> a los siguientes comandos de creación de grupos de nodos, con <var>VERSION</var> configurado como 1.37.0-gke.3570000 o una versión posterior.
  • Asegúrate de que el plano de control del clúster esté en la versión 1.37.0-gke.3570000 o una posterior.

Para los tipos de máquinas con un recuento de SSD locales configurable, ejecuta lo siguiente:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --ephemeral-storage-local-ssd count=NUMBER_OF_DISKS,capacity=CAPACITY

En el caso de los tipos de máquinas con un recuento fijo de SSD locales, ejecuta lo siguiente:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --ephemeral-storage-local-ssd capacity=CAPACITY

Reemplaza lo siguiente:

  • POOL_NAME: Es el nombre del grupo de nodos nuevo que deseas crear.
  • CLUSTER_NAME: el nombre del clúster
  • MACHINE_TYPE: Es el tipo de máquina que se usará. Para obtener una lista de los tipos de máquinas compatibles, consulta Compatibilidad con series de máquinas. No puedes usar SSD locales con el tipo de máquina e2-medium predeterminado, ya que los tipos de máquinas de núcleo compartido no los admiten.
  • NUMBER_OF_DISKS: En el caso de los tipos de máquinas con un recuento de SSD locales configurable, es la cantidad de discos SSD locales que se aprovisionarán en cada nodo.
  • CAPACITY: Es la capacidad total de SSD locales que se formatearán para el almacenamiento efímero. Este valor debe ser mayor que 0 y estrictamente menor que la capacidad física total del SSD local (recuento de discos × tamaño por disco), por ejemplo, 200GB. Ten en cuenta lo siguiente:

    • El valor no se puede cambiar después de crear el grupo de nodos.
    • GKE reserva parte de esta capacidad para el uso del sistema, por lo que el almacenamiento efímero asignable es inferior a CAPACITY. Para obtener más información, consulta Reserva de almacenamiento efímero local.

Verifica las etiquetas de los nodos

Después del aprovisionamiento, para verificar que los nodos tengan las etiquetas correctas para el almacenamiento en bloque efímero y sin procesar, ejecuta el siguiente comando:

kubectl describe node NODE_NAME

El resultado debería contener las siguientes etiquetas de nodo:

  • cloud.google.com/gke-ephemeral-storage-local-ssd: "true"
  • cloud.google.com/gke-local-nvme-ssd-partition: "true"

Accede a la capacidad efímera

Accede a tu almacenamiento efímero reservado a través de volúmenes emptyDir exactamente como lo harías con cualquier otro volumen efímero de GKE.

Accede a la capacidad de bloques sin procesar

Para acceder a tu capacidad de bloque sin procesar, crea un objeto StorageClass, aprovisiona un objeto PersistentVolume local y reclámalo con un objeto PersistentVolumeClaim.

Crea un StorageClass

Debido a que aprovisionas tus objetos PersistentVolume sin el aprovisionador estático de la comunidad, te recomendamos crear un objeto StorageClass con el campo volumeBindingMode: WaitForFirstConsumer. Esto demora la vinculación hasta la programación del Pod, lo que garantiza que Kubernetes elija un SSD local de un nodo adecuado que pueda ejecutar el Pod.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: "local-storage"
provisioner: "kubernetes.io/no-provisioner"
volumeBindingMode: "WaitForFirstConsumer"

Crea el PersistentVolume

Los objetos PersistentVolume locales tienen limitaciones importantes en relación con las actualizaciones, el escalamiento y el ajuste de escala automático de los clústeres. Antes de crear tus volúmenes, revisa las limitaciones de los PersistentVolumes locales para comprender cómo los eventos del ciclo de vida afectan tus datos.

Para crear el objeto PersistentVolume, completa los siguientes pasos para encontrar la ruta del vínculo simbólico a la partición de SSD local, determinar su capacidad restante exacta y configurar el manifiesto.

Busca la capacidad de la partición

Ejecuta el siguiente comando en el nodo de destino para encontrar la capacidad exacta del bloque sin procesar que queda para la partición.

kubectl debug node/NODE_NAME -it --image=ubuntu -- \
    sh -c 'ls -l /host/dev/disk/by-id/ | grep partition; lsblk -o NAME,SIZE,TYPE'

Reemplaza NODE_NAME por el nombre del nodo al que está conectada la SSD local.

El resultado muestra la asignación entre los nombres de los dispositivos y los symlinks de las particiones para que puedas verificar qué partición corresponde a cada dispositivo. También se enumeran los dispositivos de almacenamiento en bloques conectados al nodo y sus tamaños.

Por ejemplo, si conectas dos SSD locales al nodo y asignas 200 GB al almacenamiento efímero (capacity=200GB), el resultado es similar al siguiente:

google-local-ssd-partition0 -> /dev/nvme0n1p2
google-local-ssd-partition1 -> /dev/nvme0n2p2
NAME          SIZE TYPE
...
nvme0n1       375G disk
|-nvme0n1p1   100G part
| `-md0     199.9G raid0
`-nvme0n1p2   275G part
nvme0n2       375G disk
|-nvme0n2p1   100G part
| `-md0     199.9G raid0
`-nvme0n2p2   275G part

Toma nota de la asignación entre el vínculo simbólico google-local-ssd-partition y el nombre del dispositivo subyacente, así como del tamaño de esa partición. Usa el tamaño como PARTITION_SIZE y la ruta de acceso del symlink como LOCAL_SSD_SYMLINK_PATH en el manifiesto de PersistentVolume.

Por ejemplo, en el resultado anterior, el vínculo simbólico /dev/disk/by-id/google-local-ssd-partition0 apunta a la partición nvme0n1p2, que tiene un tamaño de 275G.

El comando kubectl debug deja un Pod temporal en ejecución en el espacio de nombres predeterminado. Para evitar que consuma recursos, borra este Pod con el siguiente comando:

kubectl delete pod DEBUG_POD_NAME

Reemplaza DEBUG_POD_NAME por el nombre del Pod que creó el comando kubectl debug, que se imprime cuando ejecutas el comando.

Configura el manifiesto de PersistentVolume

Configura el manifiesto del volumen con el tamaño de la partición que encontraste. El campo nodeAffinity es obligatorio para los volúmenes locales. Esto ayuda a garantizar que Kubernetes programe los Pods que reclaman este volumen en el nodo específico al que está conectada físicamente la SSD local. En el siguiente ejemplo, se muestra un manifiesto para una partición de SSD local de bloque sin procesar:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: "example-local-pv"
spec:
  capacity:
    storage: PARTITION_SIZE
  accessModes:
  - "ReadWriteOnce"
  volumeMode: "Block"
  persistentVolumeReclaimPolicy: "Retain"
  storageClassName: "local-storage"
  local:
    path: "LOCAL_SSD_SYMLINK_PATH"
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: "kubernetes.io/hostname"
          operator: "In"
          values:
          - "NODE_NAME"

Reemplaza lo siguiente:

  • PARTITION_SIZE: Es la capacidad real restante del bloque sin procesar que encontraste en el primer paso. Usa el sufijo Gi (por ejemplo, 275Gi) para que el valor coincida exactamente con la capacidad de la partición.
  • NODE_NAME: Es el nombre del nodo al que está conectada la SSD local.
  • LOCAL_SSD_SYMLINK_PATH: Es la ruta de acceso del vínculo simbólico a la partición de SSD local sin formato que encontraste en el primer paso. Para cada SSD local conectado al grupo de nodos, el SO host crea un vínculo simbólico para acceder a la capacidad restante del bloque sin procesar. Las rutas de acceso siguen un patrón con índice cero. Por ejemplo, si conectas tres SSD locales, las rutas de acceso de bloques sin procesar para las particiones son las siguientes:
    • /dev/disk/by-id/google-local-ssd-partition0
    • /dev/disk/by-id/google-local-ssd-partition1
    • /dev/disk/by-id/google-local-ssd-partition2

Crea la PersistentVolumeClaim

Crea un objeto PersistentVolumeClaim para reclamar el volumen. La especificación correspondiente se ve de la siguiente manera:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: "example-local-pvc"
spec:
  accessModes:
  - "ReadWriteOnce"
  volumeMode: "Block"
  storageClassName: "local-storage"
  resources:
    requests:
      storage: PARTITION_SIZE

Usa el volumen en un Pod

Puedes usar el objeto PersistentVolume en un Pod haciendo referencia al objeto PersistentVolumeClaim en una especificación de volumeDevices. A continuación, se muestra un manifiesto de Pod de ejemplo que usa la reclamación example-local-pvc:

apiVersion: v1
kind: Pod
metadata:
  name: "example-pod"
spec:
  containers:
  - name: "app"
    image: "ubuntu:22.04"
    command: ["/bin/sh", "-c"]
    args: ["tail -f /dev/null"]
    volumeDevices:
    - name: "raw"
      devicePath: "/dev/xvda"
  volumes:
  - name: "raw"
    persistentVolumeClaim:
      claimName: "example-local-pvc"

Debido a que usas el aprovisionador kubernetes.io/no-provisioner, GKE no limpia automáticamente los volúmenes locales. Si borras el objeto PersistentVolume, debes borrar de forma manual los datos del disco subyacente antes de que se pueda reutilizar de forma segura.

Soluciona problemas

Si deseas obtener instrucciones para solucionar problemas, consulta Soluciona problemas de almacenamiento en GKE.

¿Qué sigue?