En la lección anterior cerramos con una promesa: sabes qué hace Kubernetes —mantener de forma continua el estado que le declaras— y ahora toca ver cómo lo hace. Un clúster no es una caja mágica: son seis o siete procesos con responsabilidades muy delimitadas que se comunican siempre a través de un único punto central. Entender esa arquitectura es lo que después te permitirá diagnosticar problemas en lugar de reiniciar cosas al azar: cuando un pod se queda en Pending, cuando un despliegue no avanza o cuando el clúster deja de responder, la causa está casi siempre en una pieza concreta y esta lección te enseña cuál. Terminaremos siguiendo, paso a paso, todo lo que ocurre desde que ejecutas kubectl apply -f api-reservas.yaml hasta que el contenedor de api-reservas está sirviendo peticiones en un nodo.
Contenido
- Visión general: plano de control y nodos de trabajo
- Los componentes del plano de control
- Los componentes de los nodos de trabajo
- El bucle de reconciliación: la idea central
- Recorrido completo de
kubectl apply - Qué pasa cuando falla cada pieza
- Alta disponibilidad del plano de control
- Visión general: plano de control y nodos de trabajo
Un clúster de Kubernetes se divide en dos mitades con papeles muy distintos:
- El plano de control (control plane): es el cerebro. Decide, registra y vigila. No ejecuta las aplicaciones de los usuarios (salvo en clústeres de un solo nodo como minikube).
- Los nodos de trabajo (worker nodes): son los músculos. Ejecutan los contenedores de tus aplicaciones y reportan su estado.
flowchart TB
subgraph CP["Plano de control"]
API["kube-apiserver<br/>única puerta de entrada"]
ETCD[("etcd<br/>almacén de estado")]
SCH["kube-scheduler<br/>decide en qué nodo"]
CM["kube-controller-manager<br/>bucles de reconciliación"]
CCM["cloud-controller-manager<br/>integración con la nube"]
API --- ETCD
SCH --> API
CM --> API
CCM --> API
end
subgraph N1["Nodo trabajador 1"]
K1["kubelet"]
P1["kube-proxy"]
R1["containerd (CRI)"]
K1 --> R1
end
subgraph N2["Nodo trabajador 2"]
K2["kubelet"]
P2["kube-proxy"]
R2["containerd (CRI)"]
K2 --> R2
end
USER["kubectl / CI-CD"] --> API
K1 --> API
K2 --> API
P1 --> API
P2 --> API
Fíjate en la propiedad más importante del diagrama: todas las flechas pasan por kube-apiserver. Ningún componente habla directamente con otro. El scheduler no llama al kubelet; el kubelet no consulta etcd. Todos leen y escriben en la API, y esa API es la única que toca etcd. Esta topología en estrella es lo que hace el sistema extensible: para añadir una funcionalidad nueva basta con escribir un proceso que observe la API y actúe (eso es un controlador, y es exactamente lo que hacen los operadores del módulo 6).
- Los componentes del plano de control
2.1. kube-apiserver
Es el frontal REST de todo el clúster y el único componente que escribe en etcd. Todo lo que ocurre en Kubernetes es una petición HTTP contra este servidor.
Sus responsabilidades, en el orden en que se aplican a cada petición:
- Autenticación: ¿quién eres? (certificado de cliente, token, OIDC…).
- Autorización: ¿puedes hacer esto? Es donde actúa RBAC (módulo 8).
- Control de admisión: modificar o rechazar el objeto antes de guardarlo (por ejemplo, inyectar valores por defecto, aplicar cuotas o rechazar imágenes no firmadas).
- Validación del esquema del objeto.
- Persistencia en etcd.
- Notificación a todos los componentes suscritos mediante el mecanismo de watch.
Es sin estado y horizontalmente escalable: puedes tener tres réplicas detrás de un balanceador.
2.2. etcd
Es una base de datos clave-valor distribuida y consistente, basada en el algoritmo de consenso Raft. Guarda absolutamente todo el estado del clúster: objetos, configuración, secretos y estado observado.
Puntos que debes retener:
- Es la única fuente de verdad. Si pierdes etcd sin copia de seguridad, has perdido el clúster (no las aplicaciones ya corriendo, pero sí toda su definición).
- Se despliega en número impar de miembros (3 o 5) para poder formar quórum.
- Es sensible a la latencia de disco: se recomienda SSD dedicado. Es el cuello de botella habitual en clústeres grandes.
- Su copia de seguridad (
etcdctl snapshot save) es la copia de seguridad del clúster, y es materia de examen en la CKA (módulo 12).
2.3. kube-scheduler
Su trabajo es una sola cosa, y la hace muy bien: decidir en qué nodo se ejecuta cada pod recién creado. Observa continuamente la API buscando pods sin nodeName asignado y, para cada uno, ejecuta dos fases:
| Fase | Qué hace | Ejemplos de criterio |
|---|---|---|
| Filtrado (predicates) | Descarta los nodos donde el pod no puede ir | ¿Hay CPU y memoria suficientes? ¿El nodo tiene las etiquetas del nodeSelector? ¿El pod tolera los taints del nodo? ¿Están libres los puertos necesarios? |
| Puntuación (scoring) | Ordena los nodos viables y elige el mejor | Reparto equilibrado de recursos, afinidad y antiafinidad, nodos que ya tienen la imagen descargada, dispersión por zonas |
El resultado no es "arrancar el contenedor": es simplemente escribir el campo spec.nodeName del pod en la API. El scheduler nunca contacta con el nodo. Los criterios avanzados (afinidad, taints, tolerations) se estudian en el módulo 6.
2.4. kube-controller-manager
Es un único binario que ejecuta decenas de controladores en paralelo, cada uno con su propio bucle de reconciliación. Los más relevantes para el curso:
| Controlador | Qué vigila | Qué hace |
|---|---|---|
| Deployment | Objetos Deployment | Crea y actualiza ReplicaSets para desplegar nuevas versiones |
| ReplicaSet | Objetos ReplicaSet | Crea o borra pods hasta que el número coincide con replicas |
| Node | Estado de los nodos | Marca nodos como NotReady y desaloja sus pods si no responden |
| Job / CronJob | Tareas | Crea pods de tarea y los CronJobs los lanzan según horario |
| Endpoints / EndpointSlice | Services y pods | Mantiene la lista de IPs sanas detrás de cada Service |
| ServiceAccount y token | Namespaces | Crea las cuentas de servicio por defecto |
| PersistentVolume | PVCs y PVs | Vincula reclamaciones con volúmenes |
Cuando en el módulo 2 escribas un Deployment con replicas: 3 y veas aparecer tres pods, quien los ha creado ha sido este proceso.
2.5. cloud-controller-manager
Aísla todo lo que depende del proveedor de nube, de modo que el núcleo de Kubernetes no tenga código de AWS, Azure o GCP. Se encarga de:
- Nodos: consultar al proveedor si una máquina virtual ha sido eliminada realmente.
- Balanceadores: cuando creas un
Servicede tipoLoadBalancer, es quien pide el balanceador real a la nube (módulo 4). - Rutas: configurar el enrutado entre nodos en la red del proveedor.
En minikube o kind no existe, y por eso un Service de tipo LoadBalancer se queda con la IP externa en <pending> salvo que uses minikube tunnel. Es una fuente clásica de confusión que veremos en su momento.
- Los componentes de los nodos de trabajo
3.1. kubelet
Es el agente que corre en cada nodo y el único que realmente arranca contenedores. Su bucle es:
- Preguntar a la API qué pods le han sido asignados (
spec.nodeName == este nodo). - Comparar con lo que hay corriendo en la máquina.
- Pedir al runtime de contenedores, vía CRI, que arranque o pare lo que haga falta.
- Montar volúmenes, inyectar ConfigMaps y Secrets, aplicar límites de recursos.
- Ejecutar las sondas de salud (módulo 7) y reiniciar contenedores fallidos.
- Reportar continuamente el estado del nodo y de sus pods a la API.
Importante: el kubelet solo obedece a la API, no acepta órdenes de nadie más. Y solo gestiona pods, no contenedores sueltos: si arrancas un contenedor con docker run en un nodo, el kubelet lo ignora.
3.2. kube-proxy
Implementa el concepto de Service a nivel de red en cada nodo. Observa los Services y sus EndpointSlices y programa reglas de red (iptables o, en clústeres grandes, IPVS) para que el tráfico dirigido a la IP virtual de un servicio se reparta entre los pods sanos.
No es un proxy en el camino de los datos en el modo habitual: escribe reglas del kernel y se aparta. Algunos plugins de red modernos (Cilium en modo eBPF) lo sustituyen por completo. Se estudia en el módulo 4.
3.3. Runtime de contenedores y la interfaz CRI
El kubelet no sabe crear contenedores: delega en un runtime a través de la CRI (Container Runtime Interface), una API gRPC estándar. Los runtimes habituales:
| Runtime | Notas |
|---|---|
| containerd | El más extendido. Es el mismo motor que usa Docker internamente |
| CRI-O | Ligero, orientado exclusivamente a Kubernetes. Habitual en OpenShift |
| Docker Engine | Ya no se soporta directamente; requiere el adaptador cri-dockerd. dockershim se eliminó en la 1.24 |
Debajo del runtime hay otro nivel (runc) que es quien realmente habla con el kernel (namespaces y cgroups). Ese detalle no lo necesitas para operar, pero explica la frase "Kubernetes ya no usa Docker": las imágenes que construyes con Docker siguen funcionando perfectamente porque cumplen el estándar OCI.
3.4. Plugin de red (CNI) y de almacenamiento (CSI)
Dos interfaces más que conviene nombrar ya:
- CNI (Container Network Interface): el plugin que asigna IPs a los pods y hace que se vean entre nodos. Calico, Cilium, Flannel. Sin CNI instalado, los nodos se quedan en
NotReady. Módulo 4. - CSI (Container Storage Interface): el plugin que aprovisiona discos reales para los volúmenes persistentes. Módulo 5.
- El bucle de reconciliación: la idea central
Si te quedas con una sola idea de esta lección, que sea esta. Todos los controladores de Kubernetes ejecutan el mismo patrón:
bucle infinito:
estado_deseado <- leer de la API (el campo spec)
estado_real <- observar el mundo (pods existentes, nodos, etc.)
si estado_real != estado_deseado:
ejecutar las acciones mínimas para acercarlos
publicar en la API lo observado (el campo status)Consecuencias prácticas de este diseño, que explican muchos comportamientos que te encontrarás:
speclo escribes tú;statuslo escribe el sistema. Nunca edites unstatusa mano.- Es nivel, no evento. El controlador no reacciona a "se ha borrado un pod": compara la foto actual con la deseada. Por eso el sistema se recupera aunque se pierda un mensaje o un controlador se reinicie.
- Es idempotente. Aplicar el mismo manifiesto diez veces produce el mismo resultado que aplicarlo una.
- La corrección manual no dura. Si borras un pod gestionado por un ReplicaSet, vuelve en segundos. Para que desaparezca hay que cambiar el estado deseado.
- Los fallos son "eventualmente consistentes". Entre que declaras algo y se cumple pasa un tiempo; por eso los objetos tienen condiciones y eventos, y por eso
kubectl geta veces muestra estados intermedios.
- Recorrido completo de
kubectl apply
kubectl applyVamos a seguir una petición real de Rutas Norte. Supón este fichero mínimo en el directorio k8s/ del repositorio (los detalles del formato se ven en la lección Objetos, Manifiestos YAML y el Modelo Declarativo):
# k8s/api-reservas.yaml
apiVersion: v1
kind: Pod
metadata:
name: api-reservas
namespace: rutas-norte-dev
labels:
app: api-reservas
app.kubernetes.io/part-of: rutas-norte
entorno: dev
spec:
containers:
- name: api
image: registry.rutasnorte.example/api-reservas:2.4.0
ports:
- containerPort: 3000Y lo aplicas:
Detrás de esa línea de salida han ocurrido doce pasos.
sequenceDiagram
participant U as kubectl
participant A as kube-apiserver
participant E as etcd
participant S as kube-scheduler
participant K as kubelet (nodo-2)
participant C as containerd
U->>A: 1-2. POST /api/v1/namespaces/rutas-norte-dev/pods (TLS + credenciales)
A->>A: 3. Autenticación
A->>A: 4. Autorización (RBAC)
A->>A: 5. Admisión (mutación y validación)
A->>E: 6. Escribir objeto Pod (sin nodeName)
E-->>A: 7. Confirmación
A-->>U: 8. 201 Created
A-->>S: 9. Evento watch: pod pendiente
S->>A: 10. Filtrado + puntuación -> binding a nodo-2
A->>E: Persistir spec.nodeName=nodo-2
A-->>K: 11. Evento watch: tienes un pod nuevo
K->>C: 12. CRI: descargar imagen y crear contenedor
C-->>K: Contenedor en ejecución
K->>A: Actualizar status: Running
Paso a paso, con detalle:
- kubectl lee tu kubeconfig para saber a qué clúster hablar, con qué credenciales y en qué namespace.
- Convierte el YAML a JSON y lo envía como
POST(oPATCHsi el objeto ya existía) sobre HTTPS al endpoint del recurso. - Autenticación. El apiserver valida tu certificado de cliente o token. Si falla:
error: You must be logged in to the server (Unauthorized). - Autorización. RBAC comprueba si tu usuario puede hacer
create podsen el namespacerutas-norte-dev. Si falla:Error from server (Forbidden). - Control de admisión. Se ejecutan los admission controllers en dos tandas: primero los mutantes (añaden valores por defecto, la ServiceAccount, límites de un LimitRange…) y después los validantes (ResourceQuota, Pod Security Standards, webhooks propios). Cualquiera puede rechazar la petición.
- Escritura en etcd. El objeto se guarda. En este momento el pod ya existe como objeto, aunque no haya ningún contenedor en marcha. Su estado es
Pendingy suspec.nodeNameestá vacío. - etcd confirma la escritura por consenso Raft.
- El apiserver responde a kubectl con
201 Created. Aquí termina tu comando:kubectl applyno espera a que el contenedor arranque. - El scheduler recibe la notificación por su watch sobre pods sin nodo asignado.
- El scheduler decide. Filtra los nodos sin recursos suficientes o incompatibles, puntúa los restantes, elige
nodo-2y escribe el binding en la API. El pod sigue enPending, pero ya tiene destino. - El kubelet de
nodo-2se entera por su propio watch y toma el control. - El kubelet ejecuta: pide al runtime, vía CRI, que descargue
registry.rutasnorte.example/api-reservas:2.4.0(estadoContainerCreating, oImagePullBackOffsi el registro rechaza la descarga), crea el sandbox de red pidiendo una IP al plugin CNI, monta volúmenes y secretos, y arranca el contenedor. Después informa a la API:status.phase = Running.
A partir de ahí, el kubelet vigila el contenedor de forma permanente y el bucle de reconciliación sigue vivo hasta que el objeto se borre.
- Qué pasa cuando falla cada pieza
Esta tabla es oro puro para diagnosticar incidencias, y una pregunta recurrente en entrevistas y certificaciones.
| Componente caído | Qué DEJA de funcionar | Qué SIGUE funcionando |
|---|---|---|
| kube-apiserver | Todo kubectl, todos los controladores, todo cambio de estado |
Los pods ya en marcha siguen sirviendo tráfico; kube-proxy conserva sus reglas |
| etcd (sin quórum) | La API pasa a solo lectura o falla; ningún cambio se persiste | Igual que arriba: las aplicaciones siguen atendiendo |
| kube-scheduler | Los pods nuevos se quedan en Pending para siempre |
Los pods ya asignados arrancan y funcionan con normalidad |
| kube-controller-manager | No se recrean réplicas, no avanzan los despliegues, no se actualizan endpoints | Los pods existentes siguen vivos |
| cloud-controller-manager | No se crean balanceadores nuevos ni se limpian nodos borrados | El resto del clúster funciona |
| kubelet de un nodo | Ese nodo pasa a NotReady; tras ~5 min sus pods se recrean en otros nodos |
Los contenedores de ese nodo pueden seguir corriendo un rato, pero sin supervisión |
| kube-proxy de un nodo | El tráfico hacia Services desde ese nodo deja de enrutarse bien | El resto de nodos enruta correctamente |
| Plugin CNI | Los pods nuevos no obtienen IP; se quedan en ContainerCreating |
Los pods existentes conservan su red |
La conclusión operativa es tranquilizadora: el plano de control es el cerebro, no el corazón. Si se cae, el clúster deja de cambiar, pero no deja de servir. Esto es un diseño deliberado y explica por qué una caída del plano de control es grave pero rara vez es una caída del servicio.
- Alta disponibilidad del plano de control
Un clúster de prácticas tiene un solo nodo de control. Un clúster de producción, como el que Rutas Norte querrá para su namespace rutas-norte-pro, necesita tolerar la pérdida de una máquina del plano de control.
El esquema estándar:
- 3 nodos de plano de control (número impar, por el quórum de etcd).
- kube-apiserver replicado en los tres, detrás de un balanceador o de un
keepalivedcon IP virtual. Al ser sin estado, escala en activo-activo. - etcd en 3 miembros. Tolera la pérdida de 1. Con 5 miembros tolera 2. Con 2 miembros no tolera ninguno: nunca uses un número par.
- scheduler y controller-manager en activo-pasivo. Se ejecutan los tres, pero solo uno actúa: eligen líder mediante un objeto
Leaseen la API. Es imprescindible que solo uno reconcilie, o crearían pods por duplicado. - etcd apilado o externo: apilado (stacked, etcd en las mismas máquinas de control) es lo habitual y más sencillo; externo aísla el fallo y se usa en clústeres grandes.
flowchart LR
LB["Balanceador<br/>o IP virtual"]
subgraph CP1["control-1"]
A1["apiserver"]
E1[("etcd")]
S1["scheduler (líder)"]
end
subgraph CP2["control-2"]
A2["apiserver"]
E2[("etcd")]
S2["scheduler (espera)"]
end
subgraph CP3["control-3"]
A3["apiserver"]
E3[("etcd")]
S3["scheduler (espera)"]
end
LB --> A1
LB --> A2
LB --> A3
E1 <--> E2
E2 <--> E3
E1 <--> E3
Además, en un clúster gestionado (EKS, AKS, GKE, módulo 10-06) el proveedor opera todo esto por ti y ni siquiera ves las máquinas del plano de control: pagas una cuota y solo administras los nodos de trabajo. Para la mayoría de las empresas, incluida Rutas Norte, esa es la opción sensata.
Errores Comunes y Consejos
- Creer que el scheduler arranca contenedores. No: solo escribe un nombre de nodo. Quien arranca es el kubelet. Si un pod está en
Pending, el problema es del scheduler (no cabe en ningún nodo); si está enContainerCreatingoImagePullBackOff, el problema es del kubelet o del runtime. - Pensar que
kubectl applyespera a que la aplicación esté lista. Devuelve en cuanto el objeto se guarda en etcd. Para esperar de verdad, se usakubectl rollout statusokubectl wait. - Modificar recursos a mano en un nodo. Parar un contenedor con
crictlodockerno sirve de nada: el kubelet lo recrea. Siempre se actúa sobre la API. - Olvidar la copia de seguridad de etcd. Es el único componente cuyo dato es irremplazable. Sin snapshot, un desastre en etcd equivale a reconstruir el clúster desde los manifiestos (razón adicional para tenerlos todos en Git).
- Poner 2 miembros de etcd "para tener redundancia". Empeora la disponibilidad: con 2 miembros el quórum es 2, así que perder uno bloquea el clúster. Siempre impar.
- Consejo de diagnóstico: ante cualquier problema, recorre la cadena en orden — ¿el objeto existe en la API? (
kubectl get) → ¿tiene nodo asignado? (kubectl get pod -o wide) → ¿qué dice el kubelet? (kubectl describe pod, sección Events). Ese orden replica exactamente el recorrido de la sección 5.
Ejercicios
Ejercicio 1: Localizar la pieza responsable
Para cada síntoma observado en el clúster de Rutas Norte, indica qué componente es el principal sospechoso y por qué:
- El pod
api-reservaslleva 10 minutos enPendingydescribedice0/3 nodes are available: insufficient memory. kubectl get podsdevuelveUnable to connect to the server: dial tcp ... connection refused.- Se borra a mano un pod de
tienda-webgestionado por un ReplicaSet y no se recrea, pero el resto del clúster responde bien. - El pod
worker-notificacionesestáContainerCreatingdesde hace 5 minutos con el eventofailed to pull image ... unauthorized. - Un nodo aparece como
NotReadyy a los pocos minutos sus pods aparecen en otros nodos.
Ejercicio 2: Reconstruir el recorrido
Ordena estos ocho pasos, que están desordenados, y señala en cuál de ellos el pod pasa de Pending a ContainerCreating:
- a) El kubelet pide al runtime que cree el contenedor vía CRI.
- b) El apiserver escribe el objeto en etcd.
- c) RBAC comprueba los permisos del usuario.
- d) El scheduler escribe
spec.nodeName. - e) kubectl envía la petición HTTPS.
- f) Se ejecutan los admission controllers.
- g) El apiserver responde
201 Created. - h) El kubelet recibe el evento del watch.
Ejercicio 3: Diseño de alta disponibilidad
Rutas Norte quiere un clúster propio para rutas-norte-pro que tolere la caída de una máquina completa del plano de control. Indica: cuántos nodos de control usarías, cuántos miembros de etcd, cómo se accede al apiserver, en qué modo trabajan scheduler y controller-manager, y explica en dos líneas qué pasaría con la tienda web durante los 3 minutos en que el plano de control estuviera completamente caído.
Soluciones
Solución 1
- kube-scheduler (junto con la capacidad de los nodos). El pod se creó correctamente en la API, pero ningún nodo pasa la fase de filtrado por falta de memoria. La solución es reducir los
requestsdel pod o añadir capacidad. - kube-apiserver (o la red hacia él).
connection refusedsignifica que kubectl ni siquiera llega a autenticarse: el proceso no está escuchando o el endpoint del kubeconfig es incorrecto. - kube-controller-manager. El controlador de ReplicaSet es quien recrea las réplicas; si el resto funciona pero nada se reconcilia, el sospechoso es el controller-manager (o su elección de líder).
- kubelet y runtime de contenedores, con causa raíz en las credenciales del registro. El pod ya tiene nodo asignado; el fallo es al descargar la imagen (falta el
imagePullSecret). - kubelet de ese nodo (o la red del nodo). Al dejar de reportar, el controlador de nodos lo marca
NotReadyy, pasado el periodo de tolerancia, desaloja sus pods para que se recreen en otro sitio. Comportamiento esperado, no un error.
Solución 2
Orden correcto: e → c → f → b → g → d → h → a.
- e) petición HTTPS
- c) autenticación y autorización RBAC
- f) admisión (mutación y validación)
- b) escritura en etcd → el pod existe en
Pending - g) respuesta
201 Createda kubectl - d) el scheduler asigna nodo → sigue
Pending, pero ya con destino - h) el kubelet recibe el evento
- a) el kubelet crea el contenedor → aquí el pod pasa a
ContainerCreatingy después aRunning
Solución 3
- 3 nodos de plano de control y 3 miembros de etcd (topología apilada): con quórum de 2, se tolera la pérdida de 1 máquina.
- Acceso al apiserver a través de un balanceador o IP virtual (
keepalived+ HAProxy) que reparta entre las tres réplicas; el kubeconfig apunta a ese punto único, no a una máquina concreta. - kube-scheduler y kube-controller-manager en activo-pasivo, con elección de líder mediante
Lease: los tres procesos corren, pero solo el líder reconcilia, para evitar duplicar acciones. - Durante 3 minutos sin plano de control, la tienda web sigue funcionando con normalidad: los pods ya están corriendo en los nodos y kube-proxy conserva sus reglas de red. Lo que no ocurre en esos 3 minutos es cambio: no se pueden desplegar versiones, ni escalar, ni recrear pods caídos, ni ejecutar
kubectl.
Conclusión
Un clúster de Kubernetes es un conjunto de procesos con responsabilidades muy estrictas que se comunican exclusivamente a través del kube-apiserver, con etcd como única fuente de verdad. El plano de control decide (apiserver, scheduler, controller-manager, cloud-controller-manager) y los nodos ejecutan (kubelet, kube-proxy, runtime vía CRI). El pegamento conceptual es el bucle de reconciliación: comparar el estado deseado que tú declaras con el estado real observado y actuar hasta que coincidan, de forma continua e idempotente. Con ese mapa mental ya puedes razonar sobre incidencias en lugar de adivinar, y sabes por qué la caída del plano de control detiene los cambios pero no el servicio.
Tenemos la arquitectura; nos falta el vocabulario. En las próximas lecciones aparecerán constantemente términos como pod, ReplicaSet, Service, PVC o namespace, y conviene tener un mapa claro de qué es cada cosa y cómo se relacionan entre sí antes de usarlos. Eso es lo que ordena la siguiente lección: Conceptos y Terminología Clave.
Curso de Kubernetes
Módulo 1: Introducción a Kubernetes
- ¿Qué es Kubernetes?
- Arquitectura de Kubernetes
- Conceptos y Terminología Clave
- Configuración de un Clúster de Kubernetes
- La CLI de Kubernetes: kubectl
- Objetos, Manifiestos YAML y el Modelo Declarativo
- El Proyecto del Curso: la Plataforma Rutas Norte
Módulo 2: Componentes Principales de Kubernetes
- Pods
- ReplicaSets
- Deployments
- Actualizaciones, Rollbacks y Estrategias de Despliegue
- Servicios
- Namespaces
- Etiquetas, Selectores y Anotaciones
Módulo 3: Gestión de Configuración y Secretos
- ConfigMaps
- Secrets
- Variables de Entorno
- Cuotas y Límites de Recursos
- LimitRanges y Clases de Calidad de Servicio (QoS)
- ServiceAccounts y Acceso a la API desde los Pods
Módulo 4: Redes en Kubernetes
- Redes de Clúster
- Tipos de Servicios
- DNS Interno y Descubrimiento de Servicios
- Controladores de Ingress
- TLS y Gestión de Certificados con cert-manager
- Políticas de Red
Módulo 5: Almacenamiento en Kubernetes
- Volúmenes
- Volúmenes Persistentes
- Reclamaciones de Volúmenes Persistentes
- Clases de Almacenamiento
- Aprovisionamiento Dinámico, Expansión y Snapshots
- Copias de Seguridad y Restauración de Datos
Módulo 6: Conceptos Avanzados de Kubernetes
- StatefulSets
- DaemonSets
- Trabajos y CronJobs
- Init Containers, Sidecars y Patrones Multi-Contenedor
- Planificación: Afinidad, Taints y Tolerations
- Definiciones de Recursos Personalizados (CRDs)
- Operadores y el Patrón Controlador
Módulo 7: Monitoreo y Registro
- Verificaciones de Salud y Sondas
- Servidor de Métricas y kubectl top
- Monitoreo con Prometheus
- Visualización y Alertas con Grafana y Alertmanager
- Registro Centralizado con Elasticsearch, Fluentd y Kibana (EFK)
- Depuración de Aplicaciones y Eventos del Clúster
Módulo 8: Seguridad en Kubernetes
- Control de Acceso Basado en Roles (RBAC)
- Contextos de Seguridad y Endurecimiento del Contenedor
- Políticas de Seguridad de Pods y Pod Security Standards
- Seguridad de Red
- Seguridad de Imágenes
- Auditoría, Escaneo y Gestión de Vulnerabilidades
Módulo 9: Escalado y Rendimiento
- Autoescalado Horizontal de Pods
- Autoescalado Vertical de Pods
- Autoescalado de Clúster
- Escalado por Eventos y Métricas Personalizadas con KEDA
- Alta Disponibilidad: PodDisruptionBudgets y Topología
- Ajuste de Rendimiento
Módulo 10: Ecosistema y Herramientas de Kubernetes
- Minikube y Entornos Locales con kind
- Kubeadm
- Helm
- Kustomize
- GitOps con Argo CD y Flux
- Kubernetes Gestionado: EKS, AKS y GKE
Módulo 11: Estudios de Caso y Aplicaciones del Mundo Real
- Despliegue de una Aplicación Web
- Ejecución de Aplicaciones con Estado
- CI/CD con Kubernetes
- Estrategias de Despliegue: Blue-Green y Canary
- Gestión Multi-Clúster
- Operación en Producción: Incidencias, Runbooks y Costes
