Ejecuta kubectl run nginx --image=nginx:1.27 y Kubernetes crea exactamente un Pod llamado nginx. Bórralo con kubectl delete pod nginx y desaparece para siempre — nadie se entera, nadie lo reemplaza. Un Pod es la unidad mínima desplegable en Kubernetes: uno o más contenedores que comparten un namespace de red y un conjunto de volúmenes, programados juntos en un mismo nodo.

Ese Pod aislado es un callejón sin salida en producción. Si el contenedor que hay dentro falla, el kubelet lo reinicia en el mismo sitio. Si el nodo se reinicia, o alguien borra el Pod, nada lo vuelve a crear. Un Pod desnudo no tiene memoria de que debería seguir existiendo.

Qué añade un Deployment sobre un Pod

Un Deployment es un objeto de Kubernetes que indica cuántas copias de un Pod deben existir y cómo desplegar cambios sobre ellas. Dejas de gestionar Pods directamente y describes el estado deseado; un bucle de control se encarga de que ese estado se cumpla. Es el mismo modelo de reconciliación que hay detrás de todo lo demás en Kubernetes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: web-app
          image: nginx:1.27
          ports:
            - containerPort: 80
1
2
kubectl apply -f web-app-deployment.yaml
kubectl get pods
1
2
3
4
NAME                       READY   STATUS    RESTARTS   AGE
web-app-7d9f8c7b86-4kxqz   1/1     Running   0          8s
web-app-7d9f8c7b86-9wj2p   1/1     Running   0          8s
web-app-7d9f8c7b86-x2p6t   1/1     Running   0          8s

Tres Pods, no uno, y ninguno se llama web-app. Ese patrón de nombres (web-app-7d9f8c7b86-4kxqz) es la primera señal de que algo más los está gestionando.

replicas: 3 es la misma instrucción que das con docker compose up --scale web=3 en Docker Compose. La diferencia es que aquí un controlador sigue haciendo cumplir ese número mucho después de que el comando termine.

Cómo crea un Deployment los Pods en realidad: el ReplicaSet en medio

Un Deployment no crea Pods directamente. Crea un ReplicaSet, y es el ReplicaSet el que crea los Pods. Puedes ver toda la cadena:

1
2
3
kubectl get deployment web-app
kubectl get replicaset -l app=web-app
kubectl get pods -l app=web-app
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
web-app   3/3     3            3           2m

NAME                 DESIRED   CURRENT   READY   AGE
web-app-7d9f8c7b86   3         3         3       2m

NAME                       READY   STATUS    RESTARTS   AGE
web-app-7d9f8c7b86-4kxqz   1/1     Running   0          2m
web-app-7d9f8c7b86-9wj2p   1/1     Running   0          2m
web-app-7d9f8c7b86-x2p6t   1/1     Running   0          2m

El nombre del ReplicaSet es el nombre del Deployment más un hash de la plantilla del Pod (7d9f8c7b86); el nombre de cada Pod es el nombre del ReplicaSet más un sufijo aleatorio. kubectl describe pod web-app-7d9f8c7b86-4kxqz muestra la relación directamente, en el campo Controlled By: ReplicaSet/web-app-7d9f8c7b86.

Borra uno de esos Pods y el recuento baja a 2. En cuestión de segundos aparece un reemplazo. Es el ReplicaSet el que nota el hueco y crea un nuevo Pod a partir de la misma plantilla, no el Deployment actuando directamente. El ReplicaSet es quien vigila. El Deployment existe para lo único que un ReplicaSet no puede hacer por sí solo: reemplazar una plantilla de Pod de forma gradual en lugar de toda a la vez.

Qué le hace un rollout a los ReplicaSets

Cambia la imagen y aplícalo:

1
2
kubectl set image deployment/web-app web-app=nginx:1.27.1
kubectl rollout status deployment/web-app
1
2
3
Waiting for deployment "web-app" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "web-app" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "web-app" successfully rolled out

Detrás de esa línea de estado, el Deployment creó un segundo ReplicaSet para la nueva plantilla de Pod y lo fue escalando mientras reducía el antiguo. Con la estrategia RollingUpdate por defecto sobre 3 réplicas, el resultado es un Pod a la vez:

1
kubectl get replicaset -l app=web-app
1
2
3
NAME                 DESIRED   CURRENT   READY   AGE
web-app-7d9f8c7b86   0         0         0       6m
web-app-6b8f6d9c4d   3         3         3       40s

El ReplicaSet antiguo no se borra. Se queda en cero réplicas, conservando la plantilla de Pod anterior como registro. Eso es lo que hace que el rollback sea rápido:

1
kubectl rollout undo deployment/web-app

Kubernetes vuelve a escalar el ReplicaSet antiguo y reduce el nuevo — sin reconstruir nada, sin volver a descargar una imagen antigua si sigue en caché en el nodo. kubectl rollout history deployment/web-app --revision=1 sigue mostrando exactamente qué imagen ejecutaba esa revisión.

Cuándo un Pod desnudo es la decisión correcta

Un Pod desnudo no es un error en todos los contextos, solo en la mayoría:

  1. Un contenedor de diagnóstico de usar y tirar que borrarás en cinco minutos: kubectl run debug --image=busybox -it --rm -- sh.
  2. Un Job o un CronJob, que crea Pods mediante su propio controlador porque el trabajo tiene que terminar, no quedarse corriendo indefinidamente.
  3. Inspeccionar o aprender la spec del Pod en sí, antes de envolverla en algo que la gestione.

Todo lo que debe seguir funcionando tras un fallo, una caída de nodo o una actualización pasa por un Deployment. O por un StatefulSet, para Pods que necesitan una identidad estable y su propio almacenamiento — un problema distinto, y un objeto distinto. Escribe el manifiesto del Deployment por defecto y baja a un Pod desnudo solo en los tres casos anteriores.

Pod, ReplicaSet y Deployment lado a lado

PodReplicaSetDeployment
Qué gestionaContenedoresPodsReplicaSets
Reemplaza una instancia borradaNoSí, mediante su ReplicaSet
Escala a N réplicasNo
Rolling updatesNoNo
Rollback a una versión anteriorNoNo
Lo creas directamenteRara vezCasi nuncaNormalmente

Comprueba si tus propios Pods tienen un Deployment detrás

Ejecuta esto contra lo que ya tengas en tu clúster:

1
kubectl get deployment,replicaset,pod -l app=<tu-label>

Si solo aparecen filas de Pod, esos son Pods desnudos. Es el hueco que hay que cerrar antes de que el próximo drain de un nodo se lleve la app por delante.

Artículos relacionados