Pods, Deployments y Services en Kubernetes: guía completa
Si ya tienes claro qué es Kubernetes, es hora de profundizar en los tres objetos que más vas a usar en el día a día: Pods, Deployments y Services. En este post te explico cómo funcionan en detalle con ejemplos reales de YAML listos para usar. Si aún no has leído la introducción, empieza por el post de Kubernetes para principiantes.
Pods en Kubernetes: más de lo que parece
Un Pod es la unidad mínima desplegable en Kubernetes. Contiene uno o varios contenedores que comparten la misma red y almacenamiento. Aunque en la práctica casi siempre hay un solo contenedor por Pod, el patrón multi-contenedor (sidecar) es muy común en producción.
Manifiesto YAML de un Pod
apiVersion: v1
kind: Pod
metadata:
name: mi-app
labels:
app: mi-app
env: produccion
spec:
containers:
- name: mi-app
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
env:
- name: NODE_ENV
value: "production"
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
Liveness vs Readiness Probe
| Probe | Para qué sirve | Qué hace si falla |
|---|---|---|
| livenessProbe | Comprueba si el contenedor está vivo | Reinicia el contenedor |
| readinessProbe | Comprueba si está listo para recibir tráfico | Lo saca del Service (no recibe peticiones) |
| startupProbe | Para apps lentas en arrancar | Espera antes de activar las otras probes |
Comandos útiles para Pods
# Ver todos los pods con más detalle
kubectl get pods -o wide
# Ver el YAML completo de un pod
kubectl get pod mi-app -o yaml
# Ver logs
kubectl logs mi-app
kubectl logs mi-app -f # en tiempo real
kubectl logs mi-app --previous # último crash
# Acceder al pod
kubectl exec -it mi-app -- bash
# Copiar archivos al/del pod
kubectl cp mi-app:/var/log/app.log ./app.log
kubectl cp ./config.yaml mi-app:/app/config.yaml
# Ver métricas del pod
kubectl top pod mi-app
Deployments en Kubernetes: la forma correcta de desplegar
En producción nunca creas Pods directamente — usas Deployments. Un Deployment gestiona el ciclo de vida de tus Pods: cuántas réplicas quieres, cómo actualizar la imagen sin downtime, y cómo volver atrás si algo falla.
Manifiesto YAML de un Deployment completo
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-app
namespace: produccion
spec:
replicas: 3
selector:
matchLabels:
app: mi-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # pods extra durante la actualización
maxUnavailable: 0 # ningún pod caído durante la actualización
template:
metadata:
labels:
app: mi-app
version: "1.0"
spec:
containers:
- name: mi-app
image: mi-registry/mi-app:1.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
envFrom:
- configMapRef:
name: mi-app-config
- secretRef:
name: mi-app-secrets
Gestionar Deployments
# Aplicar el deployment
kubectl apply -f deployment.yaml
# Ver el estado del rollout en tiempo real
kubectl rollout status deployment/mi-app
# Actualizar la imagen
kubectl set image deployment/mi-app mi-app=mi-registry/mi-app:2.0
# Ver historial de versiones
kubectl rollout history deployment/mi-app
# Volver a la versión anterior
kubectl rollout undo deployment/mi-app
# Volver a una versión específica
kubectl rollout undo deployment/mi-app --to-revision=2
# Escalar
kubectl scale deployment/mi-app --replicas=5
# Autoscaling basado en CPU
kubectl autoscale deployment/mi-app --min=3 --max=10 --cpu-percent=70
# Pausar un rollout
kubectl rollout pause deployment/mi-app
kubectl rollout resume deployment/mi-app
Estrategias de actualización
| Estrategia | Cómo funciona | Downtime | Cuándo usarla |
|---|---|---|---|
| RollingUpdate | Actualiza pods de uno en uno | No | La mayoría de casos |
| Recreate | Para todos los pods y los recrea | Sí | Apps que no soportan múltiples versiones |
Services en Kubernetes: cómo exponer tus aplicaciones
Los Pods tienen IPs efímeras que cambian cada vez que se recrean. Un Service proporciona una IP y un nombre DNS estables para acceder a un grupo de Pods, independientemente de dónde estén ejecutándose en el cluster.
ClusterIP: comunicación interna
apiVersion: v1
kind: Service
metadata:
name: mi-app-svc
spec:
selector:
app: mi-app # se conecta a los pods con este label
ports:
- port: 80 # puerto del Service
targetPort: 8080 # puerto del contenedor
type: ClusterIP # solo accesible dentro del cluster
NodePort: acceso desde fuera del cluster
apiVersion: v1
kind: Service
metadata:
name: mi-app-nodeport
spec:
selector:
app: mi-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # puerto en cada nodo (30000-32767)
type: NodePort
LoadBalancer: para producción en cloud
apiVersion: v1
kind: Service
metadata:
name: mi-app-lb
spec:
selector:
app: mi-app
ports:
- port: 80
targetPort: 8080
type: LoadBalancer # crea un balanceador externo en GCP, AWS, Azure
Comandos útiles para Services
# Ver todos los services
kubectl get services
# Ver detalles de un service
kubectl describe service mi-app-svc
# Ver endpoints (pods conectados al service)
kubectl get endpoints mi-app-svc
# Exponer un deployment directamente
kubectl expose deployment mi-app --port=80 --target-port=8080
# Port-forward para probar localmente sin LoadBalancer
kubectl port-forward service/mi-app-svc 8080:80
Flujo completo: desplegar una app en Kubernetes
# 1. Crear el namespace
kubectl create namespace mi-proyecto
# 2. Aplicar el Deployment
kubectl apply -f deployment.yaml -n mi-proyecto
# 3. Verificar que los pods están corriendo
kubectl get pods -n mi-proyecto
# 4. Aplicar el Service
kubectl apply -f service.yaml -n mi-proyecto
# 5. Verificar el service y obtener la IP/URL
kubectl get service mi-app-svc -n mi-proyecto
# 6. Probar localmente con port-forward
kubectl port-forward service/mi-app-svc 8080:80 -n mi-proyecto
Conclusión
Pods, Deployments y Services son el ABC de Kubernetes. Con estos tres objetos puedes desplegar cualquier aplicación de forma robusta, escalarla y exponerla al mundo. El siguiente paso es aprender a diagnosticar problemas — si te encuentras con errores, el post sobre CrashLoopBackOff en Kubernetes te ayudará.
En el próximo post veremos ImagePullBackOff en Kubernetes: causas y soluciones. Tienes alguna duda sobre Pods, Deployments o Services? Déjala en los comentarios.
