Generador K8s StatefulSet

Generador YAML de StatefulSet y Headless Service de Kubernetes

Genere manifiestos de Kubernetes StatefulSet de nivel de producción con Headless Service, plantillas de volumen persistente (volumeClaimTemplates), réplicas y podManagementPolicy.

Ajustes preestablecidos
Configuración de StatefulSet y servicio
Los pods con ordinal >= partition se actualizarán primero (Canary)
Número de pods no disponibles durante el despliegue
:
:
# ============================================================================
# Kubernetes StatefulSet: postgres-ha
# Generated via ToolsAA - 100% Client-Side Stateful Workload Builder
# Headless Network Domain: postgres-ha-headless.database.svc.cluster.local
# Pod Stable FQDN: postgres-ha-[0..2].postgres-ha-headless.database.svc.cluster.local
# ============================================================================
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres-ha
  namespace: database
  labels:
    app: "postgres-ha"
    tier: "database"
    app.kubernetes.io/managed-by: toolsaa
  annotations:
    cluster.toolsaa.com/role: "primary-replica"
spec:
  serviceName: "postgres-ha-headless"
  replicas: 3
  podManagementPolicy: OrderedReady
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0
      maxUnavailable: 1
  revisionHistoryLimit: 10
  minReadySeconds: 10
  persistentVolumeClaimRetentionPolicy:
    whenDeleted: Retain
    whenScaled: Retain
  selector:
    matchLabels:
      app: "postgres-ha"
  template:
    metadata:
      labels:
        app: "postgres-ha"
        tier: "database"
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9187"
    spec:
      serviceAccountName: postgres-sa
      terminationGracePeriodSeconds: 120
      securityContext:
        runAsNonRoot: true
        runAsUser: 999
        runAsGroup: 999
        fsGroup: 999
        fsGroupChangePolicy: "OnRootMismatch"
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values: ["postgres-ha"]
              topologyKey: "kubernetes.io/hostname"
      nodeSelector:
        node-role.kubernetes.io/database: "true"
      containers:
      - name: postgres
        image: postgres:16-alpine
        imagePullPolicy: IfNotPresent
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
        ports:
        - name: postgresql
          containerPort: 5432
          protocol: TCP
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: POSTGRES_DB
          value: "app_production"
        - name: POSTGRES_USER
          value: "postgres"
        - name: PGDATA
          value: "/var/lib/postgresql/data/pgdata"
        resources:
          requests:
            cpu: "500m"
            memory: "1Gi"
          limits:
            cpu: "2000m"
            memory: "4Gi"
        volumeMounts:
        - name: pgdata
          mountPath: "/var/lib/postgresql/data"
        livenessProbe:
          exec:
            command:
            - "pg_isready"
            - "-U"
            - "postgres"
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          exec:
            command:
            - "pg_isready"
            - "-U"
            - "postgres"
            - "-h"
            - "127.0.0.1"
          initialDelaySeconds: 15
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 3
        startupProbe:
          exec:
            command:
            - "pg_isready"
            - "-U"
            - "postgres"
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 15
  volumeClaimTemplates:
  - metadata:
      name: pgdata
      labels:
        app: "postgres-ha"
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "gp3"
      resources:
        requests:
          storage: 50Gi
Réplicas con estadoOrderedReady
3 Pods con estado

Partición: 0 | Estrategia: RollingUpdate

Plantillas de PVCgp3
50Gi / pod (1 plantillas)

Retención: Retain | fsGroup:: 999

Nivel de blindajeNivel de seguridad A+
100 / 100 Preparación

Sondas: 3/3 activas

Generación de manifiestos 100% en el cliente

Sin envíos a servidores externos ni rastreo. Todos los manifiestos de StatefulSet, servicios headless y plantillas PVC se procesan directamente en la memoria del navegador.

Ciclo de vida ordenado e identidad DNS única

Mantiene identidades ordinales únicas, direccionamiento DNS predecible mediante Headless Service, despliegue OrderedReady y plantillas de reclamación de volumen persistente.

Blindaje de seguridad CIS y exportación múltiple

Aplica contextos de seguridad sin root, eliminación de capacidades y genera salidas listas para producción en plantillas Helm, Kustomize y comandos kubectl.

Referencia técnica y guía de arquitectura

Guía del Desarrollador del Generador de YAML de StatefulSet y Headless Service de Kubernetes — Guía de referencia

Genere manifiestos de Kubernetes StatefulSet de nivel de producción con Headless Service, plantillas de volumen persistente (volumeClaimTemplates), réplicas y podManagementPolicy.

Parámetros clave y controles

spec.serviceNamestring

Nombre del Headless Service complementario (clusterIP: None) que gestiona la identidad de red y el enrutamiento DNS SRV para los ordinales de los pods.

Por defecto: Obligatorio
spec.replicasinteger

Número deseado de pods con estado (0 a N-1) creados secuencialmente en orden ascendente.

Por defecto: 3
spec.podManagementPolicyenum (OrderedReady | Parallel)

Política de orden de ciclo de vida. 'OrderedReady' inicia pods uno a uno esperando su estado Ready; 'Parallel' crea o termina todos los pods simultáneamente.

Por defecto: OrderedReady
spec.volumeClaimTemplatesarray of objects

Plantillas de PersistentVolumeClaim para aprovisionar almacenamiento persistente dinámico y exclusivo para cada pod ordinal.

Por defecto: Obligatorio
spec.updateStrategyobject

Estrategia de actualización rodante automatizada con parámetro opcional 'partition' para canary o manual 'OnDelete'.

Por defecto: RollingUpdate

Consejos profesionales y mejores prácticas

Un StatefulSet requiere un Headless

Un StatefulSet requiere un Headless Service con 'clusterIP: None'. CoreDNS registra automáticamente registros A/AAAA y SRV estables con formato '<nombre-pod>.<nombre-servicio>.<namespace>.svc.cluster.local', esencial para bases de datos maestro-réplica y clusters Raft.

Configure

Configure 'spec.updateStrategy.rollingUpdate.partition' igual a réplicas - 1 para probar nuevas versiones de imagen únicamente en el pod con el ordinal más alto (p. ej., statefulset-2) como canary antes de actualizar todo el cluster.

Kubernetes no elimina automáticamente

Kubernetes no elimina automáticamente los PVCs creados por volumeClaimTemplates al reducir réplicas o eliminar el StatefulSet. Al volver a escalar hacia arriba, los nuevos pods se conectan a los mismos volúmenes existentes. En K8s 1.27+, 'persistentVolumeClaimRetentionPolicy' ofrece control granular.

Sistemas de estado distribuido como

Sistemas de estado distribuido como ZooKeeper, Kafka o Cassandra requieren quórum. Defina siempre un PodDisruptionBudget con 'minAvailable: 2' o 'maxUnavailable: 1' para evitar situaciones de split-brain durante drenajes de nodos o mantenimientos del cluster.

Errores comunes y solución de problemas

El pod permanece en estado Pending con 'persistentvolumeclaim unbound'

Ejecute 'kubectl describe pvc <nombre-pvc>'. Verifique que la storageClassName configurada exista en el cluster, que el aprovisionador dinámico CSI esté operativo y que los accessModes (p. ej., ReadWriteOnce) sean compatibles con el storage pool.

La actualización o el escalado del StatefulSet se detiene en un pod ordinal específico

Bajo la política 'OrderedReady', Kubernetes suspende la actualización o escalado si el pod ordinal precedente no supera su readinessProbe. Inspeccione los eventos con 'kubectl describe pod <nombre>' y corrija el endpoint de comprobación de salud de la aplicación.

El descubrimiento entre pods falla con error 'NXDOMAIN' en el nombre de host del Headless Service

Asegúrese de que 'spec.serviceName' en el StatefulSet coincida exactamente con 'metadata.name' del Service. Compruebe que el Service tenga 'clusterIP: None' y que los selectores de etiquetas coincidan en ambos manifiestos.

Preguntas frecuentes (FAQ)

¿Cuál es la diferencia fundamental entre un Deployment y un StatefulSet en Kubernetes?▼

Un Deployment gestiona pods sin estado intercambiables con nombres aleatorios y almacenamiento efímero o compartido. Un StatefulSet proporciona identificadores ordinales únicos y estables (app-0, app-1), orden riguroso de inicio y apagado, almacenamiento persistente exclusivo por réplica y nombres DNS predecibles mediante un Headless Service.

¿Por qué un StatefulSet requiere obligatoriamente un Headless Service ('clusterIP: None')?▼

Los servicios estándar asignan una IP virtual (VIP) única que balancea el tráfico de forma aleatoria entre pods listos. Sin embargo, las bases de datos distribuidas necesitan comunicarse punto a punto con nodos específicos (como primario o réplica). Un Headless Service omite la VIP y crea registros DNS A individuales que apuntan directamente a la IP de cada pod.

¿Qué ocurre con los PersistentVolumeClaims (PVCs) al reducir réplicas o eliminar un StatefulSet?▼

Por defecto, Kubernetes nunca elimina los PVCs generados por volumeClaimTemplates para proteger los datos frente a destrucciones involuntarias. Si el StatefulSet vuelve a escalar, los nuevos pods se vuelven a vincular a sus volúmenes ordinales previos. Los volúmenes obsoletos deben eliminarse manualmente con 'kubectl delete pvc'.

¿Cuándo conviene usar 'podManagementPolicy: Parallel' en lugar de 'OrderedReady'?▼

Utilice 'Parallel' cuando la aplicación gestione por sí misma el descubrimiento y consenso sin depender del arranque en orden secuencial, o cuando requiera escalados rápidos o actualizaciones continuas simultáneas sin esperar las sondas de preparación paso a paso.

¿Cómo funciona el parámetro 'updateStrategy.rollingUpdate.partition'?▼

El parámetro de partición establece un umbral de índice ordinal. Solo los pods con un índice mayor o igual al valor de partition se actualizan. Si configura partition en réplicas - 1, solo se actualizará el último pod para validación canary. Reducir la partición a 0 propaga el cambio a todos los pods.

Herramientas y utilidades relacionadas

Todas las herramientas →