StatefulSet

En esta página se describen los objetos StatefulSet de Kubernetes y su uso en Google Kubernetes Engine.

¿Qué es un StatefulSet?

Los StatefulSets representan un conjunto de pods con identidades únicas y persistentes, y nombres de host estables que GKE conserva sin importar dónde están programados. La información de estado y otros datos resilientes de cualquier pod del StatefulSet se conservan en el almacenamiento del disco persistente asociado al StatefulSet.

Los StatefulSets usan un índice ordinal para identificar y organizar sus pods. De forma predeterminada, los pods del StatefulSet se implementan en orden secuencial y finalizan en orden ordinal inverso. Por ejemplo, un StatefulSet denominado web tiene sus propios pods llamados web-0, web-1 y web-2; cuando se cambia la especificación del pod web, sus pods se detienen con facilidad y se vuelven a crear de forma ordenada. En este ejemplo, web-2 finaliza primero, luego web-1 y así de forma sucesiva. Como alternativa, puedes especificar el campo podManagementPolicy: Parallel para que StatefulSet inicie o finalice todos sus pods en paralelo, en lugar de esperar a que estén en ejecución y listos o que finalicen antes del comienzo o finalización de otro pod.

Los StatefulSets usan una plantilla de pod que contiene una especificación para sus pods. La especificación del pod determina cómo debe verse cada pod: qué aplicaciones se deben ejecutar en sus contenedores, qué volúmenes debe activar, sus etiquetas y selectores, y demás.

Patrones de uso

Los StatefulSets están diseñados para implementar aplicaciones con estado y aplicaciones agrupadas en clústeres que guardan datos en almacenamiento continuo, como los discos persistentes de Google Compute Engine. Los StatefulSets son adecuados para implementar Kafka, MySQL, Redis, ZooKeeper y otras aplicaciones que necesitan identidades exclusivas y persistentes, así como nombres de host estables. Para las aplicaciones sin estado, debes usar implementaciones.

Crea StatefulSets

Puedes crear un StatefulSet con kubectl apply.

Una vez creado, el StatefulSet se asegura de que la cantidad deseada de pods esté en ejecución y disponible en todo momento. El StatefulSet reemplaza de forma automática los pods que fallan o que son expulsados de sus nodos, y automáticamente asocia nuevos pods con los recursos de almacenamiento, las solicitudes y límites de recursos y otras opciones de configuración definidas en la especificación del pod del StatefulSet.

El siguiente es un ejemplo de un archivo de manifiesto de servicio y StatefulSet:

apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      selector:
        matchLabels:
          app: nginx # Label selector that determines which Pods belong to the StatefulSet
                     # Must match spec: template: metadata: labels
      serviceName: "nginx"
      replicas: 3
      template:
        metadata:
          labels:
            app: nginx # Pod template's label selector
        spec:
          terminationGracePeriodSeconds: 10
          containers:
          - name: nginx
            image: gcr.io/google_containers/nginx-slim:0.8
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
        spec:
          accessModes: [ "ReadWriteOnce" ]
          resources:
            requests:
              storage: 1Gi

En este ejemplo se dan las situaciones siguientes:

  • Se crea un objeto de servicio llamado nginx, indicado por el campo metadata: name. El servicio se orienta a una app llamada nginx, indicada por labels: app: nginx y selector: app: nginx. El servicio expone el puerto 80 y le otorga el nombre web. Este servicio controla el dominio de red para dirigir el tráfico de Internet a la aplicación en contenedores que fue implementada por el StatefulSet.
  • Se crea un StatefulSet denominado web con tres pods replicados (replicas: 3).
  • La plantilla de pod (spec: template) indica que los pods se etiquetan como app: nginx.
  • La especificación del pod (template: spec) indica que los pods del StatefulSet ejecutan un contenedor, nginx, que ejecuta la imagen nginx-slim en la versión 0.8. La imagen del contenedor se aloja en Container Registry.
  • La especificación del pod usa el puerto web que abrió el servicio.
  • template: spec: volumeMounts especifica un mountPath, que se denomina www. La ruta mountPath es donde se debe activar un volumen de almacenamiento dentro del contenedor.
  • StatefulSet aprovisiona un PersistentVolumeClaim, www, con 1 GB de almacenamiento proporcionado.

A modo de resumen, la especificación del pod contiene las instrucciones siguientes:

  • Etiqueta cada pod como app: nginx.
  • En cada pod, ejecuta un contenedor llamado nginx.
  • Ejecuta la imagen nginx-slim en la versión 0.8.
  • Haz que los pods usen el puerto 80.
  • Guarda los datos en la ruta de activación.

Para obtener más información sobre las opciones de configuración del StatefulSet, consulta la referencia de la API del StatefulSet.

Actualiza los StatefulSets

Puedes actualizar un StatefulSet si aplicas cambios en la especificación de su pod, que incluye sus volúmenes y sus imágenes de contenedor. También puedes actualizar las etiquetas, las anotaciones y los límites y solicitudes de recursos del objeto. Para actualizar un StatefulSet, puedes usar kubectl, la API de Kubernetes o el menú Cargas de trabajo de GKE en Google Cloud Console.

Para decidir cómo manejar las actualizaciones, los StatefulSets usan una estrategia de actualización definida en spec: updateStrategy. Hay dos estrategias, OnDelete y RollingUpdate:

  • OnDelete no borra ni vuelve a crear de forma automática los pods cuando se cambia la configuración del objeto. En su lugar, debes borrar de forma manual los pods antiguos para que el controlador cree pods actualizados.
  • RollingUpdate borra y vuelve a crear los pods de forma automática cuando se cambia la configuración del objeto. Los pods nuevos deben estar en los estados En ejecución y Listos antes de que se borren sus antecesores. Con esta estrategia, cambiar la especificación del pod activa automáticamente un lanzamiento. Esta es la estrategia de actualización predeterminada para los StatefulSets.

Los StatefulSets actualizan los pods en orden inverso con respecto a su ordinal. Puedes supervisar las actualizaciones de lanzamiento si ejecutas el siguiente comando:

kubectl rollout status statefulset [STATEFULSET_NAME]

Realiza una partición de las actualizaciones progresivas

Puedes realizar particiones de las actualizaciones progresivas para habilitar una actualización por etapas, lanzar una compilación Canary o realizar un lanzamiento por fases.

Cuando haces una partición de una actualización, se actualizan todos los pods con un ordinal mayor o igual al valor de partición cuando actualizas la especificación del pod del StatefulSet. Los pods con un ordinal menor al valor de partición no se actualizan y, aunque se borren, se vuelven a crear según la versión anterior de la especificación. Si el valor de partición es mayor que el número de réplicas, las actualizaciones no se propagan a los pods.

Próximos pasos