Saltar al contenido
Alexander Zelada

Ruta 02 · Lección 3 de 4

Laboratorio Cilium + eBPF en Kubernetes Paso a Paso (kind)

Monta un clúster kind sin CNI, instala Cilium con su CLI, revisa agente, operador y CRDs, y verifícalo con el connectivity test.

Alexander Zelada

Alexander Zelada · 8 min de lectura

Ruta 02 · Redes por dentro

En esta lección montas un clúster de Kubernetes con kind, con un nodo control-plane y tres workers y sin CNI, e instalas Cilium con su CLI oficial. Después abrimos cada pieza que despliega Cilium (el agente, el operador, los CRDs y el ConfigMap) y lo verificamos todo con el connectivity test. Este es el laboratorio que se usa en las lecciones siguientes.

Esta lección en vídeo.

Para las próximas lecciones necesito un clúster real, así que aquí lo monto usando kind y Cilium. De paso, voy a abrir cada componente para entender qué función tiene cada uno.

Qué es kind y qué es un CNI

kind significa Kubernetes IN Docker: cada nodo del clúster es un contenedor de Docker. Antes de arrancar, hay un término clave que necesitas tener claro, y es CNI.

CNI significa Container Network Interface. Es una especificación que define cómo un plugin de red tiene que darle IP a un Pod y conectarlo al resto del clúster. Cuando Kubernetes crea un Pod, llama al CNI para que monte el veth pair, asigne la IP y configure las rutas. Cilium, Flannel y Calico, por ejemplo, son CNI.

¿Y por qué kind? Porque tiene dos ventajas concretas. Arranca muy rápido, ya que no hay VMs ni hipervisores. Y te deja desactivar el CNI por defecto, que es justo lo que necesitamos para instalar Cilium.

El clúster que vamos a montar tiene un nodo control-plane y tres workers. Es suficiente para ver cómo Cilium distribuye sus agentes y cómo fluye el tráfico entre nodos.

¿Por qué kind y no minikube? ¿Y por qué la CLI y no Helm?

kind tiene soporte oficial de Cilium, y disableDefaultCNI es una opción nativa de su configuración. Con minikube hacen falta pasos extra.

La Cilium CLI se encarga de la configuración específica de cada entorno. Para producción, lo recomendado es Helm; para aprender, la CLI es más limpia.

kind también funciona en Windows con Docker Desktop y WSL2, pero esta lección está hecha sobre Linux.

Prerrequisitos: kind y la Cilium CLI

Empezamos instalando las dos herramientas que necesitamos. La primera es kind, y para instalarla sigo la documentación oficial:

[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

La segunda es la Cilium CLI, la herramienta que vamos a usar para instalar Cilium, verificar su estado y lanzar los tests de conectividad. También sigo lo que indica la página oficial:

CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}

Validamos que las dos están instaladas:

kind --version
cilium version

Con las dos listas, ya podemos arrancar.

Crear el clúster kind sin CNI

Lo primero es crear el archivo de configuración de kind. Para ello descargo el que proporciona la documentación oficial de Cilium:

curl -LO https://raw.githubusercontent.com/cilium/cilium/1.19.2/Documentation/installation/kind-config.yaml

Ahora veamos qué hay dentro:

cat kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
networking:
  disableDefaultCNI: true

Fíjate en la línea 9: disableDefaultCNI: true. Le dice a kind que no instale su plugin de red por defecto. Si no pones esto, kind instala su propio CNI y, cuando intentes meter Cilium, habrá conflicto entre los dos.

O sea, el clúster arrancará y se crearán los nodos, pero los Pods no podrán comunicarse. Ese es nuestro punto de partida.

Ejecutamos kind create cluster y le asignamos un nombre:

kind create cluster --config=kind-config.yaml --name cilium-lab

Comprobamos que kind ha creado los cuatro nodos:

kubectl get nodes

Si te fijas, el estado es NotReady, y es exactamente lo que esperamos. Los nodos existen y el API server responde, pero no hay CNI, así que Kubernetes no sabe cómo conectar los Pods entre sí. Si intentaras arrancar un Pod ahora mismo, se quedaría en estado Pending.

Instalar Cilium con la CLI

Ahora instalamos Cilium en el clúster, con la versión fijada:

cilium install --version 1.19.2

Mientras se instala, ejecuto cilium status --wait para comprobar que la instalación ha terminado correctamente:

cilium status --wait

El flag --wait hace que el comando se quede esperando hasta que todos los componentes estén en estado OK. Como todo ha ido bien, verifico si los nodos ya están en estado Ready:

kubectl get nodes

Cilium está instalado y la red funciona. Pero antes de pasar al connectivity test, quiero que veamos exactamente qué ha desplegado Cilium en el clúster, porque en las próximas lecciones vas a trabajar con estos componentes directamente.

Los componentes que despliega Cilium

Cilium despliega en el clúster el agente, el operador y los CRDs, y guarda su configuración en un ConfigMap. Empezamos por el agente.

El agente: DaemonSet cilium

El agente es el componente que hace el trabajo real. Carga los programas eBPF en el kernel, conecta cada Pod a la red y aplica las Network Policies. Corre como DaemonSet, es decir, con un Pod en cada nodo. Lo vemos ejecutando:

kubectl get pods -n kube-system -l k8s-app=cilium -o wide

En la columna NODE aparecen control-plane, worker, worker2 y worker3: un agente por nodo. Si pierdes el agente en un nodo, los Pods que ya corren ahí siguen con red, porque los programas eBPF siguen cargados, pero los Pods nuevos no arrancan y los cambios de política no se aplican.

Este Pod es especial porque necesita acceso privilegiado al host. Monta directorios del kernel como /sys/fs/bpf o /proc, porque está programando el kernel. Es de los pocos Pods en Kubernetes que necesitan de verdad ese nivel de acceso.

El operador: Deployment cilium-operator

Pasamos al operador. Para verlo ejecutamos:

kubectl get deployment cilium-operator -n kube-system

A diferencia del agente, el operador corre una sola réplica y no toca el tráfico. Su trabajo es mantener el orden dentro del clúster: el agente ejecuta y el operador coordina.

El operador limpia las identidades y los objetos que ya no tienen un Pod detrás y confirma que cada agente está activo. Si el operador se cae, la red sigue funcionando, pero esas tareas de mantenimiento quedan en pausa hasta que vuelva.

Los CRDs: extensiones del API de Kubernetes

Ahora los CRDs. Los listamos ejecutando:

kubectl get crds | grep cilium

Aparecen 10 CRDs, es decir, 10 tipos de objetos nuevos que Cilium registró en el API de Kubernetes. No hace falta verlos todos, solo los tres que vas a usar en las próximas lecciones.

El primero es CiliumNode. Lo vemos ejecutando:

kubectl get ciliumnodes

Hay uno por nodo, y cada uno guarda el rango de IPs que ese nodo puede repartir a sus Pods. Por ejemplo, el worker tiene el rango 10.244.2.0/24, así que cualquier Pod que arranque ahí recibe una IP de ese bloque. Esos rangos se reparten por nodo (los asigna Kubernetes o el operador de Cilium, según el modo de IPAM) para que no haya colisiones entre nodos.

El segundo es CiliumEndpoint. Lo listamos ejecutando:

kubectl get ciliumendpoints -A

Fíjate en la columna SECURITY IDENTITY. Los dos Pods de CoreDNS comparten el mismo número. ¿Por qué? Porque tienen los mismos labels. Cilium no asigna identidades por Pod, sino por conjunto de labels.

Esto es clave. Si un Pod muere y rearranca con otra IP, su identidad no cambia, y el kernel sigue comparando el mismo número. Por eso las Network Policies en Cilium no dependen de las IPs.

El tercero es CiliumNetworkPolicy. Lo comprobamos ejecutando:

kubectl get ciliumnetworkpolicies -A

La lista sale vacía. Todavía no hemos definido ninguna política, y este es exactamente el objeto que vamos a crear en la siguiente lección.

La configuración: ConfigMap cilium-config

Para terminar con los componentes, vamos a ver dónde queda guardada la configuración de Cilium:

kubectl get configmap cilium-config -n kube-system -o yaml | grep -E "^  (datapath-mode|enable-hubble|enable-l7-proxy|enable-k8s-networkpolicy):"

Todo lo que instalamos con cilium install acabó en este ConfigMap. Lo importante ahora es esto: Cilium usa veth pairs para conectar los Pods, como vimos en la lección de veth. Hubble está activado para registrar eventos de red. Y las NetworkPolicy nativas de Kubernetes también están habilitadas, así que puedes usar las de Kubernetes y las de Cilium en el mismo clúster.

Verificar la instalación con el connectivity test

Para verificar que todo está bien, empezamos ejecutando:

cilium status

Todo en verde. Pero la prueba real no es mirar el estado interno, sino comprobar que el tráfico fluye. Para eso ejecutamos el connectivity test:

cilium connectivity test

Este comando despliega un namespace de test, lanza Pods de cliente y de servidor y ejecuta decenas de pruebas: ping entre Pods del mismo nodo y entre nodos distintos, tráfico HTTP, DNS y acceso externo.

Todo en verde. El clúster está listo, y este es el entorno que usaremos en las próximas lecciones.

No borres el clúster: lo usamos en la siguiente lección. Cuando ya no lo necesites, lo puedes borrar con kind delete cluster --name cilium-lab.

Lo que hemos visto

  • Creamos un clúster kind con un control-plane y tres workers, con disableDefaultCNI: true, así que los nodos arrancan en NotReady porque no hay CNI.
  • Instalamos Cilium con la CLI oficial y la versión fijada, y los nodos pasaron a Ready.
  • Abrimos cada componente: el agente programa el kernel en cada nodo, el operador coordina identidades y endpoints, y los CRDs extienden el API de Kubernetes.
  • En CiliumEndpoint vimos que la identidad depende de los labels y no de la IP, y en el ConfigMap cilium-config que Hubble y las NetworkPolicy nativas están activados.
  • Verificamos la instalación con cilium connectivity test, que comprueba tráfico entre Pods, HTTP, DNS y acceso externo.