Cerrábamos la lección anterior con el mapa de piezas del clúster: apiserver, etcd, scheduler, controladores, kubelet. Esas son las piezas que ejecutan Kubernetes. Ahora toca el otro vocabulario, el que tú vas a escribir todos los días: pods, Deployments, Services, ConfigMaps, PVCs, namespaces. Es un vocabulario grande y la tentación es aprenderlo como un diccionario, término a término, lo cual es una mala idea: los conceptos de Kubernetes no son independientes, forman familias con relaciones jerárquicas claras. Esta lección te da ese mapa mental completo, de modo que cuando en el módulo 5 aparezca un PersistentVolumeClaim ya sepas de antemano dónde encaja y con quién habla. No vamos a desarrollar el uso práctico de cada objeto —cada uno tiene su lección propia— sino a colocarlos en el mapa.

Contenido

  1. La base: recurso, objeto y API
  2. Clúster y nodo
  3. El pod: la unidad mínima
  4. La familia de cargas de trabajo
  5. La familia de red
  6. La familia de configuración
  7. La familia de almacenamiento
  8. Organización: namespaces, etiquetas, selectores y anotaciones
  9. Controladores, operadores y CRDs
  10. Tabla maestra de conceptos

  1. La base: recurso, objeto y API

Antes de los nombres concretos, tres términos que se confunden constantemente:

Término Definición Ejemplo
Recurso (resource) Un tipo de entidad que la API sabe manejar, con su endpoint pods, deployments, services
Objeto (object) Una instancia concreta de un recurso, guardada en etcd El pod llamado api-reservas-7d9f en rutas-norte-dev
Manifiesto (manifest) El fichero YAML que describe el objeto que quieres k8s/base/api-reservas.yaml

Y la regla que gobierna todo el sistema, que ya vimos en la arquitectura:

  • spec: lo que tú quieres. Lo escribes tú.
  • status: lo que realmente hay. Lo escribe el clúster.

Todo lo que existe en Kubernetes —una aplicación, una IP virtual, una contraseña, un disco, un permiso— es un objeto con spec y status almacenado en la misma API. Esa uniformidad es lo que hace que un único comando, kubectl get, sirva para todo. El detalle de la anatomía de un objeto lo trabajaremos en Objetos, Manifiestos YAML y el Modelo Declarativo.

  1. Clúster y nodo

  • Clúster: el conjunto completo. Un plano de control más un grupo de nodos que se presentan como un único sistema. Cuando dices "despliego en el clúster", estás diciendo "entrego mi intención a la API y que el sistema decida dónde".
  • Nodo (node): una máquina —física o virtual— que ejecuta cargas. Es también un objeto de la API: kubectl get nodes te lo demuestra. Tiene capacidad (CPU, memoria, pods máximos), etiquetas (zona, tipo de disco) y condiciones (Ready, MemoryPressure).

Rutas Norte usará un clúster de prácticas de un solo nodo (minikube) durante el curso, y hablaremos de clústeres multinodo cuando lleguemos a la planificación (módulo 6) y a la alta disponibilidad (módulo 9).

  1. El pod: la unidad mínima

Este es el concepto fundacional, y el que más sorprende viniendo de Docker.

Kubernetes no ejecuta contenedores: ejecuta pods. Un pod es un grupo de uno o más contenedores que comparten red y almacenamiento y se programan siempre juntos en el mismo nodo.

Qué comparten los contenedores de un mismo pod:

  • Una única IP. Se ven entre ellos por localhost y no pueden usar el mismo puerto.
  • Los volúmenes declarados en el pod.
  • El ciclo de vida: nacen juntos, mueren juntos, se mueven juntos.

En la inmensa mayoría de los casos —y en casi todos los de Rutas Norte— un pod contiene un solo contenedor. Los pods multicontenedor se reservan para patrones concretos (sidecar, init container, adaptador) que se estudian en el módulo 6.

Dos propiedades del pod que hay que interiorizar desde el primer día:

  1. Es efímero. Un pod no se "repara" ni se mueve: si su nodo cae, ese pod se da por perdido y se crea otro nuevo, con otro nombre y otra IP. Nunca dependas del nombre ni de la IP de un pod.
  2. Rara vez se crea a mano. Un pod suelto no tiene quien lo resucite. Salvo para pruebas puntuales, siempre se crea a través de un controlador de carga de trabajo. En la lección El Proyecto del Curso crearás uno suelto justo para experimentar esa fragilidad en primera persona.

Fragmento mínimo, solo para ver la forma:

apiVersion: v1
kind: Pod
metadata:
  name: api-reservas
spec:
  containers:
    - name: api
      image: registry.rutasnorte.example/api-reservas:2.4.0

  1. La familia de cargas de trabajo

Todos estos objetos tienen el mismo propósito: crear y mantener pods. Se diferencian en cómo y cuándo.

4.1. La jerarquía esencial

flowchart TD
    D["Deployment<br/>gestiona versiones"] --> RS["ReplicaSet<br/>garantiza N réplicas"]
    RS --> P1["Pod"]
    RS --> P2["Pod"]
    RS --> P3["Pod"]
    P1 --> C1["contenedor"]
    P2 --> C2["contenedor"]
    P3 --> C3["contenedor"]

Léelo así, de abajo arriba:

  • El contenedor ejecuta tu proceso.
  • El pod envuelve uno o varios contenedores y es la unidad que se programa en un nodo.
  • El ReplicaSet vigila que haya exactamente N pods iguales; si falta uno, lo crea.
  • El Deployment gestiona ReplicaSets para poder cambiar de versión de forma progresiva: crea un ReplicaSet nuevo con la imagen nueva y va reduciendo el viejo.

Por eso tú escribes Deployments, casi nunca ReplicaSets ni Pods. El ReplicaSet existe, lo verás con kubectl get rs, pero es un intermediario que el Deployment gestiona por ti.

4.2. Las seis cargas de trabajo

Objeto Para qué sirve Rasgo distintivo En Rutas Norte
Deployment Aplicaciones sin estado, con réplicas intercambiables Actualización progresiva y rollback tienda-web, api-reservas, worker-notificaciones
ReplicaSet Mantener N copias idénticas Lo gestiona el Deployment; no se escribe a mano Creado automáticamente por los anteriores
StatefulSet Aplicaciones con estado e identidad estable Nombres fijos (-0, -1), disco propio por réplica, arranque ordenado postgres-reservas
DaemonSet Una copia en cada nodo Se ajusta solo al añadir o quitar nodos Agentes de logs y métricas (módulo 7)
Job Tarea que se ejecuta hasta completarse Termina; puede reintentar y paralelizar Migraciones de esquema de la base de datos
CronJob Job lanzado según un horario Sintaxis cron informes-ocupacion, nocturno

La pregunta clave para elegir es siempre la misma: ¿mis réplicas son intercambiables? Si cualquiera puede atender cualquier petición y no guardan nada en disco, es un Deployment. Si cada réplica tiene identidad y datos propios, es un StatefulSet.

  1. La familia de red

Los pods son efímeros y sus IPs cambian. La familia de red existe para dar estabilidad y accesibilidad encima de ese caos.

  • Service: una IP virtual y un nombre DNS estables que reparten tráfico entre un conjunto de pods, elegidos por etiquetas. Es la pieza que hace posible que tienda-web llame a api-reservas por su nombre sin conocer ninguna IP. Tipos principales: ClusterIP (interno, el habitual), NodePort y LoadBalancer (exposición externa), y ExternalName.
  • Ingress: reglas HTTP/HTTPS que enrutan por dominio y ruta hacia distintos Services, con terminación TLS. Es lo que permitirá publicar www.rutasnorte.example y api.rutasnorte.example sobre una única IP pública. Un Ingress no hace nada por sí solo: necesita un Ingress Controller instalado en el clúster (NGINX, Traefik…).
  • NetworkPolicy: cortafuegos a nivel de pod. Por defecto, en Kubernetes todos los pods pueden hablar con todos. Una NetworkPolicy restringe eso: por ejemplo, que solo api-reservas pueda conectarse a postgres-reservas. Dado que esa base de datos guarda datos personales, para Rutas Norte no es opcional.
  • EndpointSlice: la lista, mantenida automáticamente, de las IPs de pods sanos que hay detrás de un Service. No se escribe a mano, pero es lo primero que se mira cuando un Service "no llega a ningún sitio".
flowchart LR
    U["Usuario<br/>www.rutasnorte.example"] --> ING["Ingress"]
    ING --> SVC1["Service<br/>tienda-web"]
    ING --> SVC2["Service<br/>api-reservas"]
    SVC1 --> PA["Pod tienda-web"]
    SVC1 --> PB["Pod tienda-web"]
    SVC2 --> PC["Pod api-reservas"]
    SVC2 --> PD["Pod api-reservas"]
    PC --> SVC3["Service<br/>postgres-reservas"]
    PD --> SVC3
    SVC3 --> PG["Pod postgres-reservas"]

  1. La familia de configuración

La regla de oro: la imagen contiene el código; nunca la configuración ni las credenciales. La misma imagen api-reservas:2.4.0 debe poder ejecutarse en rutas-norte-dev y en rutas-norte-pro sin reconstruirse.

Objeto Contenido Cómo llega al contenedor Advertencia
ConfigMap Configuración no sensible: URLs, tamaños de caché, ficheros .conf Variables de entorno o fichero montado No cifra nada; no metas contraseñas
Secret Datos sensibles: contraseñas, tokens, certificados TLS Igual que el ConfigMap Va codificado en base64, que no es cifrado; requiere RBAC y cifrado en reposo
ServiceAccount Identidad de un pod frente a la API de Kubernetes Token montado automáticamente Distinto de la identidad de una persona

Un detalle que evita muchos malentendidos: base64 es codificación, no protección. Cualquiera con permiso de lectura sobre Secrets puede descodificarlos en un segundo. La protección real viene de RBAC (módulo 8) y del cifrado en reposo de etcd.

Relacionados con esta familia están los límites de recursos (requests y limits de CPU y memoria), las ResourceQuota por namespace y los LimitRange, que se estudian en el módulo 3 y determinan la clase de calidad de servicio (QoS) del pod.

  1. La familia de almacenamiento

El sistema de ficheros de un contenedor es efímero: al reiniciarse, se pierde. Para postgres-reservas eso es inaceptable, así que existe esta familia.

Objeto Qué es Analogía
Volume Directorio montado en el pod, definido dentro del propio pod Un directorio compartido; muchos tipos mueren con el pod (emptyDir)
PersistentVolume (PV) Una pieza de almacenamiento real del clúster, con vida independiente del pod El disco físico disponible
PersistentVolumeClaim (PVC) La petición de un usuario: "quiero 20 GiB en modo lectura-escritura" El vale que canjeas por un disco
StorageClass El "tipo" de almacenamiento y cómo se aprovisiona automáticamente El catálogo: ssd-rapido, hdd-barato

El flujo normal, que verás en el módulo 5, es: declaras un PVC en tu manifiesto → la StorageClass aprovisiona dinámicamente un PV real → el PVC queda vinculado a él → el pod monta ese PVC como un volumen. Tú, como desarrollador, casi siempre escribes solo el PVC.

La separación PV/PVC responde a un reparto de responsabilidades: el administrador del clúster gestiona la oferta (PV y StorageClass), el desarrollador expresa la demanda (PVC), y ninguno necesita saber los detalles del otro.

  1. Organización: namespaces, etiquetas, selectores y anotaciones

Con 40 objetos, el clúster se vuelve inmanejable sin organización. Kubernetes ofrece dos ejes complementarios.

8.1. Namespace: división dura

Un namespace es una partición lógica del clúster. Rutas Norte usará tres: rutas-norte-dev, rutas-norte-pre y rutas-norte-pro.

Qué te da un namespace:

  • Unicidad de nombres: puede haber un Service api-reservas en cada uno sin conflicto.
  • Ámbito de RBAC: "este equipo puede desplegar en dev pero solo leer en pro".
  • Ámbito de cuotas: límites de CPU y memoria por entorno.
  • DNS: un servicio se resuelve como api-reservas.rutas-norte-dev.svc.cluster.local.

Qué no te da: aislamiento de red (para eso, NetworkPolicy) ni aislamiento de nodos. Además, algunos objetos son de ámbito de clúster y no viven en ningún namespace: Node, PersistentVolume, StorageClass, ClusterRole, Namespace mismo.

8.2. Etiquetas y selectores: la división blanda

Una etiqueta (label) es un par clave-valor pegado a un objeto. Un selector es una consulta sobre etiquetas. Este par es el mecanismo de acoplamiento de todo Kubernetes: un Service no conoce a sus pods por nombre, los encuentra por etiqueta. Lo mismo hace un ReplicaSet con sus réplicas.

Convenciones que Rutas Norte usará en todos los objetos:

metadata:
  labels:
    app: api-reservas                       # el componente
    app.kubernetes.io/part-of: rutas-norte  # la plataforma
    entorno: dev                            # el entorno

Y el selector correspondiente en un Service:

spec:
  selector:
    app: api-reservas
    entorno: dev

Las anotaciones (annotations) son también pares clave-valor, pero con un propósito opuesto: no se pueden seleccionar. Sirven para adjuntar metadatos que consumen herramientas: la configuración de un Ingress Controller, el commit de Git que originó el despliegue, un identificador de certificado. Regla mnemotécnica: si vas a filtrar por ello, etiqueta; si es información para una herramienta o para un humano, anotación.

  1. Controladores, operadores y CRDs

Estos tres cierran el mapa y son la puerta a la parte avanzada del curso.

  • Controlador: un proceso que ejecuta el bucle de reconciliación de la lección anterior sobre un tipo de objeto. El controlador de ReplicaSet vigila ReplicaSets y crea pods. Es el patrón universal de Kubernetes.
  • CRD (Custom Resource Definition): un objeto que define un tipo de objeto nuevo. Al aplicar un CRD, la API de tu clúster empieza a entender, por ejemplo, kind: Certificate o kind: PostgresCluster, con su propio kubectl get certificates.
  • Operador: la combinación de un CRD con un controlador propio que sabe reconciliarlo. Es "conocimiento de un administrador experto convertido en software": un operador de PostgreSQL puede crear réplicas, hacer copias de seguridad y ejecutar una conmutación por error sin intervención humana.
flowchart LR
    CRD["CRD<br/>define el tipo PostgresCluster"] --> API["API de Kubernetes"]
    CR["Objeto PostgresCluster<br/>'reservas', 3 réplicas"] --> API
    API --> CTRL["Controlador del operador"]
    CTRL --> SS["StatefulSet"]
    CTRL --> SVC["Services"]
    CTRL --> SEC["Secrets"]
    CTRL --> PVC["PVCs"]

Cuando en el módulo 6 valores si postgres-reservas debe gestionarse con un StatefulSet propio o con un operador, esta será la distinción clave.

  1. Tabla maestra de conceptos

Guarda esta tabla: es el índice conceptual de todo el curso.

Concepto Qué es en una frase Dónde lo veremos en Rutas Norte Módulo
Clúster Plano de control + nodos como un solo sistema El clúster de prácticas y el futuro de producción 1, 10
Nodo Máquina que ejecuta pods Nodo único de minikube; multinodo con kind 1, 6
Pod Unidad mínima: contenedores que comparten red y disco Primer despliegue de tienda-web 1, 2
ReplicaSet Garantiza N pods idénticos Creado por los Deployments 2
Deployment Gestiona ReplicaSets para desplegar y actualizar sin corte tienda-web, api-reservas, worker-notificaciones 2
StatefulSet Réplicas con identidad y disco propios postgres-reservas 6
DaemonSet Un pod por nodo Agente de logs y de métricas 6, 7
Job Tarea que corre hasta terminar Migración del esquema de reservas 6
CronJob Job programado por horario informes-ocupacion, cada noche 6
Service IP y nombre estables + balanceo hacia pods api-reservas, postgres-reservas, redis-cache 2, 4
Ingress Enrutado HTTP por dominio y ruta, con TLS www.rutasnorte.example, api.rutasnorte.example 4
NetworkPolicy Cortafuegos entre pods Solo la API accede a la base de datos 4, 8
ConfigMap Configuración no sensible externalizada Parámetros de la API y nginx.conf de la tienda 3
Secret Datos sensibles gestionados aparte Contraseña de postgres-reservas, credenciales SMTP 3, 8
ServiceAccount Identidad del pod ante la API Cuenta mínima para cada componente 3, 8
Volume Directorio montado en el pod Caché temporal, ficheros compartidos entre contenedores 5
PersistentVolume Almacenamiento real con vida propia Disco de la base de datos 5
PersistentVolumeClaim Petición de almacenamiento Los 20 GiB que pide postgres-reservas 5
StorageClass Catálogo y aprovisionamiento dinámico de discos Clase por defecto de minikube y clases de nube 5
Namespace Partición lógica del clúster rutas-norte-dev, -pre, -pro 2
Etiqueta / selector Metadato consultable / consulta sobre él app, entorno, app.kubernetes.io/part-of 2
Anotación Metadato no consultable, para herramientas Configuración del Ingress, commit desplegado 2, 4
Recurso / objeto Tipo de entidad / instancia concreta Todo lo que escribas en k8s/ 1
Controlador Proceso que reconcilia un tipo de objeto Los que crean tus pods sin que los veas 1, 6
CRD Define un tipo de objeto nuevo en la API El que instala cert-manager 4, 6
Operador CRD + controlador con lógica experta Alternativa gestionada para PostgreSQL 6
HPA Ajusta el número de réplicas automáticamente Picos de puentes y vacaciones 9
Sonda (probe) Comprobación de salud de un contenedor Liveness y readiness de la API 7
RBAC Quién puede hacer qué sobre qué recursos Permisos del equipo y de los pods 8

Errores Comunes y Consejos

  • Confundir pod y contenedor. Un pod puede tener varios contenedores, pero se programa, se mueve y se escala como una unidad. "Escalar" significa crear más pods, no más contenedores dentro del pod.
  • Crear pods sueltos en producción. Nadie los resucita. Siempre a través de un Deployment, StatefulSet, DaemonSet o Job.
  • Guardar una contraseña en un ConfigMap. Es el error de seguridad más frecuente en clústeres reales. La distinción ConfigMap/Secret existe precisamente para poder aplicar RBAC distinto a cada uno.
  • Suponer que un Secret está cifrado. base64 es codificación. Sin cifrado en reposo y RBAC, un Secret es texto plano con un paso extra.
  • Creer que un namespace aísla la red. No lo hace: un pod de rutas-norte-dev puede alcanzar a uno de rutas-norte-pro salvo que exista una NetworkPolicy.
  • Cambiar etiquetas a la ligera. Las etiquetas son el mecanismo de acoplamiento: si modificas la etiqueta de un pod, su Service deja de verlo y su ReplicaSet crea uno nuevo para sustituirlo. Se hace a propósito en algunas técnicas de depuración, pero nunca por accidente.
  • Consejo: cuando aparezca un objeto que no conozcas, hazte tres preguntas — ¿a qué familia pertenece (carga, red, configuración, almacenamiento)?, ¿qué otro objeto lo crea o lo consume?, ¿es de ámbito de namespace o de clúster? Con esas tres respuestas ya puedes situarlo. Y kubectl explain <recurso> te las responde sin salir de la terminal.

Ejercicios

Ejercicio 1: Elegir el objeto adecuado

Para cada necesidad de Rutas Norte, indica qué objeto (o combinación de objetos) usarías y por qué:

  1. Ejecutar 4 copias intercambiables de api-reservas y poder pasar de la versión 2.4.0 a la 2.5.0 sin cortar el servicio.
  2. Que postgres-reservas conserve sus datos aunque su pod se recree, y que siempre se llame igual.
  3. Generar un informe de ocupación todas las noches a las 02:30.
  4. Que tienda-web alcance a api-reservas por un nombre fijo aunque las réplicas cambien de IP.
  5. Guardar la contraseña de la base de datos fuera de la imagen.
  6. Impedir que worker-notificaciones pueda conectarse directamente a la base de datos.

Ejercicio 2: La cadena de responsabilidad

Explica con tus palabras, en 6 líneas como máximo, qué ocurre desde que escribes replicas: 3 en un Deployment hasta que hay tres contenedores corriendo, nombrando todos los objetos y componentes que intervienen. Después responde: si borras uno de esos tres pods a mano, ¿quién lo recrea exactamente?

Ejercicio 3: Etiqueta o anotación

Clasifica cada metadato como etiqueta o anotación y justifica en una línea:

  1. app: api-reservas
  2. entorno: pro
  3. rutasnorte.example/commit: 9f3a1c2
  4. nginx.ingress.kubernetes.io/proxy-body-size: 8m
  5. app.kubernetes.io/part-of: rutas-norte
  6. rutasnorte.example/responsable: [email protected]

Soluciones

Solución 1

  1. Deployment. Es una aplicación sin estado con réplicas intercambiables; el Deployment gestiona ReplicaSets y permite la actualización progresiva y el rollback.
  2. StatefulSet + PersistentVolumeClaim (con su StorageClass detrás). El StatefulSet da identidad estable (postgres-reservas-0) y un PVC propio por réplica que sobrevive a la recreación del pod.
  3. CronJob, que a su vez crea un Job y este un Pod en cada ejecución programada.
  4. Service de tipo ClusterIP. Da nombre DNS e IP virtual estables y reparte entre los pods sanos seleccionados por etiqueta.
  5. Secret, montado como variable de entorno o fichero, con RBAC restrictivo. Nunca un ConfigMap.
  6. NetworkPolicy que permita tráfico de entrada a postgres-reservas solo desde pods con la etiqueta app: api-reservas.

Solución 2

Escribes el Deployment y lo aplicas; el apiserver lo guarda en etcd. El controlador de Deployment crea un ReplicaSet con replicas: 3. El controlador de ReplicaSet observa que hay 0 pods y crea 3 objetos Pod. El kube-scheduler asigna nodo a cada uno. El kubelet de cada nodo pide al runtime, vía CRI, que descargue la imagen y arranque el contenedor. Cadena completa: Deployment → ReplicaSet → Pod → contenedor.

Si borras un pod a mano, lo recrea el controlador de ReplicaSet (no el Deployment): detecta que hay 2 pods donde su spec pide 3 y crea uno nuevo, con nombre e IP distintos.

Solución 3

  1. Etiqueta. Identifica el componente y es la clave por la que seleccionan Services y ReplicaSets.
  2. Etiqueta. Se usa para filtrar y para selectores por entorno.
  3. Anotación. Es trazabilidad; nunca vas a seleccionar objetos por commit y el valor cambia en cada despliegue.
  4. Anotación. Es configuración que consume el Ingress Controller, no un criterio de selección.
  5. Etiqueta. Etiqueta estándar recomendada que permite consultar toda la plataforma de una vez (-l app.kubernetes.io/part-of=rutas-norte).
  6. Anotación. Información de contacto para humanos; no tiene sentido filtrar por ella y su formato libre no encaja en las restricciones de valor de una etiqueta.

Conclusión

Ya tienes el mapa completo del vocabulario: los objetos de Kubernetes se agrupan en familias con papeles claros —cargas de trabajo que crean pods, red que les da estabilidad y acceso, configuración que los parametriza, almacenamiento que les da persistencia— organizadas por namespaces y acopladas entre sí mediante etiquetas y selectores, con los controladores reconciliándolo todo y los CRDs y operadores permitiendo extender el sistema. La jerarquía Deployment → ReplicaSet → Pod → contenedor es la columna vertebral que conviene tener siempre presente, y la tabla maestra te sirve de índice para el resto del curso.

Hasta aquí, todo ha sido teoría. Es el momento de tener un clúster propio en el que probar cada cosa que vayamos aprendiendo: en la siguiente lección, Configuración de un Clúster de Kubernetes, montaremos paso a paso el entorno de prácticas que usaremos durante los doce módulos.

Curso de Kubernetes

Módulo 1: Introducción a Kubernetes

Módulo 2: Componentes Principales de Kubernetes

Módulo 3: Gestión de Configuración y Secretos

Módulo 4: Redes en Kubernetes

Módulo 5: Almacenamiento en Kubernetes

Módulo 6: Conceptos Avanzados de Kubernetes

Módulo 7: Monitoreo y Registro

Módulo 8: Seguridad en Kubernetes

Módulo 9: Escalado y Rendimiento

Módulo 10: Ecosistema y Herramientas de Kubernetes

Módulo 11: Estudios de Caso y Aplicaciones del Mundo Real

Módulo 12: Preparación para la Certificación de Kubernetes

© Copyright 2026. Todos los derechos reservados