DevOps¶
De un vistazo
Materia: Capa 3 · Sobrevivir en producción · Tiempo de lectura: ~35 min · Requisitos previos: ninguno estricto, pero el resto de Capa 3 (observabilidad, escalado, seguridad) ayuda a ver por qué esto importa.
En una frase: DevOps no es un puesto ni un montón de herramientas de moda, es una forma de acortar y hacer fiable el camino que recorre tu código desde tu editor hasta producción, borrando el muro entre "los que escriben" y "los que operan".
Por qué esto importa¶
Casi todo el mundo ha vivido esta escena, aunque no le pusiera nombre:
- Tu código funciona en tu portátil. Lo subes al servidor y explota. La frase legendaria: "en mi máquina funciona". Y tienes razón: en la tuya funciona. El problema es que la tuya y la del servidor no son la misma máquina, y nadie llevaba la cuenta de en qué se diferencian.
- El despliegue es un acto de fe que se hace una vez al mes, de noche, con toda la lista de pasos apuntada en un documento de Word que casi nadie ha vuelto a leer. Cuando algo sale mal —y sale— nadie sabe qué se rompió ni cómo volver atrás.
- El equipo de desarrollo dice "yo ya lo entregué, funciona"; el equipo de operaciones dice "esto en producción se cae". Cada uno mira al otro. El código está atascado en tierra de nadie.
- Un
bugtarda tres semanas en llegar arreglado a producción, no porque arreglarlo cueste tres semanas, sino porque el camino desde elcommithasta el usuario está lleno de pasos manuales, colas y miedo.
Todos estos dolores tienen la misma raíz: el trayecto del código a producción es largo, manual y poco fiable, y la responsabilidad sobre ese trayecto está partida entre gente que no se habla. DevOps es el conjunto de ideas —culturales primero, técnicas después— que atacan justo eso. No vas a "aprender DevOps" como quien aprende un lenguaje; vas a interiorizar un criterio: cada vez que el camino a producción sea largo, manual o dé miedo, hay algo que arreglar.
Intuición primero: el muro y el puente¶
Imagina una fábrica partida por un muro. A un lado, los diseñadores (desarrollo): inventan, cambian, quieren sacar cosas nuevas cuanto antes. Al otro lado, los operarios de la cadena (operaciones): quieren que la fábrica no se pare nunca, así que odian el cambio, porque cada cambio es un riesgo de que la línea reviente.
Sobre el muro hay una ventanilla. Los diseñadores lanzan por encima su trabajo ("aquí tienes, despliégalo") y se desentienden. Los operarios lo reciben sin saber qué es, intentan montarlo, se cae, y lo devuelven por encima del muro ("esto no funciona"). Nadie es dueño del resultado final. Cada lado optimiza su mitad y el conjunto va fatal: los desarrolladores quieren velocidad, los de operaciones quieren estabilidad, y como son objetivos enfrentados gestionados por separado, el sistema se paraliza.
graph LR
subgraph DEV["Desarrollo · quiere CAMBIO"]
D1["escribe código"]
end
subgraph OPS["Operaciones · quiere ESTABILIDAD"]
O1["mantiene el sistema en pie"]
end
D1 -->|"lanza por encima del muro<br/>«ya es tu problema»"| MURO["🧱 EL MURO"]
MURO -->|"«esto se cae, no es lo que probé»"| O1
DevOps es tirar el muro y poner un puente. La idea central es que un mismo equipo es dueño del ciclo de vida completo: lo construye, lo despliega, lo opera y lo arregla cuando se rompe a las 3 de la mañana. "You build it, you run it" (tú lo construyes, tú lo operas). Cuando quien programa es también quien recibe la llamada del pager de madrugada, deja de escribir código que "funciona en su máquina" y empieza a escribir código que sobrevive en producción. La responsabilidad compartida no es un valor moral bonito: es el mecanismo que alinea los incentivos.
Guarda esta imagen —el muro contra el puente— porque todo lo técnico que viene después (CI/CD, contenedores, infraestructura como código) son solo herramientas para sostener el puente. Si adoptas las herramientas pero mantienes el muro, no tienes DevOps: tienes un equipo de operaciones que ahora usa Docker.
El detalle¶
1. La cultura va antes que las herramientas (y esto no es un cliché)¶
El error número uno es creer que DevOps se compra o se instala. "Vamos a hacer DevOps" y acto seguido montan Jenkins, Kubernetes y diecisiete dashboards. Seis meses después tienen las mismas peleas de antes, pero con más YAML.
DevOps es, en su núcleo, un cambio de quién es responsable de qué. Concretamente:
- Responsabilidad compartida del ciclo de vida completo. No "yo programo y tú despliegas", sino "nosotros llevamos esto a producción y lo mantenemos vivo, juntos". El equipo se mide por el resultado en producción, no por "haber entregado".
- Fallar es información, no un juicio. Si cada caída termina en buscar al culpable, la gente esconde los problemas y deja de desplegar por miedo. La cultura sana trata los incidentes como aprendizaje: post-mortems sin culpables (blameless), donde se pregunta "¿qué del sistema permitió esto?" en vez de "¿quién la lió?".
- Automatizar lo repetitivo y aburrido. No por pereza, sino porque un humano haciendo veinte pasos manuales de despliegue a medianoche se equivoca, y además nadie más sabe hacerlo. La máquina lo hace igual las mil veces.
El test rápido para saber si es cultura o postureo
Pregunta: cuando algo se cae en producción, ¿qué es lo primero que pasa? Si la respuesta es "buscamos quién fue", el muro sigue en pie por mucho Kubernetes que haya. Si es "miramos qué pasó y cómo evitar que se repita", hay DevOps de verdad.
Con la cultura en su sitio, las herramientas cobran sentido: existen para hacer el camino corto y fiable. Vamos a por ellas en ese orden.
2. CI/CD: automatizar el camino del commit a producción¶
Son dos ideas encadenadas que casi siempre se nombran juntas, pero resuelven problemas distintos.
Integración continua (CI, Continuous Integration) ataca el infierno del "integramos al final". En el modelo viejo, cinco personas trabajan tres semanas cada una en su rama aislada y el último día intentan juntarlo todo: un baño de sangre de conflictos donde el código de unos rompe el de otros y nadie sabe cuál. La CI le da la vuelta: integra pronto y a menudo —cada persona funde su trabajo a la rama principal varias veces al día— y en cada push, una máquina compila el proyecto y pasa todos los tests automáticamente. Si algo rompe, te enteras en minutos, cuando el cambio es pequeño y sabes exactamente qué lo causó, no tres semanas después cuando ya es un ovillo imposible.
Entrega/Despliegue continuo (CD, Continuous Delivery / Deployment) sigue donde acaba la CI. Una vez el código pasa los tests, ¿qué hacemos con él?
- Continuous Delivery (entrega): el sistema deja el artefacto listo para desplegar con un solo clic. Un humano decide cuándo apretar el botón.
- Continuous Deployment (despliegue): si pasa todo, se despliega solo, sin intervención humana. Cada
commitque pasa los tests llega a producción automáticamente.
La distinción importa menos que la idea de fondo: el camino está automatizado y es siempre el mismo, se ejecute cuando se ejecute. Un pipeline típico se ve así:
graph LR
A["push a git"] --> B["BUILD<br/>compila /<br/>empaqueta"]
B --> C["TEST<br/>unitarios +<br/>integración"]
C --> D["ARTEFACTO<br/>imagen inmutable<br/>versionada"]
D --> E["DEPLOY staging<br/>entorno de pruebas"]
E --> F["¿pruebas<br/>OK?"]
F -->|"sí"| G["DEPLOY producción"]
F -->|"no"| H["parar +<br/>avisar"]
Por qué esto reduce el riesgo, que es la clave y no siempre es obvio: el riesgo de un despliegue no es fijo, crece con el tamaño del cambio y con lo manual que sea el proceso. Un pipeline automatizado ataca las dos cosas: te empuja a integrar cambios pequeños (menos superficie donde algo puede fallar) y elimina el paso humano donde se cometen errores. Además, como es el mismo proceso siempre, cuando falla sabes que el problema está en tu cambio, no en que "hoy Manolo se saltó el paso 7 del documento".
La CI no sustituye a los tests, los hace útiles
Una pipeline de CI sin una buena batería de tests es un cronómetro caro: te dice rápido que "compila", que es lo de menos. El valor está en que haya tests que de verdad comprueben comportamiento y que la CI los ejecute sin falta en cada cambio. La automatización amplifica lo que tengas: si tienes buenos tests, te da confianza; si no los tienes, te da una falsa sensación de seguridad.
3. Contenedores (Docker): empaquetar el entorno con la app¶
Volvamos al "en mi máquina funciona". La causa real es que un programa no vive solo: depende de una versión concreta del lenguaje, de librerías del sistema, de variables de entorno, de que exista tal carpeta, de la zona horaria... todo eso es el entorno. Tu máquina tiene un entorno; el servidor tiene otro sutilmente distinto; y esas diferencias invisibles son las que rompen el despliegue.
La idea del contenedor es brutalmente simple y por eso es tan potente: empaqueta la aplicación junto con su entorno en una única unidad sellada —la imagen— que se ejecuta igual en cualquier sitio que sepa correr contenedores. No mandas "el código y crucemos los dedos con que el servidor tenga lo necesario"; mandas una caja cerrada que ya lleva todo lo necesario dentro.
graph TB
subgraph IMG["Imagen de contenedor · la «caja sellada»"]
direction TB
APP["tu aplicación"]
LIB["librerías + dependencias<br/>versiones exactas"]
RT["runtime del lenguaje<br/>(PHP 8.2, Node 20...)"]
SYS["utilidades del sistema<br/>que necesita"]
end
IMG -->|"corre IGUAL en"| L["tu portátil"]
IMG --> S["staging"]
IMG --> P["producción"]
Dos propiedades hacen la magia:
- Reproducibilidad. La imagen se construye a partir de una receta escrita (un
Dockerfile): "parte de esta base, instala estas versiones exactas, copia mi código". La misma receta produce la misma caja siempre. El entorno deja de ser algo que "está" en un servidor (y que nadie recuerda cómo se montó) para ser algo descrito en un fichero versionado en git, igual que el código. - Inmutabilidad. Una imagen, una vez construida, no se toca. No entras a "parchear" el contenedor en caliente. Si necesitas un cambio, construyes una imagen nueva y sustituyes la vieja entera. Esto elimina la peor plaga de operaciones: el servidor mascota (snowflake), esa máquina única que alguien fue tocando a mano durante años, que nadie se atreve a reiniciar y que es imposible de replicar. Con inmutabilidad, tus servidores son ganado, no mascotas: intercambiables, desechables, recreables desde cero.
Contenedor no es lo mismo que máquina virtual
Una máquina virtual emula un ordenador entero, con su propio sistema operativo completo encima del tuyo: pesada y lenta de arrancar (minutos, gigas). Un contenedor comparte el núcleo del sistema operativo de la máquina anfitriona y solo aísla lo de la aplicación: ligero y casi instantáneo (segundos, megas). Por eso puedes tener decenas de contenedores donde tendrías una o dos VMs. El aislamiento es un poco menor, pero para la inmensa mayoría de casos sobra.
4. Orquestación (Kubernetes): cuándo la necesitas y cuándo NO¶
Vale, tienes tus contenedores. Con dos o tres en un servidor, los levantas a mano (o con un docker compose) y ya. Pero imagina que tu sistema son 200 contenedores repartidos por 40 máquinas, y que:
- Si una máquina se muere, sus contenedores deben resucitar en otra automáticamente.
- Si llega un pico de tráfico, hacen falta más copias del contenedor web, y menos cuando el pico pasa.
- Al desplegar una versión nueva, hay que ir sustituyendo copias poco a poco sin cortar el servicio.
- Los contenedores necesitan encontrarse entre sí aunque cambien constantemente de máquina.
Hacer todo eso a mano es imposible. Un orquestador —el estándar de facto es Kubernetes— es el "director de orquesta" que lo automatiza. Le dices el estado deseado ("quiero 5 copias de este servicio, siempre") de forma declarativa, y él se encarga de que la realidad coincida: si una copia se cae, la levanta; si una máquina muere, redistribuye; si pides más, escala. Tú describes el qué, no el cómo.
graph TB
DES["Estado deseado<br/>«5 copias del servicio web,<br/>siempre en pie»"] --> K["Orquestador<br/>(Kubernetes)"]
K -->|"vigila y corrige"| REAL["Estado real"]
REAL -->|"¿solo hay 4?<br/>una se cayó"| K
K -->|"levanta una nueva"| REAL
Ahora la parte que casi ningún tutorial te dice, y que es criterio puro: Kubernetes es carísimo en complejidad, y la mayoría de proyectos no lo necesitan. Es una pieza pensada para el problema de Google (miles de servicios, escala planetaria). Si tú tienes una aplicación web normal con tráfico normal, meter Kubernetes es como comprar un tráiler de 18 ruedas para ir a comprar el pan: pagas un coste operativo enorme —hay que aprenderlo, mantenerlo, depurarlo— para resolver un problema que no tienes.
La regla honesta sobre Kubernetes
No necesitas orquestación hasta que gestionar los contenedores a mano se convierta en tu cuello de botella real. Señales de que quizá ha llegado el momento: muchos servicios distintos, necesidad de escalar y desescalar solo, varios equipos desplegando de forma independiente, requisitos serios de alta disponibilidad. Si no tienes esas señales, un par de servidores con contenedores y un deploy automatizado te llevan lejísimos, con una fracción del dolor. Adoptar Kubernetes "porque es lo que se lleva" es una de las decisiones que más tiempo hace perder a equipos pequeños. Empieza simple; añade orquestación cuando el dolor lo pida, no antes.
5. Infraestructura como código (IaC)¶
Si el código de la app está en git y los contenedores se describen en un fichero... ¿por qué la infraestructura (los servidores, las redes, las bases de datos, los balanceadores) se sigue montando a mano haciendo clic en la consola web del proveedor?
La respuesta de DevOps es: no debería. La infraestructura como código (Infrastructure as Code, IaC) consiste en describir tu infraestructura en ficheros de texto versionados, y que una herramienta la cree y modifique a partir de esa descripción. En vez de "entré al panel, creé un servidor, le puse tal configuración" (un acto irrepetible que solo vive en la memoria de quien lo hizo), tienes un fichero que dice "quiero un servidor así, con esta red, esta base de datos" y lo aplicas.
Las ventajas son las mismas que ya has visto, aplicadas a la infra:
- Reproducible: puedes recrear el entorno entero desde cero. Si un centro de datos arde, levantas todo en otro aplicando los mismos ficheros.
- Versionado y revisable: los cambios de infraestructura pasan por git, se revisan en un
pull request, tienen historial. Sabes quién cambió qué y por qué, y puedes volver atrás. - Sin snowflakes: nadie "toca el servidor a mano" y crea una configuración única que nadie más entiende. La verdad está en el fichero.
Es la misma filosofía de siempre —la verdad vive en git, no en la cabeza de alguien ni en el estado mutable de una máquina— extendida a lo que sostiene la aplicación.
6. Configuración y secretos por entorno¶
Una imagen de contenedor es inmutable y la misma en desarrollo, staging y producción —eso era justo la gracia—. Pero entonces surge una pregunta: la URL de la base de datos, las claves de API, las contraseñas... son distintas en cada entorno. Si las metes dentro de la imagen, rompes la inmutabilidad (necesitarías una imagen por entorno) y, peor, acabas con contraseñas de producción escritas en el código, dentro de git, visibles para todos. Desastre de seguridad clásico.
La regla —viene de la metodología Twelve-Factor App— es: la configuración que cambia entre entornos va FUERA del artefacto, y se le inyecta al contenedor al arrancar (típicamente como variables de entorno). La misma imagen inmutable, alimentada con distinta configuración según dónde corra:
graph TB
IMG["Imagen inmutable<br/>(idéntica en todos lados)"] --> DEV["+ config DEV<br/>(BD local, claves de prueba)"]
IMG --> STG["+ config STAGING"]
IMG --> PRD["+ config PROD<br/>(BD real, claves reales)"]
DEV --> RD["corre en desarrollo"]
STG --> RS["corre en staging"]
PRD --> RP["corre en producción"]
Y dentro de la configuración hay una categoría especial: los secretos (contraseñas, claves privadas, tokens). Estos nunca deben acabar en git en texto plano. Se guardan en un gestor de secretos —una bóveda cifrada, un servicio dedicado del proveedor de nube— y se inyectan al arrancar, igual que el resto de config pero con acceso controlado y auditado. La regla de oro que debe grabarse: si un secreto aparece en un commit, considéralo comprometido y rótalo, porque el historial de git es para siempre y borrarlo no basta.
7. Estrategias de despliegue: pequeño y frecuente gana¶
Llegamos al corazón operativo. La intuición ingenua dice: "desplegar es arriesgado, así que hagámoslo poco —una vez al mes— y con mucho cuidado". Es exactamente al revés, y entender por qué es de lo más valioso de toda la lección.
Cuando despliegas una vez al mes, cada despliegue acumula cientos de cambios. Si algo se rompe, tienes que buscar la aguja del fallo en un pajar de cientos de cambios entrelazados; el rollback es aterrador porque no sabes qué otra cosa arrastras; y como cada despliegue es un evento raro y traumático, nunca te vuelves bueno haciéndolo (lo que se hace poco se hace mal). El riesgo por despliegue es enorme.
Cuando despliegas muchas veces al día, cada despliegue lleva un puñado de cambios pequeños. Si algo se rompe, el culpable está entre cuatro líneas y lo encuentras enseguida; volver atrás es trivial; y como despliegas constantemente, el proceso está tan engrasado y automatizado que es un no-evento aburrido. El riesgo por despliegue es minúsculo. La conclusión, contraintuitiva pero robusta: desplegar mucho y pequeño es mucho más seguro que desplegar poco y grande. El tamaño del batch es el rey del riesgo.
Para que "desplegar" no signifique "cortar el servicio", existen estrategias que evitan el apagón:
- Blue-green: mantienes dos entornos idénticos, azul (el que sirve ahora) y verde (el nuevo). Despliegas la versión nueva en el verde con calma, lo pruebas, y cuando está listo rediriges todo el tráfico de golpe de azul a verde. Si algo va mal, vuelves a azul al instante. El
rollbackes "apunta otra vez al que funcionaba". - Canary (canario): en vez de cambiar a todos de golpe, mandas la versión nueva a un pequeño porcentaje de usuarios (el "canario en la mina"). Vigilas: si los errores no suben, vas subiendo el porcentaje poco a poco hasta el 100%. Si el canario "muere" (los errores se disparan), retiras la versión afectando solo a ese pequeño grupo. Limita el radio de la explosión.
- Rollback: la red de seguridad transversal. Poder volver a la versión anterior de forma rápida y fiable es la diferencia entre un susto de dos minutos y una noche en vela. Y aquí la inmutabilidad paga: como la versión anterior es una imagen sellada que sigue existiendo, "volver atrás" es arrancarla otra vez, no "deshacer cambios" a mano rezando.
graph LR
subgraph CAN["Despliegue canary"]
NEW["versión nueva"] -->|"5% del tráfico"| U1["usuarios canario"]
OLD["versión actual"] -->|"95% del tráfico"| U2["resto de usuarios"]
end
U1 -->|"¿errores estables?"| DEC{"decisión"}
DEC -->|"sí → subir a 100%"| WIN["despliegue completo"]
DEC -->|"no → retirar"| BACK["rollback, solo afectó al 5%"]
8. El ciclo de feedback rápido: lo que une todo¶
Si tuvieras que resumir DevOps en una sola idea mecánica, sería esta: acortar el bucle de retroalimentación entre "hago un cambio" y "sé si fue bien o mal".
- La CI te dice en minutos si tu cambio rompe los tests (feedback rápido en la construcción).
- El despliegue automatizado te lleva a producción en minutos, no semanas (feedback rápido en la entrega).
- La observabilidad —métricas, logs, alertas, que tiene su propia lección en Observabilidad— te dice en minutos si en producción va bien o mal (feedback rápido en operación).
- El canary y el rollback te dejan reaccionar a ese feedback sin drama.
Cada pieza técnica de esta lección existe para cerrar el bucle antes. Un bucle largo (te enteras de que rompiste algo tres semanas después) es lo que hace que el software sea caro, lento y aterrador. Un bucle corto (te enteras en minutos, arreglas en minutos, despliegas en minutos) es lo que hace que un equipo pueda moverse rápido sin romper cosas, que es la promesa entera de DevOps.
Cómo se ve en la práctica¶
Aterricemos todo esto en el flujo más común que te vas a encontrar, sin depender de ninguna herramienta concreta. Un desarrollador arregla un bug:
graph LR
A["1 · edita<br/>en local"] --> B["2 · push a git"]
B --> C["3 · CI: build<br/>+ tests"]
C --> D["4 · construye imagen<br/>inmutable versionada"]
D --> E["5 · el servidor hace<br/>pull + deploy"]
E --> F["6 · observabilidad<br/>confirma que va bien"]
Paso a paso, con la lección puesta encima:
- Edita en local. Trabaja en un cambio pequeño, no en un monstruo de tres semanas (recuerda: batch pequeño = riesgo pequeño).
pusha git. git es la única fuente de verdad: el código, la receta del contenedor y la descripción de la infra viven ahí. Nada de tocar el servidor a mano.- CI arranca sola. Compila y pasa los tests. Si algo rompe, el
pipelinese para y avisa; el cambio no llega a producción. Feedback en minutos. - Se construye la imagen inmutable, versionada. Esa caja sellada es exactamente lo que probaste; no hay "y en el servidor a ver qué pasa".
- El servidor hace
pull+deploy. Baja la imagen nueva y la despliega, idealmente sin cortar el servicio (blue-green o canary). La configuración y los secretos de producción se inyectan al arrancar, fuera de la imagen. - La observabilidad confirma. Si las métricas se disparan, salta la alerta y el
rollbackdevuelve la imagen anterior en segundos.
Fíjate en lo que NO hay
En este flujo no hay un documento de Word con 30 pasos manuales, no hay "el viernes por la noche montamos el despliegue", no hay "¿quién sabía cómo se configuraba este servidor?". El camino del código a producción es corto, automático y repetible. Eso es DevOps hecho, no comprado. Y fíjate en que no aparece Kubernetes por ningún lado: este flujo completo funciona perfectamente con un par de servidores y contenedores. La orquestación se añade cuando el dolor lo pide, no de entrada.
Lo que sacrificas / errores comunes¶
- Confundir herramientas con cultura. Instalar Jenkins, Docker y Kubernetes y creer que ya "haces DevOps" mientras el muro entre desarrollo y operaciones sigue intacto y cada caída acaba en caza de brujas. Las herramientas sin el cambio de responsabilidad son postureo caro.
- Adoptar Kubernetes por defecto. El error de complejidad más común de la década. Un equipo pequeño con una app normal que se mete en Kubernetes paga un peaje operativo brutal para resolver un problema de escala que no tiene. Empieza simple.
- Automatizar el caos. Si tu proceso manual es un desastre, automatizarlo te da un desastre que ocurre más rápido y a mayor escala. Primero entiende y simplifica el proceso; luego automatízalo.
- CI verde con cero tests de verdad. Una
pipelineque solo comprueba que compila da una falsa sensación de seguridad. La CI amplifica la calidad de tus tests; si no tienes buenos tests, no tienes red. - Secretos en git. Meter una contraseña en un
commit"temporalmente". El historial de git es para siempre; una vez ahí, el secreto está comprometido aunque lo borres después. - Creer que DevOps es un puesto. "Contratemos a un DevOps" que se siente en una esquina a mantener los
pipelines. Eso recrea el muro con otro nombre: vuelve a haber un intermediario entre desarrollo y operaciones. DevOps es una forma de trabajar del equipo entero, no una persona. - Desplegar poco "para reducir riesgo". La intuición que sale cara: acumular cambios hace cada despliegue más grande, más arriesgado y más raro (y por tanto peor ejecutado). Lo seguro es lo contrario.
Resumen¶
- DevOps derriba el muro entre desarrollo y operaciones haciendo que un mismo equipo sea dueño del ciclo de vida completo. Es cultura y responsabilidad compartida antes que herramientas.
- CI/CD automatiza el camino del
commita producción: la CI compila y testea en cadapush(feedback en minutos); el CD lo lleva a producción por un camino siempre igual. Reduce riesgo empujando a cambios pequeños y quitando pasos manuales. - Los contenedores empaquetan la app con su entorno en una imagen inmutable y reproducible, matando el "en mi máquina funciona". La verdad del entorno vive en un fichero versionado, no en un servidor mascota.
- La orquestación (Kubernetes) resuelve gestionar muchos contenedores a gran escala, y la mayoría de proyectos NO la necesitan. Añádela cuando el dolor lo pida. Junto a ella: infraestructura como código y config/secretos inyectados por entorno, fuera del artefacto.
- Desplegar mucho y pequeño es más seguro que poco y grande. Con blue-green, canary y
rollbackfiable, desplegar deja de dar miedo. Todo se reduce a acortar el bucle de feedback entre hacer un cambio y saber si fue bien.
Ejercicios socráticos¶
No busques la respuesta fuera. Razónala con las ideas de esta lección. Si te atascas, la pista está en el propio texto.
- Un equipo compra Kubernetes, monta
pipelinesde CI/CD y usa contenedores, pero cada caída en producción sigue terminando en una reunión buscando al culpable, y los desarrolladores han dejado de desplegar los viernes por miedo. ¿Tienen DevOps? Justifica qué les falta y por qué las herramientas no lo arreglan. - Explica con tus palabras por qué desplegar una vez al mes es más arriesgado que desplegar diez veces al día, si en apariencia "tocar producción menos veces" debería ser más seguro. ¿Qué variable es la que de verdad manda en el riesgo?
- Tu compañero quiere meter la contraseña de la base de datos de producción dentro de la imagen del contenedor "para que sea autocontenida y no dependa de nada externo". Dale las dos razones por las que es mala idea (una de arquitectura, una de seguridad) y di cómo se hace bien.
- Una imagen de contenedor es inmutable, la misma en todos los entornos. Entonces, ¿cómo puede la aplicación conectarse a una base de datos distinta en desarrollo y en producción sin construir dos imágenes? Y a partir de ahí: ¿por qué la inmutabilidad hace que el
rollbacksea trivial? - Un
pipelinede CI está siempre en verde y el equipo despliega con total confianza. Aun así, losbugsllegan constantemente a producción. Con lo que sabes de la relación entre CI y tests, ¿qué está pasando y por qué el verde engaña?
Repaso espaciado¶
Pasa estas a Anki (
repasos.md). Formato: pregunta que obligue a razonar, no a reconocer.
- [ ] ¿Cuál es el problema de fondo que resuelve DevOps, y por qué "responsabilidad compartida del ciclo de vida" es el mecanismo y no solo un valor bonito?
- [ ] Distingue qué automatiza la CI de qué automatiza el CD, y explica por qué cada uno acorta el bucle de feedback.
- [ ] ¿Qué dos propiedades de los contenedores (empieza por "in..." y "re...") matan el "en mi máquina funciona", y cómo lo hacen?
- [ ] ¿Cuándo SÍ y cuándo NO necesitas un orquestador como Kubernetes? Da la señal concreta que indica que ha llegado el momento.
- [ ] ¿Por qué desplegar en
batchespequeños y frecuentes reduce el riesgo? Nombra dos estrategias que permiten desplegar sin cortar el servicio.
Para seguir tirando del hilo¶
- The Phoenix Project (Kim, Behr, Spafford) — novela sobre una empresa ahogada por el muro entre desarrollo y operaciones; la mejor forma de sentir por qué DevOps es cultura antes que herramientas.
- Accelerate (Forsgren, Humble, Kim) — la evidencia con datos: qué prácticas (despliegue frecuente,
lead timecorto,rollbackrápido) correlacionan de verdad con equipos de alto rendimiento. - Continuous Delivery (Humble, Farley) — la referencia detallada sobre
pipelines, despliegue y automatización del camino a producción. - The Twelve-Factor App (12factor.net) — breve y gratis; el origen de la regla de sacar la configuración del artefacto e inyectarla por entorno.
- Experimento: coge una app tuya, escríbele un
Dockerfiley arráncala en un contenedor. Luego bórrala de tu máquina y levántala solo desde la imagen. Ver que corre "sin instalar nada" asienta la idea de empaquetar el entorno más que releerla.