Día 37 - Múltiples Ambientes en Kubernetes
🌍 Múltiples Ambientes con Kubernetes
"Un ambiente para probar, otro para validar, y uno para vivir tranquilo en producción."
🎯 Lo que harás HOY
- ✅ Tres ambientes separados: dev, staging, prod
- ✅ Deploy automático según la rama de Git
- ✅ Configuraciones diferentes para cada ambiente
- ✅ Aprobación manual para producción
Tiempo: 30 minutos
🛠️ Prerrequisitos
- ✅ Cluster Kubernetes funcionando (del Día 36)
- ✅ kubectl configurado
- ✅ Repositorio en GitHub
🏗️ Paso 1: Crear los Ambientes (5 min)
# Crear los tres namespaces
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace prod
# Verificar
kubectl get namespaces
📁 Paso 2: Estructura de Archivos
Crea esta estructura en tu repo:
k8s/
├── dev/
│ ├── deployment.yaml
│ └── service.yaml
├── staging/
│ ├── deployment.yaml
│ └── service.yaml
└── prod/
├── deployment.yaml
└── service.yaml
kubectl create namespace prod
Verificar que se crearon
kubectl get namespaces | grep -E "(dev|staging|prod)"
---
## 📁 Paso 2: Crear Archivos YAML por Ambiente
### 2.1 Crear estructura simple
```bash
mkdir -p k8s/dev k8s/staging k8s/prod
2.2 Ambiente de DESARROLLO
Crea k8s/dev/app-dev.yaml
:
# Deployment para desarrollo
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-app
namespace: dev
labels:
app: mi-app
environment: development
spec:
replicas: 1 # Solo 1 réplica en dev
selector:
matchLabels:
app: mi-app
template:
metadata:
labels:
app: mi-app
environment: development
spec:
containers:
- name: app
image: nginx:alpine
ports:
- containerPort: 80
env:
- name: ENVIRONMENT
value: "DEVELOPMENT"
- name: DEBUG
value: "true"
- name: VERSION
value: "dev-build"
resources:
requests:
memory: "32Mi"
cpu: "25m"
limits:
memory: "64Mi"
cpu: "50m"
---
# Service para desarrollo
apiVersion: v1
kind: Service
metadata:
name: mi-app-service
namespace: dev
labels:
app: mi-app
spec:
selector:
app: mi-app
ports:
- port: 80
targetPort: 80
nodePort: 30001
type: NodePort
2.3 Ambiente de STAGING
Crea k8s/staging/app-staging.yaml
:
# Deployment para staging
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-app
namespace: staging
labels:
app: mi-app
environment: staging
spec:
replicas: 2 # 2 réplicas en staging
selector:
matchLabels:
app: mi-app
template:
metadata:
labels:
app: mi-app
environment: staging
spec:
containers:
- name: app
image: nginx:alpine
ports:
- containerPort: 80
env:
- name: ENVIRONMENT
value: "STAGING"
- name: DEBUG
value: "false"
- name: VERSION
value: "staging-build"
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
---
# Service para staging
apiVersion: v1
kind: Service
metadata:
name: mi-app-service
namespace: staging
labels:
app: mi-app
spec:
selector:
app: mi-app
ports:
- port: 80
targetPort: 80
nodePort: 30002
type: NodePort
2.4 Ambiente de PRODUCCIÓN
Crea k8s/prod/app-prod.yaml
:
# Deployment para producción
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-app
namespace: prod
labels:
app: mi-app
environment: production
spec:
replicas: 3 # 3 réplicas en producción
selector:
matchLabels:
app: mi-app
template:
metadata:
labels:
app: mi-app
environment: production
spec:
containers:
- name: app
image: nginx:alpine
ports:
- containerPort: 80
env:
- name: ENVIRONMENT
value: "PRODUCTION"
- name: DEBUG
value: "false"
- name: VERSION
value: "prod-v1.0.0"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
# Health checks para producción
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
# Service para producción
apiVersion: v1
kind: Service
metadata:
name: mi-app-service
namespace: prod
labels:
app: mi-app
spec:
selector:
app: mi-app
ports:
- port: 80
targetPort: 80
nodePort: 30003
type: NodePort
🔄 Paso 3: Workflows Automáticos por Rama
3.1 Deploy automático a DESARROLLO
Crea .github/workflows/deploy-dev.yml
:
name: 🛠️ Deploy a DEV
on:
push:
branches: [develop]
workflow_dispatch:
jobs:
deploy-dev:
name: Desplegar a Desarrollo
runs-on: mi-runners
steps:
- name: Checkout código
uses: actions/checkout@v4
- name: Verificar cluster
run: |
echo "🔍 Verificando conexión..."
kubectl get nodes
- name: Desplegar a desarrollo
run: |
echo "🛠️ Desplegando a DESARROLLO..."
kubectl apply -f k8s/dev/app-dev.yaml
- name: Esperar que esté listo
run: |
echo "⏳ Esperando deployment..."
kubectl rollout status deployment/mi-app -n dev --timeout=300s
- name: Ver resultado
run: |
echo "✅ Estado en DEV:"
kubectl get pods -n dev
echo "🌐 Accesible en: http://localhost:30001"
3.2 Deploy automático a STAGING
Crea .github/workflows/deploy-staging.yml
:
name: 🎭 Deploy a STAGING
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy-staging:
name: Desplegar a Staging
runs-on: mi-runners
steps:
- name: Checkout código
uses: actions/checkout@v4
- name: Desplegar a staging
run: |
echo "🎭 Desplegando a STAGING..."
kubectl apply -f k8s/staging/app-staging.yaml
- name: Esperar que esté listo
run: |
kubectl rollout status deployment/mi-app -n staging --timeout=300s
- name: Verificar deployment
run: |
echo "✅ Estado en STAGING:"
kubectl get pods -n staging
echo "🌐 Accesible en: http://localhost:30002"
- name: Test básico
run: |
echo "🧪 Probando conectividad..."
kubectl run test-staging --image=curlimages/curl --rm -i --restart=Never -- \
curl -s http://mi-app-service.staging.svc.cluster.local || echo "Test completado"
3.3 Deploy manual a PRODUCCIÓN
Crea .github/workflows/deploy-prod.yml
:
name: 🏭 Deploy a PRODUCCIÓN
on:
workflow_dispatch:
inputs:
confirm:
description: '¿Confirmas el deploy a PRODUCCIÓN? (escribe: SI)'
required: true
default: 'NO'
jobs:
deploy-production:
name: Desplegar a Producción
runs-on: mi-runners
if: github.event.inputs.confirm == 'SI'
steps:
- name: Checkout código
uses: actions/checkout@v4
- name: Confirmación de producción
run: |
echo "🚨 DESPLEGANDO A PRODUCCIÓN 🚨"
echo "Rama: ${{ github.ref_name }}"
echo "Commit: ${{ github.sha }}"
- name: Backup actual
run: |
echo "💾 Creando backup..."
kubectl get deployment mi-app -n prod -o yaml > backup-prod.yaml 2>/dev/null || echo "No hay deployment previo"
- name: Desplegar a producción
run: |
echo "🏭 Desplegando a PRODUCCIÓN..."
kubectl apply -f k8s/prod/app-prod.yaml
- name: Esperar deployment
run: |
kubectl rollout status deployment/mi-app -n prod --timeout=600s
- name: Verificar resultado
run: |
echo "✅ Estado final en PRODUCCIÓN:"
kubectl get pods -n prod -o wide
kubectl get service -n prod
echo "🌐 Accesible en: http://localhost:30003"
- name: Test de producción
run: |
echo "🧪 Test final de producción..."
kubectl run test-prod --image=curlimages/curl --rm -i --restart=Never -- \
curl -s http://mi-app-service.prod.svc.cluster.local || echo "Test completado"
- name: Rollback si algo falla
if: failure()
run: |
echo "🔙 ¡Algo falló! Haciendo rollback..."
if [ -f backup-prod.yaml ]; then
kubectl apply -f backup-prod.yaml
echo "✅ Rollback desde backup completado"
else
kubectl rollout undo deployment/mi-app -n prod
echo "✅ Rollback automático completado"
fi
🎯 Paso 4: Probar Todo el Flujo (5 min)
4.1 Crear rama de desarrollo
# Crear y cambiar a rama develop
git checkout -b develop
# Hacer un cambio pequeño
echo "# Cambio para desarrollo" >> README.md
git add .
git commit -m "Test: deploy a desarrollo"
git push origin develop
4.2 Ver el flujo completo
- Push a
develop
→ Deploy automático a DEV - Merge a
main
→ Deploy automático a STAGING - Trigger manual → Deploy a PRODUCCIÓN (con confirmación)
4.3 Acceder a cada ambiente
# Ver todos los ambientes
kubectl get pods -A | grep mi-app
# Acceder a desarrollo
kubectl port-forward -n dev svc/mi-app-service 8001:80
# http://localhost:8001
# Acceder a staging
kubectl port-forward -n staging svc/mi-app-service 8002:80
# http://localhost:8002
# Acceder a producción
kubectl port-forward -n prod svc/mi-app-service 8003:80
# http://localhost:8003
🛠️ Comandos Útiles para el Día a Día
Ver estado de todos los ambientes:
echo "=== DESARROLLO ==="
kubectl get pods -n dev
echo "=== STAGING ==="
kubectl get pods -n staging
echo "=== PRODUCCIÓN ==="
kubectl get pods -n prod
Hacer rollback rápido:
# Rollback en cualquier ambiente
kubectl rollout undo deployment/mi-app -n dev
kubectl rollout undo deployment/mi-app -n staging
kubectl rollout undo deployment/mi-app -n prod
Ver logs de cada ambiente:
# Logs de desarrollo
kubectl logs -n dev -l app=mi-app --tail=20
# Logs de staging
kubectl logs -n staging -l app=mi-app --tail=20
# Logs de producción
kubectl logs -n prod -l app=mi-app --tail=20
Eliminar todo si necesitás empezar de nuevo:
kubectl delete namespace dev staging prod