Lesson  in  Kubernetes 101

Los componentes del clúster

Antes de crear nada, conoce la maquinaria: recorre un clúster Kubernetes vanilla y localiza el API server, etcd, el scheduler, el controller manager, el kubelet y kube-proxy, cada uno en su sitio.

Llevas todo el curso pidiéndole cosas a Kubernetes. Este laboratorio va del otro lado del mostrador: un paseo guiado, sin escribir ni una línea de YAML, para ponerle cara a la maquinaria que ha estado atendiéndote.

Va al final a propósito. Cada uno de estos componentes se explica en el libro donde hace falta y no todos juntos —kube-proxy en el capítulo de Red, el kube-scheduler en el de Scheduling—, así que hasta aquí no habrías tenido con qué relacionarlos. Ahora sí. Junto a cada uno verás dónde lo cuenta el libro, por si quieres volver.

Y es un clúster especial para la ocasión. El resto del curso usa k3s, una distribución que empaqueta todo Kubernetes en un solo binario (comodísimo, pero opaco). Hoy el playground es Kubernetes vanilla instalado con kubeadm, donde cada componente corre por separado y a la vista. Un control plane en la máquina cplane-01 y nodos worker donde correrán las aplicaciones.

Paso 1: Los nodos

Abre la pestaña dev-machine y pide el mapa:

kubectl get nodes -o wide

Ahí está la división fundamental del clúster: cplane-01 con el rol control-plane (el cerebro) y los nodos worker (el músculo). Ese comando que acabas de ejecutar, por cierto, ya ha atravesado medio clúster: kubectl ha hablado por HTTPS con el API server, que es la puerta de entrada única de Kubernetes. Nadie (ni tú, ni los componentes internos) habla con nadie si no es a través de él.

Paso 2: El control plane, componente a componente

Los componentes del cerebro no son demonios misteriosos: en un clúster kubeadm son Pods, y viven en el namespace kube-system. Míralos:

kubectl get pods -n kube-system -o wide

Localiza estos cuatro, todos con el sufijo -cplane-01 porque corren en el control plane:

  • kube-apiserver: la puerta de entrada. Valida y atiende cada petición de la API. → capítulo de Arquitectura, y su cadena de admisión en el de Seguridad.
  • etcd: la memoria. Una base de datos clave-valor donde vive todo el estado del clúster; es lo único que Kubernetes necesita respaldar. → Apéndice D.
  • kube-scheduler: el asignador. Decide en qué nodo debe correr cada Pod nuevo (y solo decide: no ejecuta nada). → capítulo de Scheduling, donde además está todo lo que puedes hacer para influir en esa decisión.
  • kube-controller-manager: el insistente. Ejecuta los bucles de control que comparan sin descanso el estado deseado con el real y corrigen la diferencia. La "magia" declarativa de Kubernetes sale de aquí. → Apéndice D, y el bucle en sí en el capítulo de Extensibilidad, donde escribes uno.

Fíjate también en los que no llevan el sufijo del control plane: los Pods de kube-proxy (hay uno por cada nodo del clúster, control plane incluido) y los de coredns. A esos volveremos en el paso 5.

Deja constancia del recorrido guardando el inventario completo en un archivo:

kubectl get pods -n kube-system -o wide > /home/laborant/componentes.txt

Paso 3: Los static Pods y su carpeta secreta

Aquí hay un huevo y gallina delicioso: si el scheduler es un Pod, ¿quién programó al scheduler? La respuesta está en el propio nodo. Abre la pestaña cplane-01 y mira dentro de la configuración de Kubernetes:

sudo ls -l /etc/kubernetes/manifests

Cuatro archivos YAML, uno por componente del control plane. Son static Pods: el kubelet de este nodo vigila esa carpeta y ejecuta directamente cualquier manifiesto que encuentre en ella, sin pasar por el API server ni por el scheduler. Así arranca el control plane: primero el kubelet, que levanta estos cuatro Pods leyendo el disco, y con ellos arranca el clúster. Puedes asomarte a uno (todavía no entenderás cada campo, y no pasa nada):

sudo head -20 /etc/kubernetes/manifests/kube-scheduler.yaml

Paso 4: El kubelet, el que no puede ser un Pod

Sigues en cplane-01. El kubelet es el agent que corre en cada nodo y convierte las decisiones del clúster en contenedores de verdad, hablando con el runtime (aquí, containerd). Y tiene una particularidad que ya habrás deducido del paso anterior:

systemctl status kubelet

Es un servicio de systemd, un proceso del sistema operativo. No puede ser un Pod por pura lógica: alguien tiene que estar ahí antes que los Pods para poder ejecutarlos. Es el único componente de esta lección que vive fuera del clúster que él mismo sostiene.

El libro lo cuenta en el capítulo de Arquitectura, y cómo habla con el runtime de contenedores (CRI, containerd, runc) en el Apéndice D.

Paso 5: Los que están en todos los nodos

Vuelve a la pestaña dev-machine para los dos últimos protagonistas:

kubectl get daemonset,deployment -n kube-system
  • kube-proxy aparece como un objeto llamado DaemonSet, cuya misión es garantizar una copia en cada nodo. Programa las reglas de red locales de cada máquina para que el tráfico de los Services llegue a su destino. → abre el capítulo de Red, porque no se entiende sin el Service; el DaemonSet, en el de Workloads.
  • CoreDNS es el servidor DNS interno del clúster, y corre como un Deployment normal y corriente, el mismo tipo de objeto que usas tú para tus aplicaciones. → capítulo de Red, sección de CoreDNS.

Si te apetece verlo todo dibujado, la pestaña Explorer muestra el grafo de objetos de kube-system en directo.

El resumen que llevarte al resto del curso

  • Todo pasa por el API server; todo se recuerda en etcd.
  • El scheduler decide dónde, los controllers insisten hasta que el estado real coincide con el deseado.
  • El kubelet ejecuta en cada nodo (y es systemd, no Pod); kube-proxy enruta en cada nodo; CoreDNS da nombre a las cosas.
  • El control plane de kubeadm son static Pods leídos de /etc/kubernetes/manifests.

Fíjate en que casi todo lo de esta lección lo has estado usando sin verlo: cada kubectl apply del curso ha pasado por el API server, ha acabado en etcd, lo ha colocado el scheduler y lo ha ejecutado un kubelet.

Y queda una cosa por hacer con esta maquinaria, que es romperla. La lección siguiente cierra el curso apagando el kube-scheduler de este mismo tipo de clúster, para ver qué deja de funcionar y —lo que sorprende a casi todo el mundo— qué sigue funcionando tan tranquilo.