kubectl rollout es el comando que usas para controlar e inspeccionar cómo Kubernetes despliega los cambios en un workload. Cuando modificas un Deployment, Kubernetes reemplaza los pods antiguos por otros nuevos, y kubectl rollout es la forma de observar ese proceso, pausarlo, revertirlo, reiniciarlo y consultar su historial.
En esta guía aprenderás cómo funciona un rollout de Kubernetes por dentro, todos los subcomandos de kubectl rollout con ejemplos, por qué los rollouts se atascan y cómo diagnosticarlos, y las prácticas que hacen que los rollouts sean seguros en producción.
¿Qué es kubectl rollout?
kubectl rollout es un conjunto de comandos para gestionar el rollout de un workload después de modificarlo. Un rollout es el proceso de reemplazar los pods que ejecutan la versión anterior por pods que ejecutan la nueva. El comando no modifica el workload en sí. Lo que hace es permitirte observar y controlar el rollout que desencadena un cambio: comprobar si terminó, ver qué cambió, deshacerlo, pausarlo y reanudarlo, o reiniciar los pods.
Funciona con los workloads que gestionan los rollouts por ti, es decir, Deployments, StatefulSets y DaemonSets. La mayor parte de esta guía usa un Deployment, ya que es donde los rollouts son más comunes.
¿Cómo ejecuta Kubernetes realmente un rollout?
Cuando cambias la plantilla de pods de un Deployment, Kubernetes no edita los pods en ejecución. Crea un nuevo ReplicaSet para la nueva versión y mueve gradualmente los pods del ReplicaSet antiguo al nuevo. Cada ReplicaSet, y cada pod que le pertenece, lleva una etiqueta pod-template-hash, que es un hash de la plantilla de pods. Con esta etiqueta, Kubernetes distingue las versiones y mantiene cada pod vinculado al ReplicaSet correcto. Cuando más adelante haces un rollback, en realidad Kubernetes solo vuelve a escalar un ReplicaSet antiguo.
Lo importante es saber qué cambios inician realmente un rollout. Solo los cambios en la plantilla de pods, el campo .spec.template, crean un nuevo ReplicaSet y una nueva revisión. Eso significa que una imagen nueva, una variable de entorno modificada o un resource request actualizado disparan un rollout. Un cambio en el número de réplicas no lo hace, porque aumentar o reducir la escala solo redimensiona el ReplicaSet actual en lugar de crear uno nuevo. Por eso escalar un Deployment nunca aparece en su historial de rollouts.
La velocidad del rollout se controla con dos campos dentro de la estrategia de rolling update. maxSurge define cuántos pods extra pueden existir por encima del número deseado durante el rollout, con un valor predeterminado del 25%, redondeado hacia arriba. maxUnavailable define cuántos pods pueden faltar por debajo del número deseado durante el rollout, con un valor predeterminado del 25%, redondeado hacia abajo. Juntos controlan qué tan rápido Kubernetes reemplaza los pods antiguos por los nuevos. Configurar maxSurge: 1 y maxUnavailable: 0 es una opción segura muy común, ya que agrega un pod nuevo antes de eliminar uno antiguo y nunca baja de la capacidad total.
Hay tres configuraciones más que controlan el avance del rollout. Un pod nuevo solo cuenta como disponible cuando pasa su readiness probe, así que sin un buen readiness probe Kubernetes tratará un pod como listo antes de que pueda atender tráfico y avanzará demasiado pronto. minReadySeconds hace que un pod espere, después de estar listo, antes de contar como disponible, lo que detecta un pod que pasa su probe y luego falla segundos después. Y progressDeadlineSeconds, que por defecto es 600 (10 minutos), es el tiempo que Kubernetes espera a que el rollout avance antes de marcar el Deployment como fallido con ProgressDeadlineExceeded.

Los subcomandos de kubectl rollout y qué recursos los admiten
kubectl rollout tiene seis subcomandos: status, history, undo, pause, resume y restart. No todos aplican a todos los workloads. status, history, undo y restart funcionan con Deployments, StatefulSets y DaemonSets. pause y resume funcionan solo con Deployments, porque solo un Deployment tiene un rollout que se puede pausar. Las siguientes secciones cubren cada uno, usando un Deployment llamado api.
kubectl rollout status
kubectl rollout status sigue un rollout y te avisa cuando termina:
kubectl rollout status deployment/apiMientras se ejecuta, imprime el progreso y sale cuando el rollout finaliza. Verás líneas como Waiting for deployment "api" rollout to finish: 2 out of 4 new replicas have been updated... y, al final, deployment "api" successfully rolled out. Cada línea refleja cómo el nuevo ReplicaSet escala y los pods pasan a estar disponibles.
Por defecto, el comando transmite el estado en tiempo real y espera. Hay dos flags que cambian este comportamiento: --timeout evita que espere indefinidamente, algo importante en un script, y --watch=false hace que imprima el estado actual una sola vez y salga en lugar de seguir transmitiendo:
kubectl rollout status deployment/api --timeout=5mkubectl rollout status deployment/api --watch=falseLa parte más útil de rollout status es su código de salida. Devuelve 0 cuando el rollout tiene éxito y un código distinto de cero cuando falla o se agota el tiempo. Esto lo hace útil en pipelines de CI/CD: el pipeline puede esperar a que el rollout termine y fallar si el Deployment no llega a estar listo, en lugar de tratar un kubectl apply exitoso como un despliegue exitoso.
kubectl rollout history
kubectl rollout history lista las revisiones anteriores de un workload, para que puedas ver qué cambió y elegir a cuál revertir:
kubectl rollout history deployment/apiLa salida es una tabla con los números de revisión y una columna CHANGE-CAUSE. Para ver la plantilla de pods completa de una revisión, pasa --revision:
kubectl rollout history deployment/api --revision=2La columna CHANGE-CAUSE solo se completa si configuras la anotación kubernetes.io/change-cause. El antiguo flag --record que la rellenaba está obsoleto, así que la forma actual es establecer la anotación tú mismo después de un cambio:
kubectl annotate deployment/api kubernetes.io/change-cause="update image to api:1.4.0"Sin la anotación, la columna muestra <none>, lo que dificulta saber qué cambió en cada revisión.
Qué tan atrás puedes revertir depende de revisionHistoryLimit, cuyo valor predeterminado es 10. Kubernetes conserva esa cantidad de ReplicaSets antiguos y elimina los más viejos. Si el límite es demasiado bajo, puede que la revisión a la que quieres volver ya no exista.
kubectl rollout undo
kubectl rollout undo revierte un workload. Sin argumentos, vuelve a la revisión anterior, y con --to-revision va a una revisión específica del historial:
kubectl rollout undo deployment/apikubectl rollout undo deployment/api --to-revision=2Esto funciona porque Kubernetes todavía conserva el ReplicaSet antiguo y simplemente lo vuelve a escalar. Un rollback es en sí mismo un rollout, así que ejecuta después rollout status para confirmar que terminó.
Una limitación importante es que undo solo restaura la plantilla de pods. Esto incluye la imagen del contenedor, las variables de entorno y la configuración de recursos. No deshace los cambios hechos fuera de la plantilla de pods. Por ejemplo, si el release también modificó un ConfigMap, un Secret, un esquema de base de datos o un sistema externo, revertir el Deployment no revierte esos cambios.
Por esta razón, trata rollout undo como una herramienta de recuperación rápida, no como tu estrategia habitual de despliegue. Puede restaurar rápidamente una versión anterior de los pods, pero no puede revertir todo lo que pudo haber cambiado durante un release.
kubectl rollout restart
kubectl rollout restart reinicia todos los pods de un workload sin cambiar la imagen:
kubectl rollout restart deployment/apiEl comando agrega a la plantilla de pods una anotación kubectl.kubernetes.io/restartedAt con la marca de tiempo actual; como esto modifica la plantilla de pods, Kubernetes lo trata como un rollout normal. Crea un nuevo ReplicaSet y reemplaza los pods antiguos gradualmente, respetando maxSurge, maxUnavailable y los readiness probes. Con probes bien configurados, esto permite reiniciar la aplicación sin tiempo de inactividad.
Un caso de uso común es aplicar cambios que no reinician los pods de forma automática. Por ejemplo, cuando actualizas un ConfigMap o un Secret que la aplicación lee solo al arrancar, los pods existentes siguen usando los valores antiguos. Un rollout restart reemplaza esos pods para que arranquen con los valores nuevos.
Un rollout restart es más controlado que eliminar pods manualmente o escalar un Deployment a cero. Eliminar pods a mano los reemplaza, pero no te da el mismo proceso de rollout controlado, y escalar a cero detiene todos los pods antes de iniciar los nuevos, lo que provoca tiempo de inactividad. Un rollout restart reemplaza los pods gradualmente siguiendo la configuración de rollout del Deployment.
kubectl rollout pause y resume
kubectl rollout pause impide que un Deployment actúe sobre los cambios, y kubectl rollout resume le permite continuar:
kubectl rollout pause deployment/apikubectl rollout resume deployment/apiEsto resulta útil en dos escenarios. El primero es agrupar varios cambios en un solo rollout. Si primero pausas, luego cambias la imagen, los recursos y el entorno, y después reanudas, Kubernetes realiza un único rollout con todos los cambios en lugar de un rollout separado por cada edición:
kubectl rollout pause deployment/apikubectl set image deployment/api api=api:1.5.0kubectl set resources deployment/api -c=api --limits=cpu=500m,memory=512Mikubectl rollout resume deployment/apiEl segundo es pausar a mitad de un rollout para validar un canary parcial. Inicias un rollout cambiando la imagen, dejas que arranquen algunos pods nuevos y luego pausas. Ahora una pequeña parte del tráfico está en la versión nueva mientras el resto sigue en la antigua, y puedes observar sus métricas y logs. Si se ve saludable, reanuda para completar el rollout, y si no, ejecuta undo para revertir. Recuerda que no puedes revertir un Deployment pausado, así que reanúdalo antes de ejecutar undo.
¿Por qué se atascan los rollouts y cómo diagnosticarlos?
Un rollout se atasca cuando los pods nuevos no llegan a estar disponibles, y el Deployment termina reportando ProgressDeadlineExceeded. Estas son las causas más comunes:
a. Capacidad insuficiente del clúster para los pods de surge: Un rolling update crea pods extra (maxSurge) antes de eliminar los antiguos, así que el rollout necesita CPU y memoria libres para programarlos. Si el clúster no tiene espacio, los pods de surge se quedan en Pending y el rollout no puede avanzar. Debes verificarlo con kubectl get pods y kubectl describe pod en el pod pendiente, y comprobar si el Cluster Autoscaler puede agregar un nodo.
b. Fallas del readiness probe y CrashLoopBackOff: Si los pods nuevos arrancan pero nunca pasan su readiness probe, o fallan y se reinician en bucle, nunca cuentan como disponibles y el rollout se estanca. Lee los logs del pod nuevo con kubectl logs y sus eventos con kubectl describe pod. Aquí es donde aparecen un probe mal configurado o una imagen nueva defectuosa.
c. OOMKills por requests y limits de memoria mal dimensionados: Si la versión nueva necesita más memoria de la que su limit permite, el kernel mata cada pod nuevo al arrancar, así que el pod muestra OOMKilled con código de salida 137 y el rollout nunca se completa. Los logs del pod suelen estar vacíos, porque el contenedor fue eliminado en lugar de fallar por sí mismo, así que la señal está en kubectl describe pod, bajo el último estado.
d. Los PodDisruptionBudgets no bloquean el rollout en sí: Un PodDisruptionBudget no restringe el rolling update de un Deployment. Los PDBs no limitan los rolling updates de los workloads porque el rollout reemplaza los pods directamente y no a través de la API de eviction. Lo que sí restringe un PDB son las evictions voluntarias: drenados de nodos, la reducción de escala del Cluster Autoscaler y similares. Así que un PDB puede bloquear un drenado de nodo que ocurra al mismo tiempo que tu rollout, y un PDB mal configurado (por ejemplo, minAvailable igual al número de réplicas) puede bloquear los drenados por completo, pero no es lo que está frenando el rollout en sí.
e. Conflictos entre el Horizontal Pod Autoscaler y las réplicas: Si un HPA gestiona las réplicas de un Deployment y además defines replicas de forma fija en el manifiesto, cada kubectl apply restablece el número al valor del manifiesto hasta que el HPA lo corrige de nuevo. Esto puede provocar un escalado confuso durante un rollout. La solución es omitir replicas del manifiesto en cualquier Deployment gestionado por un HPA.
La mayoría de estos problemas se reducen al dimensionamiento de recursos. Los pods de surge que no caben en el clúster y los pods nuevos que terminan OOMKilled apuntan a una configuración de recursos incorrecta. Aquí es donde entra PerfectScale. Su plataforma de gobernanza de Kubernetes observa cómo tus workloads usan realmente la CPU y la memoria y lo convierte en recomendaciones de right-sizing accionables y automatizadas que puedes aplicar de forma manual o autónoma. Con requests y limits que reflejan la realidad, tus pods de surge caben y tus pods nuevos tienen la memoria que necesitan, así que los rollouts terminan sin problemas en lugar de atascarse. Equipos como Paramount Pictures y Creditas usan PerfectScale para mantener sus clústeres eficientes, y puedes registrarte o agendar una sesión técnica.

Buenas prácticas para ejecutar kubectl rollout en producción
Aquí tienes algunas prácticas simples para mantener los rollouts de producción seguros y sin sobresaltos:
a. Aplica right-sizing a los requests y limits antes de desplegar: Debes configurar resource requests y limits precisos antes de iniciar un rollout. Esto da a los pods de surge suficiente espacio para programarse y reduce el riesgo de que los pods nuevos terminen OOMKilled.
b. Revisa las métricas y los logs, no solo el rollout status: Un rollout status exitoso solo significa que los pods nuevos llegaron a estar listos. No significa que la aplicación funcione correctamente. Debes revisar las tasas de error, la latencia y los logs después de un rollout, especialmente cuando uses un canary pausado.
c. Configura progressDeadlineSeconds y --timeout de forma explícita: Debes establecer un progressDeadlineSeconds razonable para que Kubernetes marque como fallido un Deployment atascado. Usa --timeout con rollout status para que tu pipeline deje de esperar después de un período definido.
d. Agrega una anotación de change-cause en cada cambio: Debes configurar kubernetes.io/change-cause al hacer cambios para que rollout history muestre claramente qué cambió en cada revisión. Esto facilita elegir la revisión correcta durante un rollback.
e. Mantén revisionHistoryLimit lo suficientemente alto para revertir con seguridad: El valor predeterminado de 10 es adecuado para la mayoría de los workloads, pero si despliegas con mucha frecuencia, asegúrate de que siga cubriendo las revisiones a las que podrías necesitar volver de forma realista.
f. Limita el radio de impacto desplegando de forma gradual: Evita enviar un cambio riesgoso a todos los namespaces o clústeres a la vez. Despliégalo por etapas para poder detectar problemas a tiempo y detenerte antes de que afecten a todo.
g. Pasa de comandos manuales a GitOps y entrega progresiva: kubectl rollout es útil para aprender y gestionar rollouts manualmente. Para entornos de producción más grandes, herramientas como Argo CD o Flux pueden gestionar los despliegues mediante GitOps, mientras que Argo Rollouts o Flagger pueden automatizar despliegues canary y blue-green.