Kubernetes: Pods, Services, Deployments - Guía Completa
Comprender los Pods, Services y Deployments es fundamental para dominar Kubernetes. Estos recursos principales forman la base del despliegue y gestión de aplicaciones en clústeres de Kubernetes. Esta guía completa cubre conceptos, ejemplos prácticos y mejores prácticas de producción.
Tabla de Contenidos
- Introducción
- Requisitos Previos
- Pods
- Services
- Deployments
- ReplicaSets
- Labels y Selectors
- Rolling Updates y Rollbacks
- Mejores Prácticas de Producción
- Resolución de Problemas
- Conclusión
Introducción
Kubernetes orquesta aplicaciones en contenedores utilizando varios recursos clave:
- Pods: Unidades más pequeñas desplegables, encapsulando uno o más contenedores
- Services: Endpoints de red estables para acceder a los Pods
- Deployments: Actualizaciones declarativas para Pods y ReplicaSets
Jerarquía de Recursos
Deployment
└── ReplicaSet
└── Pod(s)
└── Container(s)
Requisitos Previos
- Clúster de Kubernetes (kubeadm, minikube o proveedor de nube)
- kubectl instalado y configurado
- Conocimientos básicos de contenedores y Docker
- Familiaridad con sintaxis YAML
Verificar configuración:
kubectl version --client
kubectl cluster-info
kubectl get nodes
Pods
Los Pods son la unidad atómica de despliegue en Kubernetes, representando uno o más contenedores estrechamente acoplados que comparten recursos.
Características del Pod
- Efímeros y desechables
- Comparten namespace de red (una sola IP)
- Comparten volúmenes de almacenamiento
- Se programan juntos en el mismo nodo
- Gestionados por controladores de nivel superior
Creando un Pod Simple
# simple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
environment: dev
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
# Crear pod
kubectl apply -f simple-pod.yaml
# Verificar estado del pod
kubectl get pods
# Describir pod
kubectl describe pod nginx-pod
# Eliminar pod
kubectl delete pod nginx-pod
Pod Multi-Contenedor
# multi-container-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: app
image: myapp:latest
ports:
- containerPort: 8080
volumeMounts:
- name: shared-data
mountPath: /app/data
- name: sidecar
image: log-collector:latest
volumeMounts:
- name: shared-data
mountPath: /logs
volumes:
- name: shared-data
emptyDir: {}
Pod con Límites de Recursos
# pod-resources.yaml
apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: app
image: nginx:alpine
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
Pod con Variables de Entorno
# pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DATABASE_HOST
value: "postgres.default.svc.cluster.local"
- name: DATABASE_PORT
value: "5432"
- name: API_KEY
valueFrom:
secretKeyRef:
name: api-credentials
key: api-key
Ciclo de Vida del Pod
# Verificar fases del pod
kubectl get pods -w
# Fases del pod:
# Pending - Esperando programación
# Running - Pod programado, contenedores en ejecución
# Succeeded - Todos los contenedores terminaron exitosamente
# Failed - Al menos un contenedor falló
# Unknown - El estado del pod no se puede determinar
Services
Los Services proporcionan redes estables para acceder a los Pods, ofreciendo balanceo de carga y descubrimiento de servicios.
Tipos de Service
- ClusterIP: Acceso solo dentro del clúster (predeterminado)
- NodePort: Expone en la IP de cada nodo en un puerto estático
- LoadBalancer: Balanceador de carga en la nube (requiere proveedor de nube)
- ExternalName: Mapea a nombre DNS externo
Service ClusterIP
# service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
type: ClusterIP
selector:
app: backend
tier: api
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
# Crear service
kubectl apply -f service-clusterip.yaml
# Acceder desde dentro del clúster
kubectl run curl --image=curlimages/curl -it --rm -- sh
# curl http://backend-service
Service NodePort
# service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # Opcional: 30000-32767
protocol: TCP
# Crear service
kubectl apply -f service-nodeport.yaml
# Acceder desde fuera del clúster
curl http://<NODE_IP>:30080
Service LoadBalancer
# service-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: LoadBalancer
selector:
app: frontend
ports:
- port: 80
targetPort: 3000
protocol: TCP
# Crear service
kubectl apply -f service-loadbalancer.yaml
# Obtener IP externa (puede tardar)
kubectl get service frontend-service
# Acceder vía IP externa
curl http://<EXTERNAL_IP>
Service con Afinidad de Sesión
# service-session.yaml
apiVersion: v1
kind: Service
metadata:
name: sticky-service
spec:
type: ClusterIP
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
selector:
app: web
ports:
- port: 80
targetPort: 8080
Service Headless
# service-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: database-service
spec:
clusterIP: None # Service headless
selector:
app: database
ports:
- port: 5432
targetPort: 5432
Deployments
Los Deployments proporcionan actualizaciones declarativas para Pods y ReplicaSets, habilitando escalado, rolling updates y rollbacks.
Deployment Básico
# deployment-basic.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
# Crear deployment
kubectl apply -f deployment-basic.yaml
# Verificar deployment
kubectl get deployments
kubectl get pods
# Escalar deployment
kubectl scale deployment nginx-deployment --replicas=5
# Eliminar deployment
kubectl delete deployment nginx-deployment
Deployment Listo para Producción
# deployment-production.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
environment: production
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
version: v1.0.0
spec:
containers:
- name: app
image: myapp:1.0.0
ports:
- containerPort: 8080
name: http
env:
- name: ENVIRONMENT
value: "production"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Deployment con ConfigMap y Secret
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: "postgres://db:5432"
log_level: "info"
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
db_password: cGFzc3dvcmQxMjM= # codificado en base64
---
# deployment-with-config.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- configMapRef:
name: app-config
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: db_password
ReplicaSets
Los ReplicaSets aseguran que un número especificado de réplicas de Pod estén ejecutándose. Típicamente gestionados por Deployments.
Ejemplo de ReplicaSet
# replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx:alpine
# Crear ReplicaSet
kubectl apply -f replicaset.yaml
# Verificar ReplicaSet
kubectl get replicasets
kubectl get pods
# Escalar ReplicaSet
kubectl scale replicaset frontend-replicaset --replicas=5
Labels y Selectors
Los Labels organizan y seleccionan objetos de Kubernetes. Los Selectors consultan objetos por labels.
Uso de Labels
# pod-with-labels.yaml
apiVersion: v1
kind: Pod
metadata:
name: labeled-pod
labels:
app: web
environment: production
tier: frontend
version: v1.2.3
spec:
containers:
- name: nginx
image: nginx:alpine
Selectores de Labels
# Basados en igualdad
kubectl get pods -l app=web
kubectl get pods -l environment=production
# Basados en conjuntos
kubectl get pods -l 'environment in (production, staging)'
kubectl get pods -l 'tier notin (database)'
# Múltiples condiciones
kubectl get pods -l app=web,environment=production
# Mostrar labels
kubectl get pods --show-labels
Agregar/Eliminar Labels
# Agregar label
kubectl label pods labeled-pod new-label=value
# Actualizar label
kubectl label pods labeled-pod environment=staging --overwrite
# Eliminar label
kubectl label pods labeled-pod environment-
Rolling Updates y Rollbacks
Realizar Rolling Update
# Actualizar imagen del deployment
kubectl set image deployment/nginx-deployment nginx=nginx:1.26-alpine
# O actualizar vía edición
kubectl edit deployment nginx-deployment
# Observar estado del rollout
kubectl rollout status deployment/nginx-deployment
# Verificar historial del rollout
kubectl rollout history deployment/nginx-deployment
Estrategia de Actualización
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # Máximo de pods por encima del conteo deseado
maxUnavailable: 25% # Máximo de pods no disponibles durante actualización
Rollback de Deployment
# Revertir a versión anterior
kubectl rollout undo deployment/nginx-deployment
# Revertir a revisión específica
kubectl rollout history deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2
# Pausar rollout
kubectl rollout pause deployment/nginx-deployment
# Reanudar rollout
kubectl rollout resume deployment/nginx-deployment
Mejores Prácticas de Producción
Solicitudes y Límites de Recursos
spec:
containers:
- name: app
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Health Checks
spec:
containers:
- name: app
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
Pod Disruption Budgets
# pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web
Anti-Afinidad para Alta Disponibilidad
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
Contexto de Seguridad
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Resolución de Problemas
Problemas con Pods
# Obtener detalles del pod
kubectl describe pod <pod-name>
# Ver logs
kubectl logs <pod-name>
kubectl logs <pod-name> --previous # Contenedor anterior
# Ejecutar en pod
kubectl exec -it <pod-name> -- sh
# Verificar eventos
kubectl get events --sort-by='.lastTimestamp'
Problemas con Services
# Verificar endpoints del service
kubectl get endpoints <service-name>
# Probar resolución DNS
kubectl run test --image=busybox:1.28 --rm -it -- nslookup <service-name>
# Verificar conectividad del service
kubectl run curl --image=curlimages/curl --rm -it -- curl http://<service-name>
Problemas con Deployments
# Verificar estado del deployment
kubectl get deployment <deployment-name>
kubectl describe deployment <deployment-name>
# Verificar ReplicaSet
kubectl get rs
kubectl describe rs <replicaset-name>
# Verificar estado del rollout
kubectl rollout status deployment/<deployment-name>
Problemas Comunes
# ImagePullBackOff
kubectl describe pod <pod-name> # Verificar nombre de imagen y credenciales
# CrashLoopBackOff
kubectl logs <pod-name> # Verificar logs de la aplicación
# Pods pendientes
kubectl describe pod <pod-name> # Verificar recursos del nodo y programación
# Service no accesible
kubectl get endpoints <service-name> # Verificar que los pods estén seleccionados
Conclusión
Los Pods, Services y Deployments forman el núcleo de la gestión de aplicaciones en Kubernetes. Comprender estos recursos es esencial para desplegar aplicaciones escalables y resilientes.
Puntos Clave
- Pods: Unidad más pequeña desplegable, efímera
- Services: Endpoints de red estables, balanceo de carga
- Deployments: Actualizaciones declarativas, escalado, rollbacks
- Labels: Organizan y seleccionan recursos
- Health Checks: Aseguran la fiabilidad de la aplicación
- Límites de Recursos: Previenen el agotamiento de recursos
Referencia Rápida
# Pods
kubectl get pods
kubectl describe pod <name>
kubectl logs <name>
kubectl exec -it <name> -- sh
kubectl delete pod <name>
# Services
kubectl get services
kubectl describe service <name>
kubectl get endpoints <name>
# Deployments
kubectl get deployments
kubectl describe deployment <name>
kubectl scale deployment <name> --replicas=5
kubectl set image deployment/<name> container=image:tag
kubectl rollout status deployment/<name>
kubectl rollout undo deployment/<name>
# Labels
kubectl get pods --show-labels
kubectl get pods -l app=web
kubectl label pods <name> key=value
Próximos Pasos
- Práctica: Desplegar varias aplicaciones
- Monitoreo: Configurar Prometheus y Grafana
- Logging: Implementar logging centralizado
- Seguridad: Aplicar RBAC y políticas de seguridad de pods
- Redes: Configurar controladores Ingress
- Almacenamiento: Implementar volúmenes persistentes
- CI/CD: Automatizar despliegues
¡Domina estos fundamentos para construir aplicaciones robustas en Kubernetes!


