Problema

Montar un clúster Kubernetes en placas de bajo consumo (SBC) suele implicar recortes: una única interfaz de 1 GbE, almacenamiento en SD/eMMC, poca RAM y distribuciones ligeras como k3s. Estas limitaciones hacen que el entorno de pruebas no refleje la complejidad de un clúster de producción y, cuando se intenta escalar, aparecen cuellos de botella de red, pérdida de datos y problemas de consistencia. El reto real es conseguir un entorno “casi‑prod” con hardware limitado, manteniendo:

  • Red de alta velocidad para tráfico de pods y BGP.
  • Almacenamiento persistente con replicación.
  • Inmutabilidad del nodo para evitar drift.
  • Control de versiones declarativo (GitOps).

Causa

Los fallos habituales en este tipo de despliegues provienen de tres áreas:

  1. Red insuficiente – Usar la única NIC del SBC para gestión, BGP y tráfico de pods genera congestión y colisiones ARP. Además, la falta de separación física dificulta la aplicación de políticas de red avanzadas.
  2. Almacenamiento volátil – Las tarjetas SD/eMMC no están diseñadas para IOPS intensivo; cuando se usa como backend de etcd o PV, la latencia aumenta y aparecen errores de escritura.
  3. Configuración mutable – Sistemas operativos tradicionales permiten acceso SSH y cambios ad‑hoc. Con el tiempo, los nodos divergen, lo que rompe la reproducibilidad y complica la recuperación ante fallos.

Solución

Una arquitectura modular que aborda cada causa permite replicar un entorno de producción sin sacrificar la simplicidad del SBC.

1. Selección de hardware y topología de red

  • Dos NICs nativas por nodo: una dedicada a gestión/BGP/ingress y otra aislada para tráfico de pods (Cilium en modo “direct routing”). Conexión mediante cableado 2.5 GbE y PoE+ elimina adaptadores externos y reduce puntos de falla.
  • Switch PoE 2.5 GbE (por ejemplo, Ubiquiti Flex) alimenta los SBC y provee el enlace troncal. Mantener un solo cable de alimentación simplifica el cableado y evita fuentes de alimentación múltiples.

2. Sistema operativo inmutable – Talos Linux

Talos elimina SSH, expone solo una API segura y garantiza que el estado del nodo sea idéntico tras cada reinicio. La configuración se declara en archivos YAML y se aplica con talosctl. Un flujo típico:

talosctl apply-config -n 10.0.0.2 -f talos-node.yaml
talosctl bootstrap -n 10.0.0.2

3. Red de capa 3 con Cilium y BGP

Cilium sustituye a kube‑proxy y permite anunciar rutas de servicios mediante BGP. Cada nodo ejecuta un daemon FRR que anuncia los IPs de carga balanceada al router UDR. La configuración mínima de HelmRelease para Cilium incluye:

controller:
  enabled: true
bgp:
  enabled: true
  announce:
    loadbalancerIPs: true
    podCIDR: true

4. Almacenamiento distribuido con Longhorn

Longhorn replica cada volumen en los NVMe PCIe 3.0 de los tres nodos (1 TB cada uno). Con tres réplicas, la pérdida de un nodo no afecta la disponibilidad. La instalación se hace vía Helm y se habilita defaultReplicaCount: 3.

5. GitOps con Flux

Flux monitoriza un repositorio Git y sincroniza los manifests de Talos, Cilium y Longhorn. Cada cambio pasa por revisión de código, lo que evita configuraciones manuales y asegura trazabilidad.

6. Automatización del provisioning

Un script de bootstrap que:

  1. Instala Talos en cada SBC (flasheo de la imagen oficial).
  2. Configura la red estática y habilita PoE.
  3. Aplica los manifests de Helm (Cilium, Longhorn, Flux).
  4. Registra los peers BGP en FRR.

Cuándo aplicar esta solución

Escenarios ideales

  • Homelabs o edge sites donde se dispone de SBC con al menos dos NICs y capacidad PCIe.
  • Necesidad de reproducir un entorno de producción (por ejemplo, pruebas de CI/CD, validación de políticas de red).
  • Requerimientos de alta disponibilidad de almacenamiento y balanceo de carga sin invertir en servidores x86.

Señales de que la solución es adecuada

  • Latencia de red superior a 1 GbE o congestión en la NIC de gestión.
  • Fallos recurrentes de ETCD o PV por I/O limitado.
  • Necesidad de mantener la configuración del nodo bajo control de versiones.

Casos donde no aplica

  • SBC sin NIC adicional (solo 1 GbE) – la separación de tráfico no será posible.
  • Entornos donde el consumo energético es crítico y no se dispone de PoE.
  • Clústeres con menos de tres nodos – Longhorn necesita al menos tres réplicas para tolerancia a fallos.

Código

# Talos node config (simplificado)
cluster:
  controlPlane:
    endpoint: https://10.0.0.1:6443
    certSANs:
      - 10.0.0.1
      - 10.0.0.2
      - 10.0.0.3
machine:
  network:
    interfaces:
      - device: eth0
        addresses:
          - 10.0.0.2/24
        routes:
          - network: 0.0.0.0/0
            gateway: 10.0.0.1
      - device: eth1
        addresses:
          - 192.168.100.2/24
  install:
    image: ghcr.io/siderolabs/installer:latest
    wipe: true
# HelmRelease for Cilium (Helm values)
helm:
  chart: cilium
  repo: https://helm.cilium.io/
  version: 1.14.0
values:
  kubeProxyReplacement: strict
  bgp:
    enabled: true
    announce:
      loadbalancerIPs: true
      podCIDR: true
  ipam:
    mode: kubernetes
# FRR BGP config (aplicado vía ConfigMap)
router bgp 65001
  neighbor 10.0.0.1 remote-as 65000
  neighbor 10.0.0.1 timers 30 90
  network 10.0.0.0/24
  network 192.168.100.0/24

Verificación

  1. Estado de los nodostalosctl get nodes debe listar los tres SBC con Ready y ControlPlane: true.
  2. Ciliumcilium status muestra KubeProxyReplacement: enabled y BGP: active.
  3. Longhorn – En la UI, cada volumen debe tener tres réplicas y estado Healthy.
  4. BGP – En el router UDR, verifica que aparecen tres rutas ECMP para cada IP de LoadBalancer (show ip bgp).
  5. Fluxflux get kustomizations muestra que todos los recursos están sincronizados sin errores.

Notas adicionales

  • Ajuste de MTU: Cuando se usa 2.5 GbE, establece MTU 9000 en ambas NICs y en los pods (cilium-configmtu: 9000). Evita fragmentación y mejora el rendimiento de Cilium.
  • Respaldo de la configuración Talos: Exporta el estado con talosctl backup -n <node> antes de cualquier cambio mayor.
  • Monitoreo: Prometheus + Grafana pueden scrapear métricas de Cilium (cilium_metrics) y Longhorn (longhorn_manager), facilitando la detección temprana de cuellos de botella.
  • Actualizaciones: Con Talos, la actualización del nodo es un talosctl upgrade que reemplaza la imagen sin tocar el disco raíz, manteniendo la inmutabilidad.
  • PoE: Verifica que el switch suministre al menos 25 W por puerto; de lo contrario, el SBC puede reiniciarse bajo carga.

Con esta arquitectura, cualquier SBC con recursos decentes puede convertirse en un nodo Kubernetes de producción, sin los compromisos habituales de los clústers caseros. La combinación de Talos, Cilium BGP y Longhorn brinda inmutabilidad, networking de capa 3 y almacenamiento resiliente, mientras que Flux asegura que todo permanezca bajo control de versiones.