From n00b to ZeroCool / Profesionalización
Kubernetes, el jefe final del cloud native (y cómo no morir en el intento)
Kubernetes sin humo: qué resuelve, conceptos clave y guía práctica para deploy, debug y operación. Tips reales para sobrevivir producción.
Lo que vale la pena leer aquí
Una noche cualquiera: ya se acabó el sprint, el release “era de puro config”, y de pronto el chat explota.
Una noche cualquiera: ya se acabó el sprint, el release “era de puro config”, y de pronto el chat explota.
—“Banda, el servicio no responde en production.”
—“Pero en mi máquina sí jalaba.”
—“¿Quién movió el Ingress?”
Abres la laptop ya guerrera (12% de batería porque el multicontacto del cowork murió), te conectas a la VPN que a veces sí y a veces no, y ahí está: Kubernetes.
El jefe final no porque sea “malo”, sino porque te obliga a jugar con mecánicas nuevas: declarativo, reconciliación, control loops, networking, permisos, recursos… y una cantidad ofensiva de YAML.
La neta: K8s te da superpoderes, pero te cobra en complejidad. Si lo adoptas por moda, se vuelve monstruo. Si lo entiendes con calma, es de lo más sólido para correr software serio sin vivir apagando fuegos.
Qué te vas a llevar
- Qué problema sí resuelve Kubernetes (y cuándo ni lo voltees a ver).
- Los conceptos que realmente necesitas para operar sin pánico: Pod, Deployment, Service, Ingress, ConfigMap/Secret, Namespace.
- Una guía paso a paso para:
- levantar un cluster local,
- hacer deploy de un servicio,
- exponerlo,
- debuggear cuando truena,
- y aplicar buenas prácticas de “producción básica”.
- Errores comunes (de los que sí salen en el jale) y cómo salir en corto.
Por qué Kubernetes se siente como “jefe final”
Antes del cloud native, muchas personas vivimos el caminito clásico:
- “Sube el jar/php/node al server y reinicia.”
- “Ya somos 3 servers, hagamos un script.”
- “Ahora hay 10, usemos Ansible/Terraform.”
- “Metamos Docker para que no se rompa el setup.”
- “Y ahora… ¿cómo orquestamos 50 contenedores con autoscaling, rollouts y health checks?”
Ahí entra Kubernetes: un orquestador que mantiene tu estado deseado. Tú declaras “quiero 3 réplicas”, K8s se encarga de que existan; si una muere, la repone. No es magia: son controladores trabajando 24/7 para que el cluster se parezca a tu YAML.
¿Cuándo sí conviene?
- Tienes varios servicios (o vas para allá) y quieres deploys repetibles.
- Te importa el rolling update sin downtime.
- Necesitas autoscaling (aunque sea básico por CPU/RAM).
- Quieres estandarizar runtime y operación entre equipos sin reinventar la rueda.
¿Cuándo no?
- Un solo servicio, tráfico estable, equipo chico, y el “tiempo de operar” vale oro.
- No tienes CI/CD ni observabilidad: K8s no te la regala, te la exige.
- Tu app depende de stateful pesado (DBs, colas, storage) y quieres “meterlo al cluster” nomás porque sí.
Decisión práctica: Kubernetes no es requisito para ser pro. Es una herramienta. Úsala cuando tu complejidad lo amerite, no cuando te lo pida un post de LinkedIn o el vendor.
Guía principal: tu primer deploy bien hecho (con debug de verdad)
La meta: correr un servicio web simple en Kubernetes, exponerlo y aprender a diagnosticarlo cuando algo se rompe (porque se va a romper).
1) Levanta un cluster local sin sufrir de gratis
Opciones decentes:
- minikube (clásico, completo)
- kind (Kubernetes in Docker, buenísimo para tests)
- Docker Desktop Kubernetes (cómodo, pero a veces opaco)
Ejemplo con kind:
kind create cluster --name byteit
kubectl cluster-info
kubectl get nodes
Si kubectl no pega, casi siempre es contexto:
kubectl config get-contexts
kubectl config use-context kind-bytheit
Escena real: en oficina/escuela, el Wi‑Fi corporativo bloquea medio mundo o el proxy te mete zancadilla. Cluster local te salva para practicar sin depender de la red.
2) Crea un Namespace (porque production no es tu playground)
Evita tirar todo en default. Te ayuda a aislar, limpiar y controlar permisos.
kubectl create namespace demo
kubectl config set-context --current --namespace=demo
3) Deploy de una app (Deployment + Service)
Usaremos nginx para enfocarnos en Kubernetes. El workflow aplica igual para tu API.
Crea deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
Crea service.yaml:
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
Aplica:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl get deploy,po,svc
Decisión práctica: requests/limits no son adorno. Sin requests, el scheduler adivina. Sin límites, un bug o un spike te puede tumbar el nodo y arrastrar a otros.
4) Acceso local (port-forward) para validar rápido
kubectl port-forward svc/web-svc 8080:80
Abre http://localhost:8080.
Tip de vida real: cuando estás atorado con IPs, DNS y firewalls de “levanta ticket y te contestan en 3 días”, port-forward es tu “déjame confirmar que sí corre” inmediato.
5) Debug básico cuando algo no levanta
Este combo te resuelve 80% de broncas:
kubectl get pods
kubectl describe pod <pod>
kubectl logs <pod>
kubectl logs <pod> -c <container>
Si el Pod no arranca:
ImagePullBackOff: imagen privada, tag inexistente, credenciales.CrashLoopBackOff: tu app arranca y muere (config, env vars, puertos, migraciones).Pending: no hay recursos, afinidad, taints, requests imposibles.
6) Configuración sin rebuild: ConfigMap y Secret
ConfigMap para config no sensible:
kubectl create configmap web-config --from-literal=APP_MODE=demo
Secret para cosas sensibles (ojo: en K8s base64 no es “encriptado”, es “codificado”):
kubectl create secret generic web-secret --from-literal=API_KEY="cambia-esto"
Móntalos como env vars (fragmento para tu Deployment):
env:
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: web-config
key: APP_MODE
- name: API_KEY
valueFrom:
secretKeyRef:
name: web-secret
key: API_KEY
Tradeoff real: si tu organización trae compliance encima, tarde o temprano terminas en External Secrets + un vault (AWS Secrets Manager, GCP Secret Manager, Vault). Porque “Secret en etcd” puede ser suficiente… o un riesgo, según tu threat model.
7) Exponer hacia afuera: Ingress (cuando ya es “de verdad”)
En local puedes vivir con port-forward. En un cluster real vas a querer Ingress.
Primero necesitas un Ingress Controller (nginx, traefik, etc.). En kind/minikube es instalable; en managed K8s a veces ya viene como add‑on.
Ejemplo de Ingress (ingress.yaml):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
rules:
- host: web.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
Tu DNS local puede ser /etc/hosts apuntando a la IP del ingress (en producción sería un LB + DNS real).
Decisión práctica: Ingress te da rutas y control, pero también mete complejidad (certificados, controllers, annotations). Si tu app es interna, a veces un Service ClusterIP + gateway interno es más simple y menos frágil.

Screenshots sugeridos (para que quede bien usable)
kubectl get pods -o widemostrando estados (Running/Pending/CrashLoopBackOff).- Pantalla de
kubectl describe podcon eventos (ImagePullBackOff, failed scheduling, probes failed). kubectl get svcy el port-forward funcionando en el navegador.- YAML del Deployment con probes y resources resaltados.
- Si usas Ingress:
kubectl get ingressy el host resolviendo.
Errores comunes (los que sí te pasan en producción) + salida
1) “Mi Pod está Running pero no responde”
Causa típica: tu app escucha en 127.0.0.1 dentro del contenedor, no en 0.0.0.0.
- Revisa el puerto:
kubectl exec -it <pod> -- sh netstat -tulpn || ss -tulpn - Arreglo: configura tu server para bind
0.0.0.0.
2) Readiness/Liveness mal puestas y te autosaboteas
Si tu readinessProbe falla, el Service deja de mandarte tráfico (bien). Si tu livenessProbe falla, K8s te reinicia (también bien… hasta que te mete en un loop infernal).
Solución práctica:
- Readiness: endpoint ligero, sin dependencias frágiles.
- Liveness: más tolerante, con delays realistas.
- Si tu app tarda en arrancar, usa
startupProbe.
3) “Funcionaba ayer y hoy no”: tags latest y deploys no deterministas
Causa: la imagen cambió pero el tag no. Kubernetes cree que ya la tiene.
Solución:
- Usa tags inmutables (
1.2.3o mejor digestsha256). - En CI, publica imagen con SHA del commit.
4) Te quedas sin recursos y el scheduler te manda a la banca (Pending)
Revisa:
kubectl describe pod <pod> | sed -n '/Events/,$p'
Solución:
- Ajusta
requestsa algo realista. - Si tu cluster es chico, acepta la realidad: necesitas más nodos o menos hambre.
5) “No puedo hacer kubectl, me marca forbidden”
Bienvenido a RBAC.
Solución:
- Confirma tu identidad/contexto.
- Pide/crea un Role/ClusterRole correcto.
- No uses
cluster-admincomo curita permanente; es deuda técnica con intereses.
Escena muy de jale: el admin se fue de vacaciones, tú entras a cubrir, y te dicen “pues súbele permisos mientras”. Se siente tentador. No lo hagas sin dejar evidencia y sin plan de rollback. Luego llega auditoría… o un incidente.

Checklist final (para sentirte más pro y menos improvisado)
- Tengo Namespaces por ambiente/equipo (y no todo vive en
default). - Mis Deployments tienen
readinessProbeylivenessProbe(y no están agresivas). - Definí
requestsylimits(y los medí en staging). - Uso tags inmutables para imágenes (nada de
latesten producción). - Mis configs están en ConfigMap/Secret o un gestor externo (con rotación si aplica).
- Sé dónde ver logs (
kubectl logs) y eventos (kubectl describe). - Tengo una ruta de rollback (Deployment rollout o GitOps).
- Tengo al menos métricas básicas (CPU/RAM, latencia, errores) antes de “escalarlo”.
FAQ
1) ¿Kubernetes es lo mismo que Docker?
No. Docker (o containerd) corre contenedores; Kubernetes los orquesta: scheduling, self‑healing, rollouts, networking, config, scaling.
2) ¿Necesito Kubernetes para ser cloud-native?
No necesariamente. Puedes armar un stack cloud-native con contenedores + CI/CD + observabilidad en una plataforma más simple. Kubernetes entra cuando la operación/escala lo justifica.
3) ¿Qué aprendo primero: Helm o YAML a mano?
Primero YAML a mano para entender qué estás aplicando. Luego Helm para empaquetar y versionar despliegues sin volverte loco copiando manifests.
4) ¿Qué es lo mínimo para que un cluster sea “operable” en producción?
Monitoreo (métricas), logging centralizado, backups si hay state, control de accesos (RBAC), y un proceso de deploy/rollback repetible. Sin eso, estás apostando.
5) ¿Cómo empiezo a debuggear sin perderme?
Orden rápido: kubectl get pods → describe (eventos) → logs → exec si necesitas asomarte. Y siempre verifica: imagen, env vars, puertos, probes y recursos.
Siguiente episodio
Cuando Kubernetes ya está corriendo, el siguiente monstruo es poder verlo: métricas, logs y trazas sin sentir que estás leyendo la Matrix.
Nos vamos a meter con observabilidad cloud-native para que los incidentes duren minutos, no toda la noche.
Idea para cerrar bien este post: toma una sola práctica de aquí y conviértela en algo que tu equipo pueda aplicar hoy.
Cuando un artículo aterriza en decisiones reales, deja de ser contenido y se vuelve ventaja.


