CURSO COMPLETO 2024

Kubernetes
Dominio Total

Aprende orquestación de contenedores desde cero hasta producción. Arquitectura, despliegues, redes, seguridad y más.

12MÓDULOS
80+LECCIONES
50+EJEMPLOS
100%ESPAÑOL
COMENZAR CURSO
SCROLL

Plan de Estudios

Un viaje completo desde los fundamentos hasta producción avanzada

MÓDULO 01
☁️

Introducción a Kubernetes

Qué es, por qué usarlo y conceptos fundamentales de orquestación.

¿Qué es K8s? Historia Contenedores Instalación
MÓDULO 02
🏗️

Arquitectura

Control Plane, Worker Nodes, etcd, API Server y componentes clave.

Control Plane etcd kubelet kube-proxy
MÓDULO 03
📦

Pods

La unidad básica de despliegue. Ciclo de vida, configuración y multi-container.

Pod Spec Init Containers Sidecars Probes
MÓDULO 04
🔄

Workloads

Deployments, StatefulSets, DaemonSets, Jobs y CronJobs explicados.

Deployment StatefulSet DaemonSet Jobs
MÓDULO 05
🌐

Servicios y Redes

ClusterIP, NodePort, LoadBalancer, Ingress y DNS interno.

ClusterIP LoadBalancer Ingress DNS
MÓDULO 06
💾

Storage y Volúmenes

PersistentVolumes, PVC, StorageClass y gestión de datos.

PV / PVC StorageClass ConfigMap Secrets
MÓDULO 07
🔐

Seguridad (RBAC)

Roles, ClusterRoles, ServiceAccounts, NetworkPolicies y PodSecurity.

RBAC ServiceAccount NetworkPolicy Secrets
MÓDULO 08
⚖️

Escalado y Scheduling

HPA, VPA, Node Affinity, Taints/Tolerations y Pod Disruption.

HPA VPA Affinity Taints
MÓDULO 09
🎛️

ConfigMaps y Secrets

Gestión de configuración y datos sensibles de forma segura.

ConfigMap Secrets Env Vars Volumes
MÓDULO 10
⛑️

Helm - Package Manager

Charts, Templates, Repositorios y despliegues reproducibles.

Charts Templates Values Repos
MÓDULO 11
📊

Monitoring y Logging

Prometheus, Grafana, ELK Stack y alertas en producción.

Prometheus Grafana ELK Alertas
MÓDULO 12
🚀

CI/CD y Producción

GitOps, ArgoCD, estrategias de despliegue y mejores prácticas.

GitOps ArgoCD Blue/Green Canary

Módulo 01 — Introducción a Kubernetes

¿Qué es Kubernetes?

Kubernetes (K8s) es una plataforma open-source de orquestación de contenedores, originalmente desarrollada por Google y ahora mantenida por la CNCF. Su nombre proviene del griego "timonel" o "piloto". Se ocupa de automatizar el despliegue, escalado y gestión de aplicaciones en contenedores.

ℹ️ Kubernetes surgió de la experiencia de Google con su sistema interno llamado Borg, que durante años gestionó millones de contenedores en producción.

¿Por qué Kubernetes?

Antes de Kubernetes, desplegar aplicaciones en múltiples servidores era una tarea manual y propensa a errores. K8s resuelve problemas reales:

  • Alta disponibilidad: reinicia contenedores caídos automáticamente
  • Escalado automático: aumenta o reduce réplicas según la demanda
  • Despliegues sin downtime: rolling updates y rollbacks
  • Gestión de configuración: ConfigMaps y Secrets integrados
  • Service Discovery: DNS interno y balanceo de carga

Instalación — minikube (local)

bash
# Instalar minikube en Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Instalar kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# Iniciar cluster local
minikube start --driver=docker --cpus=2 --memory=4096

# Verificar
kubectl cluster-info
kubectl get nodes

Comandos esenciales de kubectl

bash
# Ver recursos del cluster
kubectl get nodes
kubectl get pods --all-namespaces
kubectl get services

# Información detallada
kubectl describe node <nombre-nodo>
kubectl describe pod <nombre-pod>

# Ver logs
kubectl logs <pod-name>
kubectl logs -f <pod-name>  # en tiempo real

# Ejecutar comando dentro de un pod
kubectl exec -it <pod-name> -- /bin/bash

Módulo 02 — Arquitectura de Kubernetes

Un cluster de Kubernetes está compuesto por dos tipos de nodos: el Control Plane (cerebro del cluster) y los Worker Nodes (donde corren las aplicaciones).

┌─────────────────────────────────────────────────────────┐ │ CONTROL PLANE │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ API Server │ │ Scheduler │ │ Controller │ │ │ │ (kube-api) │ │ │ │ Manager │ │ │ └──────┬───────┘ └──────────────┘ └──────────────┘ │ │ │ │ │ ┌──────▼───────────────────────────────────────────┐ │ │ │ etcd │ │ │ │ (base de datos distribuida) │ │ │ └──────────────────────────────────────────────────┘ │ └──────────────────────────┬──────────────────────────────┘ │ ┌────────────────┼────────────────┐ │ │ │ ┌─────────▼──────┐ ┌───────▼───────┐ ┌─────▼──────────┐ │ WORKER NODE 1 │ │ WORKER NODE 2 │ │ WORKER NODE 3 │ │ │ │ │ │ │ │ ┌────────────┐ │ │ ┌───────────┐ │ │ ┌────────────┐ │ │ │ kubelet │ │ │ │ kubelet │ │ │ │ kubelet │ │ │ │ kube-proxy │ │ │ │kube-proxy │ │ │ │ kube-proxy │ │ │ │ Pod Pod │ │ │ │ Pod Pod │ │ │ │ Pod Pod │ │ │ └────────────┘ │ │ └───────────┘ │ │ └────────────┘ │ └────────────────┘ └───────────────┘ └────────────────┘

Componentes del Control Plane

ComponenteFunción
kube-apiserverPunto de entrada de todas las solicitudes REST. Frontend del Control Plane.
etcdBase de datos key-value distribuida. Almacena todo el estado del cluster.
kube-schedulerDecide en qué nodo se ejecuta cada Pod nuevo.
controller-managerEjecuta controladores que regulan el estado del cluster.
cloud-controllerIntegra el cluster con el proveedor de nube (AWS, GCP, Azure).

Componentes del Worker Node

ComponenteFunción
kubeletAgente que corre en cada nodo. Asegura que los contenedores estén corriendo.
kube-proxyMantiene las reglas de red. Permite la comunicación entre Pods y Servicios.
Container RuntimeSoftware que ejecuta contenedores (containerd, CRI-O, Docker).
💡 Tip: En producción, siempre usa 3 o más nodos de Control Plane para alta disponibilidad. Un solo nodo de control es un punto único de falla (SPOF).

Módulo 03 — Pods

El Pod es la unidad más pequeña en Kubernetes. Representa uno o más contenedores que comparten red y almacenamiento. Los Pods son efímeros: si mueren, no se recrean solos (para eso existen los Deployments).

Pod básico

yaml
apiVersion: v1
kind: Pod
metadata:
  name: mi-pod
  labels:
    app: web
    version: "1.0"
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

Liveness y Readiness Probes

Las probes permiten a Kubernetes saber si tu aplicación está sana y lista para recibir tráfico:

yaml
livenessProbe:   # reinicia el pod si falla
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
  failureThreshold: 3

readinessProbe:  # retira del balanceo si falla
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

startupProbe:   # para apps lentas al arrancar
  httpGet:
    path: /healthz
    port: 8080
  failureThreshold: 30
  periodSeconds: 10

Ciclo de vida de un Pod

FaseDescripción
PendingFue aceptado pero aún no está corriendo (descargando imagen, etc.)
RunningAl menos un contenedor está corriendo
SucceededTodos los contenedores terminaron con éxito (exit 0)
FailedAl menos un contenedor falló (exit != 0)
UnknownNo se puede obtener el estado (problema de red con el nodo)

Módulo 04 — Workloads

Deployment

El Deployment es el recurso más común. Gestiona ReplicaSets para garantizar que siempre haya N copias de tu Pod corriendo.

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mi-app
  namespace: production
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: mi-app
  template:
    metadata:
      labels:
        app: mi-app
    spec:
      containers:
      - name: app
        image: myrepo/mi-app:v2.0
        ports:
        - containerPort: 3000
bash
# Escalar deployment
kubectl scale deployment mi-app --replicas=5

# Rolling update de imagen
kubectl set image deployment/mi-app app=myrepo/mi-app:v3.0

# Ver historial de rollouts
kubectl rollout history deployment/mi-app

# Rollback a versión anterior
kubectl rollout undo deployment/mi-app

# Rollback a revisión específica
kubectl rollout undo deployment/mi-app --to-revision=2

StatefulSet

Para aplicaciones que necesitan identidad estable y almacenamiento persistente (bases de datos, caches distribuidos).

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: "postgres"
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

DaemonSet

Garantiza que todos los nodos ejecuten una copia del Pod. Ideal para agentes de monitoreo, logging y networking.

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

CronJob

yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: backup-db
spec:
  schedule: "0 2 * * *"  # cada día a las 2am
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: postgres:15
            command: ["/bin/sh", "-c", "pg_dump $DATABASE_URL | gzip > /backup/db.sql.gz"]
          restartPolicy: OnFailure

Módulo 05 — Servicios y Redes

Un Service es una abstracción que expone una aplicación corriendo en Pods. Proporciona una dirección IP estable y balanceo de carga.

Tipos de Service

TipoAccesoCaso de uso
ClusterIPSolo interno al clusterComunicación entre microservicios
NodePortIP del nodo + puertoDesarrollo, pruebas
LoadBalancerIP pública (cloud)Exponer app al exterior
ExternalNameAlias DNS externoAcceder a servicios externos
yaml
# ClusterIP (por defecto)
apiVersion: v1
kind: Service
metadata:
  name: mi-servicio
spec:
  type: ClusterIP
  selector:
    app: mi-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

Ingress

Ingress gestiona el acceso externo HTTP/HTTPS a los servicios del cluster, típicamente con un Ingress Controller (nginx, traefik, etc.).

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mi-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
  - hosts: [app.midominio.com]
    secretName: tls-secret
  rules:
  - host: app.midominio.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
⚠️ Para que Ingress funcione necesitas un Ingress Controller instalado en el cluster. En minikube: minikube addons enable ingress

Módulo 06 — Storage y Volúmenes

PersistentVolume (PV) y PersistentVolumeClaim (PVC)

Un PV es una pieza de almacenamiento en el cluster. Un PVC es una solicitud de almacenamiento por parte de un usuario.

yaml
# PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-datos
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: fast-ssd
  hostPath:
    path: /mnt/datos
---
# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mi-pvc
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 5Gi

StorageClass

Define cómo se aprovisiona el almacenamiento dinámicamente. Cada proveedor de nube tiene sus propias StorageClasses.

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: ebs.csi.aws.com  # AWS EBS
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Módulo 07 — Seguridad y RBAC

Role-Based Access Control

RBAC controla quién puede hacer qué en el cluster. Los componentes principales son: Role, ClusterRole, RoleBinding y ClusterRoleBinding.

yaml
# Role (namespace-scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: production
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
---
# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: production
subjects:
- kind: ServiceAccount
  name: mi-app-sa
  namespace: production
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

NetworkPolicy

Controla el tráfico de red entre Pods. Por defecto, Kubernetes permite todo el tráfico entre Pods.

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}  # aplica a todos los pods
  policyTypes:
  - Ingress
  # sin reglas = denegar todo ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
spec:
  podSelector:
    matchLabels:
      app: api
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

Módulo 08 — Escalado y Scheduling

Horizontal Pod Autoscaler (HPA)

Escala automáticamente el número de réplicas basándose en métricas (CPU, memoria, métricas personalizadas).

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: mi-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mi-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Node Affinity y Taints/Tolerations

yaml
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/arch
            operator: In
            values: [amd64]
          - key: node-type
            operator: In
            values: [gpu]
  tolerations:
  - key: gpu
    operator: Equal
    value: "true"
    effect: NoSchedule

Módulo 09 — ConfigMaps y Secrets

ConfigMap

Almacena configuración no sensible en formato key-value o archivos de configuración completos.

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_HOST: postgres-service
  APP_PORT: "3000"
  LOG_LEVEL: info
  nginx.conf: |
    server {
      listen 80;
      location / { proxy_pass http://app:3000; }
    }
---
# Usar ConfigMap en un Pod
envFrom:
- configMapRef:
    name: app-config

# O variable específica:
env:
- name: DB_HOST
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: DATABASE_HOST

Secrets

bash
# Crear secret desde literales
kubectl create secret generic db-credentials \
  --from-literal=username=admin \
  --from-literal=password=S3cur3P@ss!

# Crear secret desde archivo
kubectl create secret generic tls-secret \
  --from-file=tls.crt=./cert.pem \
  --from-file=tls.key=./key.pem
yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
stringData:  # se encripta automáticamente en base64
  username: admin
  password: S3cur3P@ss!
⚠️ Los Secrets en Kubernetes están codificados en base64 pero NO encriptados por defecto. Para producción activa Encryption at Rest o usa soluciones como HashiCorp Vault o AWS Secrets Manager.

Módulo 10 — Helm

Helm es el gestor de paquetes de Kubernetes. Un Chart es un paquete de recursos Kubernetes con plantillas y valores configurables.

Comandos esenciales

bash
# Instalar Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Agregar repositorio
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Buscar charts
helm search repo nginx

# Instalar un chart
helm install mi-nginx bitnami/nginx \
  --namespace web \
  --create-namespace \
  --set service.type=LoadBalancer \
  --set replicaCount=3

# Listar releases
helm list --all-namespaces

# Actualizar release
helm upgrade mi-nginx bitnami/nginx --set replicaCount=5

# Rollback
helm rollback mi-nginx 1

# Desinstalar
helm uninstall mi-nginx

Crear un Chart propio

bash
helm create mi-app
# Estructura generada:
# mi-app/
# ├── Chart.yaml        # metadata del chart
# ├── values.yaml       # valores por defecto
# ├── templates/        # plantillas YAML
# │   ├── deployment.yaml
# │   ├── service.yaml
# │   └── ingress.yaml
# └── charts/           # dependencias

# Validar chart
helm lint mi-app

# Ver los YAMLs generados
helm template mi-app ./mi-app --values mi-app/values.yaml

values.yaml típico

yaml
replicaCount: 2

image:
  repository: myrepo/mi-app
  tag: "1.0.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  host: app.midominio.com

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

Módulo 11 — Monitoring y Logging

Stack Prometheus + Grafana

bash
# Instalar kube-prometheus-stack via Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --set grafana.adminPassword=admin123 \
  --set prometheus.prometheusSpec.retention=30d

# Ver pods del stack
kubectl get pods -n monitoring

# Acceder a Grafana (port-forward)
kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80

ServiceMonitor para tus apps

yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: mi-app-monitor
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: mi-app
  endpoints:
  - port: metrics
    interval: 15s
    path: /metrics

Logging con Loki + Promtail

bash
helm repo add grafana https://grafana.github.io/helm-charts
helm install loki grafana/loki-stack \
  --namespace monitoring \
  --set grafana.enabled=false \
  --set promtail.enabled=true

# En Grafana, agregar datasource Loki:
# URL: http://loki:3100
# Query ejemplo LogQL:
# {namespace="production", app="mi-app"} |= "error"

Alertas con AlertManager

yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: alertas-app
spec:
  groups:
  - name: app.rules
    rules:
    - alert: PodCrashLooping
      expr: rate(kube_pod_container_status_restarts_total[5m]) > 0.1
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "Pod {{ $labels.pod }} en CrashLoopBackOff"

Módulo 12 — CI/CD y GitOps con ArgoCD

Instalar ArgoCD

bash
kubectl create namespace argocd
kubectl apply -n argocd \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Obtener contraseña inicial
kubectl get secret argocd-initial-admin-secret \
  -n argocd -o jsonpath="{.data.password}" | base64 -d

# Port-forward para acceder a la UI
kubectl port-forward svc/argocd-server -n argocd 8080:443

Application en ArgoCD

yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: mi-app-prod
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/mi-org/mi-app-k8s
    targetRevision: HEAD
    path: manifests/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

Estrategias de Despliegue

EstrategiaDowntimeRollbackCosto
RecreateLentoBajo
Rolling UpdateNoMedioBajo
Blue/GreenNoInmediatoAlto (2x recursos)
CanaryNoRápidoMedio

Canary con Argo Rollouts

yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: mi-app-rollout
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 10    # 10% del tráfico
      - pause: {duration: 5m}
      - setWeight: 25
      - pause: {duration: 10m}
      - setWeight: 50
      - pause: {}        # aprobación manual
      - setWeight: 100
🚀 Best Practice: Combina ArgoCD (GitOps) + Argo Rollouts (despliegues progresivos) + Prometheus (métricas) para un pipeline de producción robusto con análisis automático de calidad.

Recursos Adicionales

Herramientas y referencias para profundizar

📚

Documentación Oficial

kubernetes.io — La fuente de verdad. Reference API, guides, tutoriales oficiales.

kubernetes.io/docs API Reference
🛠️

Herramientas Clave

k9s, Lens, Helm, kustomize, kubectx/kubens para productividad diaria.

k9s Lens IDE kustomize
🎓

Certificaciones

CKA, CKAD, CKS — Las certificaciones oficiales de Kubernetes de la CNCF.

CKA CKAD CKS