
La contenedorización ha revolucionado la forma en que construimos, enviamos y ejecutamos software. Al empaquetar aplicaciones con sus dependencias en unidades portátiles y livianas, los contenedores resuelven el problema de "funciona en mi máquina" y permiten una implementación consistente en entornos de desarrollo, pruebas y producción.
La contenedorización ha revolucionado la forma en que construimos, enviamos y ejecutamos software. Al empaquetar aplicaciones con sus dependencias en unidades portátiles y livianas, los contenedores resuelven el problema de "funciona en mi máquina" y permiten una implementación consistente en entornos de desarrollo, pruebas y producción.
Docker hizo que los contenedores fueran accesibles. Kubernetes los hizo manejables a escala. Juntos, forman la columna vertebral de la implementación moderna de aplicaciones nativas de la nube.
┌───────────────────────┐ ┌───────────────────────┐
│ Virtual Machine │ │ Container │
├───────────────────────┤ ├───────────────────────┤
│ ┌─────────────────┐ │ │ ┌─────────────────┐ │
│ │ Application │ │ │ │ Application │ │
│ ├─────────────────┤ │ │ ├─────────────────┤ │
│ │ Guest OS │ │ │ │ Dependencies │ │
│ │ (full kernel) │ │ │ ├─────────────────┤ │
│ ├─────────────────┤ │ │ │ Container │ │
│ │ Hypervisor │ │ │ │ Runtime │ │
│ ├─────────────────┤ │ │ ├─────────────────┤ │
│ │ Host OS │ │ │ │ Host OS │ │
│ └─────────────────┘ │ │ │ Kernel (shared)│ │
└───────────────────────┘ │ └─────────────────┘ │
└───────────────────────┘
| Característica | máquina virtual | Recipiente |
|---|---|---|
| Tiempo de arranque | Minutos | Milisegundos |
| Tamaño | GB | MB |
| Sobrecarga del sistema operativo | SO completo por VM | Núcleo compartido |
| Aislamiento | Fuerte (nivel de hardware) | Nivel de proceso |
| Actuación | Casi nativo | Casi nativo |
| Portabilidad | Bien | Excelente |
| Densidad | Bajo (10-100 por host) | Alto (100-1000 por host) |
| Concepto | Descripción |
|---|---|
| Imagen | Una plantilla de solo lectura con instrucciones para crear un contenedor |
| Recipiente | Una instancia ejecutable de una imagen. |
| archivo Docker | Un archivo de texto con instrucciones para construir una imagen. |
| Registro | Almacenamiento y distribución de imágenes (Docker Hub, ECR, GCR) |
| Volumen | Almacenamiento de datos persistente fuera del sistema de archivos contenedor |
| Red | Comunicación entre contenedores y el mundo exterior. |
| Componer | Definir y ejecutar aplicaciones de múltiples contenedores |
# 1. Use specific base images (not 'latest')
FROM node:20-alpine AS builder
# 2. Set working directory
WORKDIR /app
# 3. Copy dependency files first (leverage layer caching)
COPY package*.json ./
RUN npm ci --production
# 4. Copy application code last
COPY . .
# 5. Use multi-stage builds
FROM node:20-alpine AS production
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
# 6. Run as non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 7. Expose only necessary ports
EXPOSE 3000
# 8. Use exec form of CMD
CMD ["node", "dist/server.js"]
# Build image
docker build -t myapp:1.0 .
# Run container
docker run -d --name myapp -p 3000:3000 myapp:1.0
# Execute command in running container
docker exec -it myapp bash
# View logs
docker logs -f myapp
# List containers
docker ps -a
# Stop and remove
docker stop myapp && docker rm myapp
# Volumes (persistent data)
docker volume create data-volume
docker run -v data-volume:/app/data myapp:1.0
# Compose (multi-service)
docker compose up -d
docker compose logs -f
docker compose down
# docker-compose.yml
version: '3.8'
services:
web:
image: myapp:latest
ports:
- "3000:3000"
networks:
- frontend
- backend
depends_on:
- api
- db
api:
image: api:latest
networks:
- backend
environment:
- DB_HOST=db
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- backend
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
networks:
frontend:
backend:
volumes:
postgres_data:
secrets:
db_password:
file: ./secrets/db_password.txt
Kubernetes (K8s) automatiza la implementación, el escalado y la gestión de aplicaciones en contenedores en un clúster.
┌──────────────────────────────────────────────┐
│ Kubernetes Control Plane │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ API │ │ Scheduler│ │ Controller │ │
│ │ Server │ │ │ │ Manager │ │
│ └──────────┘ └──────────┘ └──────────────┘ │
│ ┌─────────────────────────────────────────┐│
│ │ etcd (distributed key-value store) ││
│ └─────────────────────────────────────────┘│
└─────────────────┬────────────────────────────┘
│
┌─────────────────▼────────────────────────────┐
│ Worker Nodes │
│ ┌──────────────────────────────────────────┐│
│ │ Node 1 ││
│ │ ┌──────┐ ┌──────┐ ┌──────┐ ││
│ │ │ Pod │ │ Pod │ │ Pod │ ││
│ │ └──────┘ └──────┘ └──────┘ ││
│ │ ┌────────────────────────────────────┐ ││
│ │ │ kubelet ││ kube-proxy ││ container │ ││
│ │ │ ││ ││ runtime │ ││
│ │ └────────────────────────────────────┘ ││
│ └──────────────────────────────────────────┘│
│ ┌──────────────────────────────────────────┐│
│ │ Node 2 (same structure) ││
│ └──────────────────────────────────────────┘│
└──────────────────────────────────────────────┘
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp-container
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 3
periodSeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
protocol: TCP
type: ClusterIP # Internal access only
---
# For external access:
apiVersion: v1
kind: Service
metadata:
name: myapp-loadbalancer
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
DB_HOST: postgres-service
LOG_LEVEL: info
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
DB_PASSWORD: c3VwZXJzZWNyZXQ= # base64 encoded
# Apply configurations
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
# Check status
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get ingress
# View logs
kubectl logs -f deployment/myapp-deployment
# Scale
kubectl scale deployment/myapp-deployment --replicas=5
# Rollout update
kubectl set image deployment/myapp-deployment myapp=myapp:2.0
kubectl rollout status deployment/myapp-deployment
# Rollback if needed
kubectl rollout undo deployment/myapp-deployment
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-deployment
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
---
apiVersion: v1
kind: Pod
metadata:
name: postgres
spec:
containers:
- name: postgres
image: postgres:16-alpine
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-storage
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: data-claim
# Create namespaces for environment isolation
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production
# Deploy to specific namespace
kubectl apply -f deployment.yaml -n production
# Resource quotas per namespace
kubectl create quota prod-quota --hard=cpu=40,memory=80Gi,pods=50 -n production
| Guión | Docker solo | Agregar Kubernetes |
|---|---|---|
| Desarrollo local | ✅ Sí | ❌ Exceso |
| Implementación de un único servidor | ✅ Sí | ❌ Exceso |
| 2-3 microservicios | ✅ Composición acoplable | ❌ Generalmente exagerado |
| Se requiere alta disponibilidad | ❌ Conmutación por error manual | ✅ Autocuración |
| Se necesita escalado automático | ❌ manuales | ✅ HPA |
| Clúster de múltiples nodos | ❌ Limitado | ✅ Incorporado |
| Actualizaciones continuas | ❌ manuales | ✅ Incorporado |
| Implementaciones canarias | ❌ Complejo | ✅ Soporte nativo |
| Multinube | ❌ No portátil | ✅ Portátil |
Marco de decisión:
node:20-alpine, no node:latest).docker scan myapp:1.0.signo de cosign --key cosign.key myapp:1.0.readOnlyRootFilesystem: true.# Sidecar pattern for logging
spec:
containers:
- name: app
image: myapp:latest
- name: log-collector
image: fluentd:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
# GitHub Actions — Build + Deploy to Kubernetes
name: CI/CD
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t registry.example.com/myapp:${{ github.sha }} .
- name: Push to registry
run: docker push registry.example.com/myapp:${{ github.sha }}
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/myapp-deployment \
myapp=registry.example.com/myapp:${{ github.sha }}
| Categoría | Herramientas |
|---|---|
| Tiempo de ejecución del contenedor | Docker, en contenedor, CRI-O |
| Orquestación | Kubernetes, Nomad, Docker Swarm |
| Administrador de paquetes | Timón, personalizar |
| Malla de servicio | Istio, Linkerd, Cilio |
| Escucha | Prometeo + Grafana, Datadog |
| Explotación florestal | ELK Stack, Grafana Loki, Fluentd |
| Seguridad | Trivy, Falco, OPA/Gatekeeper, Kyverno |
| GitOps | ArgoCD, flujo |
| Herramientas para desarrolladores | Skaffold, Inclinación, DevSpace |
| Almacenamiento | Torre/Ceph, Longhorn, Portworx |
| Sin servidor en K8 | Knativo, OpenFaaS, KEDA |
Docker y Kubernetes juntos proporcionan una plataforma poderosa para crear, implementar y escalar aplicaciones modernas:
La inversión en el aprendizaje de la contenerización y la orquestación rinde dividendos en términos de confiabilidad de la implementación, eficiencia operativa y portabilidad de las aplicaciones entre entornos.
Todavía no hay comentarios aprobados. Las respuestas nuevas pueden esperar moderación.