Saltar al contenido

Kubernetes desde cero: componentes, nodos e interfaces principales

Augusto Mancuso
Published date:

Kubernetes desde cero: componentes, nodos e interfaces principales

Kubernetes, también conocido como K8s, es una plataforma open source para administrar cargas de trabajo y servicios en contenedores. Su objetivo es permitir que las aplicaciones puedan desplegarse, escalarse, actualizarse y recuperarse de fallos de forma automatizada.

La documentación oficial lo define como una plataforma portable y extensible para gestionar workloads y servicios, facilitando la configuración declarativa y la automatización. (Kubernetes)

Pero Kubernetes no es simplemente “una herramienta para correr contenedores”. Es más útil pensarlo como una plataforma de orquestación distribuida.

Kubernetes coordina nodos, contenedores, redes, almacenamiento, balanceo interno, políticas de seguridad, controladores y APIs para que una aplicación pueda ejecutarse de forma confiable sobre distintos tipos de infraestructura: cloud pública, entornos on-premise o arquitecturas híbridas.

En este post quiero ordenar los conceptos base que conviene entender antes de meterse en temas más avanzados como Ingress, Gateway API, Service Mesh, GitOps, autoscaling, observabilidad o despliegues multi-cluster.


La idea principal: Kubernetes trabaja con estado deseado

Uno de los conceptos más importantes de Kubernetes es el de estado deseado.

En lugar de conectarnos manualmente a un servidor y ejecutar procesos uno por uno, declaramos qué queremos que exista.

Por ejemplo:

Quiero 3 réplicas de esta aplicación.
Quiero exponer este servicio en el puerto 80.
Quiero que este Pod tenga 512 MiB de memoria.
Quiero montar este volumen persistente.

Kubernetes toma esa definición e intenta acercar el estado real del cluster al estado deseado.

Si declaramos que una aplicación debe tener 3 réplicas y una se cae, Kubernetes intenta crear otra. Si actualizamos la imagen de un contenedor, Kubernetes puede hacer un rolling update.

Si un nodo deja de estar disponible, Kubernetes puede crear reemplazos para workloads gestionados por controladores, como Deployments, StatefulSets o Jobs, siempre que existan nodos aptos y que las restricciones de scheduling, almacenamiento, afinidad o toleraciones lo permitan.

Esa lógica de reconciliación es una de las bases del modelo operativo de Kubernetes.


Cómo se divide un cluster Kubernetes

Un cluster Kubernetes se divide principalmente en dos grandes partes:

Kubernetes Cluster
├── Control Plane
└── Worker Nodes

El Control Plane es el cerebro del cluster. Expone la API, guarda el estado, decide dónde se ejecutan los Pods y ejecuta los controladores.

Los Worker Nodes son los nodos donde corren realmente las aplicaciones. Ahí viven los Pods, los contenedores, el runtime, la red de Pods y parte de la integración con storage.

La documentación oficial resume esta arquitectura en componentes de control plane y componentes de nodo. El control plane gestiona el estado global del cluster, mientras que los nodos ejecutan y mantienen los Pods. (Kubernetes)


Componentes del Control Plane

El Control Plane está compuesto por varios componentes principales. Cada uno cumple una función distinta, pero todos trabajan alrededor de la misma idea: mantener el cluster alineado con el estado deseado.

kube-apiserver

El kube-apiserver es la puerta de entrada al cluster.

Todo lo que interactúa con Kubernetes habla, directa o indirectamente, con el API Server:

Cuando ejecutamos:

kubectl apply -f deployment.yaml

en realidad estamos enviando una solicitud al kube-apiserver.

Sus responsabilidades principales son:

De forma simplificada:

kubectl

kube-apiserver

etcd

El API Server es crítico porque todos los componentes del cluster se coordinan a través de él.


etcd

etcd es la base de datos clave-valor donde Kubernetes guarda el estado del cluster.

Ahí se almacena información como:

Por ejemplo, si creamos un Deployment con 3 réplicas, esa definición queda persistida en etcd.

Deployment nginx replicas=3

etcd

Esto es importante porque Kubernetes no “recuerda” el estado del cluster mágicamente. Lo guarda en etcd.

Por eso, en clusters productivos, etcd debe tratarse como un componente crítico. Si perdemos etcd sin backup, podemos perder el estado completo del cluster.

También hay un punto de seguridad importante: como etcd almacena Secrets, en producción conviene habilitar encryption at rest, limitar el acceso con RBAC y proteger los backups de etcd. Por defecto, los Secrets de Kubernetes no deben asumirse como cifrados en reposo. (Kubernetes)


kube-scheduler

El kube-scheduler decide en qué nodo se va a ejecutar cada Pod.

Cuando se crea un Pod, al principio queda en estado pendiente. El scheduler evalúa los nodos disponibles y elige el más adecuado.

Para tomar esa decisión puede considerar, entre otras cosas:

Ejemplo simplificado:

Pod backend-api pendiente

scheduler evalúa nodos

scheduler elige worker-03

Una vez tomada la decisión, esa asignación se guarda a través del API Server.


kube-controller-manager

El kube-controller-manager ejecuta varios controladores que mantienen el estado real del cluster alineado con el estado deseado.

Un controller observa recursos de Kubernetes y actúa cuando detecta una diferencia entre lo que debería existir y lo que realmente existe.

Ejemplo:

Estado deseado: 3 réplicas de nginx
Estado real:    2 réplicas vivas
Acción:         crear una réplica nueva

Algunos controllers típicos son:

Este patrón de reconciliación aparece una y otra vez en Kubernetes. Entenderlo ayuda mucho para leer cómo funcionan Deployments, Jobs, Operators y varios componentes más.


cloud-controller-manager

El cloud-controller-manager es un componente opcional que aparece cuando Kubernetes se integra con un proveedor cloud o con una plataforma de infraestructura específica.

En una cloud pública puede encargarse de tareas como:

Algunos ejemplos:

En un entorno on-premise, como Proxmox, puede no existir un cloud-controller-manager equivalente al de una cloud pública, o puede existir uno específico de la plataforma.

En esos casos suelen combinarse herramientas que cubren responsabilidades distintas:

Es importante no confundir estas herramientas: no todas reemplazan al cloud-controller-manager. Cada una resuelve una parte distinta de la integración entre Kubernetes y la infraestructura.


Componentes de los Worker Nodes

Los Worker Nodes son los nodos donde corren las aplicaciones. Cada worker tiene varios componentes importantes.

kubelet

El kubelet es el agente principal del nodo.

Cada nodo worker tiene un kubelet. Su trabajo es comunicarse con el API Server y asegurarse de que los Pods asignados a ese nodo estén corriendo.

Sus responsabilidades principales son:

Flujo simplificado:

API Server

kubelet

container runtime

contenedores

Ejemplo:

scheduler asigna un Pod a worker-02

kubelet de worker-02 detecta la asignación

kubelet llama al runtime

containerd crea el contenedor

Container runtime

El container runtime es el software que ejecuta los contenedores.

Kubernetes no ejecuta contenedores directamente. El kubelet se comunica con un runtime compatible mediante la Container Runtime Interface, o CRI.

Ejemplos actuales de runtimes:

Docker Engine no es usado directamente por Kubernetes desde la remoción de dockershim en Kubernetes 1.24. Solo puede integrarse mediante una capa compatible con CRI, como cri-dockerd, si se instala y configura explícitamente. (Kubernetes)

Flujo típico:

kubelet

CRI

containerd

runc

contenedor

kube-proxy

kube-proxy implementa parte de la conectividad de los Services dentro del cluster.

Cuando creamos un Service, Kubernetes genera una forma estable de acceder a un conjunto de Pods, aunque esos Pods cambien de IP o sean recreados.

Ejemplo:

Service api-service → 10.96.20.15:80

Backends reales:
├── Pod 10.244.1.10:8080
├── Pod 10.244.2.11:8080
└── Pod 10.244.3.12:8080

kube-proxy mantiene reglas de red para que el tráfico hacia el Service llegue a los Pods correspondientes.

Tradicionalmente puede trabajar con backends como iptables o IPVS. En versiones modernas de Kubernetes también existe soporte para nftables, dependiendo de la versión y configuración del cluster.

Kubernetes documenta kube-proxy como un componente opcional del nodo. En algunos clusters, especialmente con CNIs que implementan service proxying en su propio dataplane, kube-proxy puede omitirse o ser reemplazado. Un ejemplo conocido es Cilium en modo kube-proxy replacement, usando eBPF. (Kubernetes)


CNI plugin

El CNI plugin implementa la red de Pods.

Kubernetes define el modelo de red, pero no implementa por sí solo toda la red. Para eso delega en plugins de red, normalmente basados en Container Network Interface, o CNI.

Ejemplos:

El CNI se encarga de tareas como:

Ejemplo:

Pod A en worker-01

red del cluster

Pod B en worker-03

Esa comunicación entre Pods de distintos nodos funciona gracias a la implementación de red del cluster.

Un matiz importante: en Kubernetes actual, la gestión de CNI ya no está dentro del alcance directo del kubelet. El kubelet solicita al container runtime la creación del Pod sandbox, y el runtime, configurado con CNI, invoca el plugin de red para crear la interfaz del Pod, asignar IP y conectar el Pod a la red del cluster. (Kubernetes)


CSI node plugin

Si usamos almacenamiento persistente, normalmente también tendremos componentes CSI corriendo en los nodos.

CSI significa Container Storage Interface y permite integrar Kubernetes con sistemas de almacenamiento externos.

Ejemplos de drivers:

Un driver CSI suele tener componentes de controller y de node.

El controller plugin puede encargarse de tareas como:

El node plugin corre en los nodos y suele encargarse de:

La documentación oficial explica que el subsistema de PersistentVolumes abstrae cómo se provee el storage de cómo lo consume el usuario mediante PersistentVolumes y PersistentVolumeClaims. (Kubernetes)


Interfaces y extensiones principales de Kubernetes

Una de las razones por las que Kubernetes se volvió tan importante es que no intenta resolver todo de una única manera.

En lugar de eso, define interfaces y puntos de extensión. Esto permite elegir distintas tecnologías para runtime, red, storage, seguridad, observabilidad o entrada de tráfico.


CRI: Container Runtime Interface

CRI es la interfaz entre el kubelet y el runtime de contenedores.

kubelet

CRI

containerd / CRI-O

Gracias a CRI, Kubernetes puede trabajar con distintos runtimes sin depender de uno solo.

Funciones típicas:

Ejemplo práctico:

kubectl run nginx --image=nginx

Flujo simplificado:

API Server recibe el Pod

Scheduler asigna un nodo

kubelet del nodo recibe el Pod

kubelet llama al runtime por CRI

containerd descarga la imagen

containerd crea e inicia el contenedor

CNI: Container Network Interface

CNI es la interfaz usada por el runtime para conectar los Pods a la red del cluster.

kubelet

container runtime

CNI plugin

red del Pod

Ejemplos:

En un cluster productivo, la elección del CNI es importante porque impacta en varios aspectos:

Para entornos on-premise, Calico y Cilium suelen ser opciones interesantes. Calico tiene mucho peso en networking tradicional, BGP y NetworkPolicy. Cilium agrega un enfoque moderno basado en eBPF, con buenas capacidades de observabilidad y funcionalidades avanzadas.


CSI: Container Storage Interface

CSI permite integrar Kubernetes con sistemas de storage externos.

Kubernetes

CSI driver

storage

Objetos relacionados:

Ejemplo:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: datos-app
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ceph-rbd
  resources:
    requests:
      storage: 20Gi

Flujo simplificado:

PVC

StorageClass

CSI controller plugin

volumen

Pod

CSI node plugin

montaje del volumen en el nodo

La provisión dinámica permite crear volúmenes bajo demanda cuando un usuario crea un PersistentVolumeClaim, siempre que exista una StorageClass configurada para ese provisioner. (Kubernetes)

En infraestructura on-premise, algunas alternativas comunes son:


CRDs: Custom Resource Definitions

Las CRDs permiten extender la API de Kubernetes con nuevos tipos de recursos.

Kubernetes trae recursos nativos como:

Pero con CRDs podemos agregar recursos nuevos, por ejemplo:

La documentación oficial explica que CustomResourceDefinition permite definir recursos personalizados y que la API de Kubernetes se encarga de servirlos y almacenarlos. (Kubernetes)

Ejemplo conceptual:

apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: db-secret
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-store
    kind: SecretStore
  target:
    name: db-secret
    creationPolicy: Owner
  data:
    - secretKey: password
      remoteRef:
        key: prod/db
        property: password

Kubernetes no sabe de AWS Secrets Manager, Vault o Google Secret Manager de forma nativa. Pero con una CRD y un controller podemos extender Kubernetes para manejar esos casos.

El ejemplo anterior es orientativo: para que funcione en un cluster real, también tiene que existir el SecretStore o ClusterSecretStore, el backend externo y el controller correspondiente.


Operators y controllers

Un controller observa recursos de Kubernetes y toma acciones para reconciliar el estado.

Un Operator es un controller especializado que normalmente usa CRDs para gestionar aplicaciones complejas.

CRD + Controller = Operator

Ejemplos:

Ejemplo conceptual:

Creamos un recurso Certificate

cert-manager lo observa

cert-manager solicita o renueva un certificado

cert-manager crea o actualiza un Secret TLS

Este patrón es clave porque permite operar aplicaciones complejas usando el mismo modelo declarativo de Kubernetes.


Ingress Controller

Ingress es un recurso estándar de Kubernetes para exponer aplicaciones HTTP/HTTPS, pero Kubernetes no implementa por sí solo el proxy reverso.

Para que un Ingress funcione necesitamos un Ingress Controller.

Ingress

Ingress Controller

NGINX / HAProxy / Traefik / Envoy / Kong

Ejemplos:

La documentación oficial define Ingress como un objeto de API que administra el acceso externo a los Services del cluster, normalmente HTTP. (Kubernetes)

Ejemplo:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api
spec:
  rules:
    - host: api.empresa.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api
                port:
                  number: 8080

Gateway API

Gateway API es una evolución más moderna y expresiva del modelo de entrada de tráfico en Kubernetes.

Mientras Ingress puede quedarse corto para escenarios avanzados, Gateway API propone un modelo más flexible y orientado a roles.

La documentación oficial describe Gateway API como una familia de APIs para provisioning dinámico de infraestructura y routing avanzado de tráfico. También destaca su diseño orientado a roles, portabilidad, expresividad y extensibilidad. (Kubernetes)

Objetos estables comunes:

Según la versión de Gateway API instalada y el canal elegido, también pueden existir otros tipos de Route, como:

Conviene verificar el estado de cada recurso y el soporte de la implementación elegida. No todos los controllers soportan todos los tipos de Route, y algunos recursos pueden requerir instalar APIs experimentales.

Ejemplo conceptual:

Equipo de infraestructura crea Gateway

Equipo de aplicación crea HTTPRoute

Esto es útil cuando infraestructura y desarrollo tienen responsabilidades separadas.

Para un entorno on-premise con varios clusters Kubernetes, Gateway API puede ayudar a estandarizar cómo se expone el tráfico dentro de cada cluster. Luego, por delante, puede existir una capa global de balanceo con HAProxy, NGINX, Envoy, F5, FortiADC u otra solución.


Admission Webhooks

Los Admission Webhooks permiten validar o modificar recursos antes de que se guarden en Kubernetes.

Flujo simplificado:

kubectl apply

authentication

authorization

admission

etcd

Hay dos tipos principales:

Ejemplos de validación:

Ejemplos de mutación:

Herramientas comunes:

Este mecanismo es muy importante para aplicar políticas de seguridad y estándares internos dentro del cluster.

En producción, los Admission Webhooks deben diseñarse con cuidado: configurar timeouts razonables, failurePolicy, alta disponibilidad, certificados válidos, métricas y alertas. Un webhook caído o lento puede afectar la creación o actualización de recursos. La política failurePolicy define si un error o timeout del webhook se ignora o si la request se rechaza. (Kubernetes)


Cómo se ve esto en una instalación con kubeadm

En una instalación con kubeadm, los componentes principales del Control Plane suelen correr como static Pods.

Los manifiestos están en:

/etc/kubernetes/manifests/

Ahí normalmente podemos encontrar:

kube-apiserver.yaml
kube-controller-manager.yaml
kube-scheduler.yaml

Si se usa etcd local, también suele existir:

etcd.yaml

Esto significa que el kubelet del nodo control plane se encarga de levantar esos componentes como Pods estáticos.

Si el cluster usa etcd externo, kubeadm no genera el static Pod local de etcd.

En los workers, en cambio, normalmente encontramos:


Errores comunes o puntos importantes

Pensar que Kubernetes ejecuta contenedores directamente

Kubernetes no ejecuta contenedores por sí mismo. El kubelet se comunica con un runtime compatible mediante CRI, y ese runtime es el que termina creando los contenedores.

kubelet

CRI

container runtime

contenedor

Confundir Ingress con Ingress Controller

Ingress es un recurso de Kubernetes. El Ingress Controller es el componente que implementa el comportamiento real.

Sin un controller instalado, crear un recurso Ingress no alcanza para exponer una aplicación.


Asumir que todos los clusters tienen cloud-controller-manager

En clouds públicas suele existir una integración clara con el proveedor. En entornos on-premise, esto depende mucho de la plataforma y de las herramientas instaladas.

Por eso conviene separar responsabilidades:


Tratar etcd como un componente secundario

etcd es crítico. Guarda el estado del cluster.

En producción debería tener backups, monitoreo, control de acceso, cifrado en reposo cuando corresponda y una estrategia clara de recuperación.


Elegir CNI o CSI sin mirar el contexto

No todos los plugins resuelven lo mismo ni tienen las mismas capacidades.

Antes de elegir un CNI conviene revisar:

Antes de elegir un CSI conviene revisar:


Resumen rápido

CapaComponenteFunción principal
Control Planekube-apiserverExpone la API del cluster
Control PlaneetcdGuarda el estado del cluster
Control Planekube-schedulerDecide en qué nodo corre cada Pod
Control Planekube-controller-managerEjecuta controllers de reconciliación
Control Planecloud-controller-managerIntegra Kubernetes con la infraestructura subyacente
WorkerkubeletAgente del nodo; gestiona Pods
Workercontainer runtimeEjecuta contenedores mediante CRI
Workerkube-proxyImplementa Services y balanceo interno, si aplica
WorkerCNI pluginImplementa la red de Pods
WorkerCSI node pluginMonta volúmenes persistentes en los nodos
ExtensiónCRDAgrega nuevos recursos a la API
ExtensiónOperatorAutomatiza operación de aplicaciones complejas
EntradaIngress ControllerExpone tráfico HTTP/HTTPS mediante recursos Ingress
Entrada modernaGateway APIRouting avanzado y modelo orientado a roles

Cierre

Kubernetes puede parecer difícil al principio porque tiene muchos componentes y nombres nuevos. Pero la arquitectura se vuelve más fácil de entender cuando la dividimos en capas.

El Control Plane toma decisiones, guarda el estado y coordina el cluster.

Los Worker Nodes ejecutan las aplicaciones.

Y las interfaces como CRI, CNI y CSI permiten que Kubernetes sea extensible y pueda integrarse con distintos runtimes, redes y sistemas de almacenamiento.

La idea que me parece más importante es esta: Kubernetes no es un producto cerrado. Es una plataforma extensible que define contratos claros y permite elegir implementaciones según el contexto.

En entornos cloud-native reales, especialmente on-premise o híbridos, entender estos componentes es clave para diseñar clusters más confiables, seguros, observables y fáciles de operar.


Fuentes

1) Kubernetes y arquitectura del cluster

2) Runtime, red y storage

3) Extensión de Kubernetes

4) Entrada de tráfico

5) Seguridad

Previous
EnvoyBrokerLab: laboratorio local para entender Envoy, control planes y aprovisionamiento asíncrono
Next
Ingress vs Gateway API: dos formas de exponer tráfico en Kubernetes