☸️ Kubernetes Desde Cero - Guía Completa

Aprende Kubernetes desde los fundamentos hasta conceptos avanzados

"Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services."
Explorar Temas

📖 Temas del Curso

Haz clic en cualquier tema para ver el contenido detallado

📌 Introducción a Kubernetes

¿Qué es Kubernetes? Kubernetes (también conocido como K8s) es una plataforma de código abierto para automatizar el despliegue, escalado y gestión de aplicaciones containerizadas. Fue diseñado por Google y ahora es mantenido por la Cloud Native Computing Foundation (CNCF).

Características principales:

  • Orquestación de contenedores: Gestiona automáticamente dónde y cómo se ejecutan los contenedores.
  • Auto-escalado: Escala aplicaciones automáticamente según la demanda.
  • Auto-reparación: Reinicia contenedores fallidos y reemplaza nodos.
  • Balanceo de carga: Distribuye el tráfico entre contenedores.
  • Gestión de secretos: Almacena y gestiona información sensible.

Arquitectura de Kubernetes:

  • Control Plane: Componentes que toman decisiones globales del cluster.
  • API Server: Expone la API de Kubernetes.
  • etcd: Almacén de datos consistente y distribuido.
  • Scheduler: Asigna pods a nodos.
  • Controller Manager: Ejecuta procesos de control.
  • Worker Nodes: Nodos que ejecutan las aplicaciones.
  • Kubelet: Agente que corre en cada nodo.
  • Kube-proxy: Mantiene reglas de red.
💡 Dato curioso: El nombre Kubernetes viene del griego y significa "timonel" o "piloto". El logo de las 7 hélices representa las 7 letras de la palabra.
← Volver a temas

🔧 Instalación y Configuración

Opciones de instalación:

1. Minikube (Local):
# Instalar Minikube en Windows
choco install minikube

# Iniciar cluster
minikube start

# Verificar
kubectl cluster-info
2. Kind (Kubernetes in Docker):
# Instalar Kind
choco install kind

# Crear cluster
kind create cluster --name mi-cluster

# Verificar
kubectl cluster-info
3. Docker Desktop:
# Habilitar Kubernetes en Docker Desktop
# Ir a Settings → Kubernetes → Enable Kubernetes
4. kubectl (CLI):
# Instalar kubectl en Windows
choco install kubernetes-cli

# Verificar instalación
kubectl version --client

# Configurar autocompletado
kubectl completion powershell

Configuración del contexto:

# Ver contexto actual
kubectl config current-context

# Listar contextos
kubectl config get-contexts

# Cambiar contexto
kubectl config use-context mi-contexto

# Ver configuración
kubectl config view
💡 Tip: Para desarrollo local, usa Minikube o Kind. Para producción, considera servicios gestionados como GKE, EKS o AKS.
← Volver a temas

📚 Conceptos Básicos

Recursos fundamentales:

Pod:

La unidad más pequeña en Kubernetes. Un Pod puede contener uno o más contenedores que comparten almacenamiento y red.

Deployment:

Define el estado deseado de los Pods y ReplicaSets. Maneja actualizaciones y rollbacks.

Service:

Define un conjunto de Pods y una política para acceder a ellos. Proporciona IP estable y DNS.

Namespace:

Divide un cluster físico en múltiples clusters virtuales.

Comparativa de recursos:

Recurso Propósito Nivel
Pod Unidad de ejecución Más bajo
ReplicaSet Mantiene réplicas Intermedio
Deployment Gestiona despliegues Alto
StatefulSet Aplicaciones con estado Alto

Ciclo de vida de un Pod:

  • Pending: El Pod ha sido aceptado pero no está listo.
  • Running: El Pod está ejecutándose.
  • Succeeded: Todos los contenedores terminaron exitosamente.
  • Failed: Al menos un contenedor falló.
  • Unknown: El estado no puede ser determinado.
💡 Importante: Los Pods son efímeros. No almacenes datos importantes directamente en ellos.
← Volver a temas

📦 Pods, Deployments, Services

Creación de Pods:

# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mi-pod
  labels:
    app: web
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
# Aplicar
kubectl apply -f pod.yaml

# Ver pods
kubectl get pods

# Ver detalles
kubectl describe pod mi-pod

Deployments:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mi-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
# Aplicar deployment
kubectl apply -f deployment.yaml

# Escalar
kubectl scale deployment mi-deployment --replicas=5

# Actualizar imagen
kubectl set image deployment/mi-deployment nginx=nginx:1.22

# Ver rollout
kubectl rollout status deployment/mi-deployment

# Rollback
kubectl rollout undo deployment/mi-deployment

Services:

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mi-servicio
spec:
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

Tipos de Services:

  • ClusterIP: Expone el servicio dentro del cluster (default).
  • NodePort: Expone el servicio en cada nodo.
  • LoadBalancer: Expone el servicio externamente usando un balanceador.
  • ExternalName: Mapea el servicio a un DNS externo.
← Volver a temas

⚙️ ConfigMaps y Secrets

ConfigMaps:

Los ConfigMaps permiten almacenar datos de configuración no confidenciales en pares clave-valor.

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_URL: "postgresql://localhost:5432/mydb"
  LOG_LEVEL: "info"
  APP_ENV: "production"
  config.properties: |
    server.port=8080
    server.host=0.0.0.0
# Crear ConfigMap
kubectl create configmap app-config --from-literal=KEY=value

# Desde archivo
kubectl create configmap app-config --from-file=config.properties

# Usar en Pod
kubectl apply -f pod-with-config.yaml

Secrets:

Los Secrets almacenan información sensible como contraseñas, tokens OAuth y claves SSH.

# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
stringData:
  username: admin
  password: supersecret123
  api-key: abc123xyz
# Crear Secret desde literal
kubectl create secret generic app-secret \
  --from-literal=username=admin \
  --from-literal=password=supersecret123

# Desde archivo
kubectl create secret generic app-secret \
  --from-file=./credentials.txt

# Ver secrets (los valores están en base64)
kubectl get secrets
kubectl describe secret app-secret

Usar en Pods:

apiVersion: v1
kind: Pod
metadata:
  name: mi-pod
spec:
  containers:
  - name: app
    image: mi-app
    env:
    - name: DB_USER
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: username
    envFrom:
    - configMapRef:
        name: app-config
⚠️ Importante: Los Secrets están codificados en base64, no encriptados. Para mayor seguridad, usa herramientas como Sealed Secrets o Vault.
← Volver a temas

💾 Volúmenes y Persistencia

Tipos de volúmenes:

1. emptyDir:

Volume temporal que se crea cuando un Pod es asignado a un nodo.

volumes:
- name: cache-volume
  emptyDir: {}
2. hostPath:

Monta un archivo o directorio del nodo host.

volumes:
- name: log-volume
  hostPath:
    path: /var/log
    type: Directory
3. PersistentVolume (PV):
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mi-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /mnt/data
4. PersistentVolumeClaim (PVC):
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mi-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
5. Usar PVC en Pod:
apiVersion: v1
kind: Pod
metadata:
  name: mi-pod
spec:
  containers:
  - name: app
    image: mi-app
    volumeMounts:
    - name: storage
      mountPath: /data
  volumes:
  - name: storage
    persistentVolumeClaim:
      claimName: mi-pvc

Storage Classes:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
💡 Tip: Usa StorageClasses para aprovisionamiento dinámico de volúmenes en la nube.
← Volver a temas

🌐 Ingress y Networking

Modelo de red de Kubernetes:

  • Todos los Pods pueden comunicarse sin NAT.
  • Todos los nodos pueden comunicarse con todos los Pods.
  • La IP del Pod es la misma vista desde el Pod y desde otros.

Network Policies:

# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: backend

Ingress:

Ingress expone servicios HTTP/HTTPS desde fuera del cluster.

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mi-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: miapp.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

Ingress con TLS:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-ingress
spec:
  tls:
  - hosts:
    - miapp.com
    secretName: tls-secret
  rules:
  - host: miapp.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: mi-servicio
            port:
              number: 443

Ingress Controllers:

  • NGINX: El más popular, mantenido por la comunidad.
  • Traefik: Fácil de usar, auto-descubrimiento.
  • HAProxy: Alto rendimiento.
  • Cloud providers: ALB (AWS), Application Gateway (Azure).
💡 Tip: Usa cert-manager para gestionar certificados TLS automáticamente con Let's Encrypt.
← Volver a temas

✅ Buenas Prácticas

Gestión de recursos:

resources:
  requests:
    memory: "128Mi"
    cpu: "100m"
  limits:
    memory: "256Mi"
    cpu: "500m"

Health Checks:

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

Security Context:

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  allowPrivilegeEscalation: false
  capabilities:
    drop:
    - ALL

Labels y Annotations:

metadata:
  labels:
    app: mi-app
    version: v1.0.0
    environment: production
  annotations:
    description: "Mi aplicación principal"
    contact: "equipo@empresa.com"

Checklist de seguridad:

  • ✓ No ejecutar como root
  • ✓ Usar imágenes oficiales y actualizadas
  • ✓ Escanear imágenes con herramientas de seguridad
  • ✓ Usar Network Policies
  • ✓ Limitar recursos (CPU/Memoria)
  • ✓ Usar Secrets para datos sensibles
  • ✓ Habilitar RBAC
💡 Tip: Usa herramientas como kube-bench y kube-hunter para auditar la seguridad de tu cluster.
← Volver a temas

🔄 StatefulSets y DaemonSets

StatefulSets:

StatefulSets gestionan aplicaciones con estado que requieren identidad de red única y almacenamiento persistente.

# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

Características de StatefulSets:

  • Los Pods tienen nombres estables: web-0, web-1, web-2...
  • Se despliegan en orden (0, 1, 2...).
  • Se eliminan en orden inverso.
  • Cada Pod tiene su propio PVC.

DaemonSets:

DaemonSets aseguran que todos (o algunos) nodos ejecuten una copia de un Pod.

# daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-logging
  template:
    metadata:
      labels:
        name: fluentd-logging
    spec:
      containers:
      - name: fluentd
        image: fluentd:latest
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

Casos de uso de DaemonSets:

  • Logging (Fluentd, Filebeat)
  • Monitoring (Prometheus Node Exporter)
  • Redes (kube-proxy, Calico)
  • Almacenamiento (Ceph, GlusterFS)
💡 Tip: Usa StatefulSets para bases de datos y DaemonSets para agentes que deben correr en todos los nodos.
← Volver a temas

📈 Auto-scaling (HPA/VPA)

Horizontal Pod Autoscaler (HPA):

HPA escala automáticamente el número de Pods basándose en métricas de CPU, memoria o custom metrics.

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: mi-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mi-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
# Crear HPA con kubectl
kubectl autoscale deployment mi-app \
  --min=2 \
  --max=10 \
  --cpu-percent=70

# Ver HPA
kubectl get hpa

# Ver detalles
kubectl describe hpa mi-app-hpa

Vertical Pod Autoscaler (VPA):

VPA ajusta automáticamente los requests y limits de CPU/memoria de los contenedores.

# vpa.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: mi-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mi-app
  updatePolicy:
    updateMode: "Auto"  # Off, Initial, Recreate, Auto

Cluster Autoscaler:

Escala automáticamente el número de nodos en el cluster.

Comparativa:

Tipo Qué escala Cuándo usar
HPA Número de Pods Carga variable predecible
VPA Recursos del Pod Aplicaciones con uso variable
Cluster Autoscaler Número de nodos Cuando faltan recursos
⚠️ Importante: No uses HPA y VPA juntos en el mismo deployment (pueden conflictuar).
← Volver a temas

🔧 CI/CD con Kubernetes

Flujo de CI/CD:

  1. Desarrollador hace push al repositorio
  2. CI pipeline construye la imagen Docker
  3. La imagen se publica en el registry
  4. CD pipeline actualiza el deployment en Kubernetes

GitHub Actions ejemplo:

# .github/workflows/deploy.yml
name: Deploy to Kubernetes

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Login to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build and push
      uses: docker/build-push-action@v4
      with:
        push: true
        tags: user/app:${{ github.sha }}

    - name: Configure kubectl
      uses: azure/k8s-set-context@v3
      with:
        kubeconfig: ${{ secrets.KUBE_CONFIG }}

    - name: Deploy
      run: |
        kubectl set image deployment/my-app app=user/app:${{ github.sha }}
        kubectl rollout status deployment/my-app

Helm para gestión de releases:

# Instalar Helm
choco install kubernetes-helm

# Crear chart
helm create mi-app

# Instalar chart
helm install mi-release ./mi-app

# Actualizar
helm upgrade mi-release ./mi-app

# Rollback
helm rollback mi-release 1

# Listar releases
helm list

Estrategias de deployment:

  • Recreate: Elimina todos los Pods y crea nuevos.
  • RollingUpdate: Actualiza gradualmente (default).
  • Blue-Green: Dos entornos idénticos.
  • Canary: Despliega a un subconjunto de usuarios.
💡 Tip: Usa ArgoCD o Flux para GitOps - sincronización automática del cluster con el repositorio Git.
← Volver a temas

📊 Monitoring con Prometheus

Prometheus Stack:

Prometheus es un sistema de monitoring y alerting. El stack incluye Prometheus, Grafana, Alertmanager y exporters.

Instalación con Helm:

# Agregar repositorio
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

# Instalar kube-prometheus-stack
helm install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace

Componentes:

  • Prometheus Server: Almacena métricas time-series.
  • Grafana: Dashboards y visualización.
  • Alertmanager: Gestiona alertas.
  • Node Exporter: Métricas del sistema.
  • kube-state-metrics: Métricas de recursos K8s.

ServiceMonitor ejemplo:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: app-monitor
  labels:
    release: monitoring
spec:
  selector:
    matchLabels:
      app: mi-app
  endpoints:
  - port: web
    interval: 30s
    path: /metrics

Alertas ejemplo:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: app-alerts
spec:
  groups:
  - name: app.rules
    rules:
    - alert: HighCPU
      expr: rate(container_cpu_usage_seconds_total[5m]) > 0.8
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "High CPU usage detected"
        description: "CPU usage is above 80%"

Acceder a Grafana:

# Port-forward
kubectl port-forward svc/monitoring-grafana -n monitoring 3000:80

# Credenciales por defecto
# Usuario: admin
# Password: prom-operator
💡 Tip: Usa dashboards predefinidos de la comunidad para Kubernetes y aplicaciones comunes.
← Volver a temas

📚 Contenido del Curso

Módulo 1: Fundamentos

  • Introducción a Kubernetes
  • Instalación y configuración
  • Conceptos básicos
  • Pods, Deployments, Services
Ir a temas →

Módulo 2: Intermedio

  • ConfigMaps y Secrets
  • Volúmenes y persistencia
  • Ingress y networking
  • Buenas prácticas
Ir a temas →

Módulo 3: Avanzado

  • StatefulSets y DaemonSets
  • Auto-scaling (HPA/VPA)
  • CI/CD con Kubernetes
  • Monitoring con Prometheus
Ir a temas →

📝 Ejemplos Rápidos

Comandos Básicos

# Ver información del cluster
kubectl cluster-info

# Listar pods
kubectl get pods

# Aplicar manifest
kubectl apply -f archivo.yaml

# Eliminar recurso
kubectl delete -f archivo.yaml

# Ver logs
kubectl logs <pod-name>

Pod Básico

apiVersion: v1
kind: Pod
metadata:
  name: mi-pod
  labels:
    app: web
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mi-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Service

apiVersion: v1
kind: Service
metadata:
  name: mi-servicio
spec:
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

📖 Recursos Adicionales

Herramientas

  • Minikube - Kubernetes local
  • Kind - Kubernetes en Docker
  • Helm - Package manager
  • Lens - IDE para Kubernetes

Comunidades

👨‍💻 Desarrollado por Isaac Esteban Haro Torres

Ingeniero en Sistemas · Full Stack · Automatización · Data

📧 Email: zackharo1@gmail.com

📱 WhatsApp: 098805517

💻 GitHub: github.com/ieharo1

🌐 Portafolio: ieharo1.github.io/portafolio-isaac.haro/