Tengo un problema con las ZimaBoard: cada vez que compro una, acabo comprando dos más. Empecé con una para probar, le puse K3s, y al mes siguiente tenía tres formando un clúster de Kubernetes conectado por Tailscale. Consume menos de 20W en total. Menos que la bombilla del baño.
Este tutorial es el registro completo de cómo lo monté. No me salto los errores ni las cosas que no funcionaron, porque cuando yo buscaba esto nadie contaba la parte fea. Y con ZimaOS, la parte fea es importante.
Si ya tienes el hardware y solo quieres saber si merece la pena, mira primero la review del ZimaBoard 2 donde cuento los meses previos a este clúster. Y si tienes dudas sobre si necesitas Kubernetes o Docker Compose, el post sobre cuándo usar cada uno te ayudará a decidir.
Qué vamos a montar#
Un clúster K3s de 3 nodos (1 control plane + 2 workers), conectado a través de Tailscale. Los nodos pueden estar en ubicaciones diferentes. Vamos a instalar paneles de gestión (Rancher, Portainer, Kubernetes Dashboard) y ver qué pasa con el almacenamiento en ZimaOS.
Números reales de mi setup:
- Consumo total idle: 15-20W (los 3 nodos)
- Coste del hardware: unos 750€
- Recursos: 12 cores, 46GB RAM, unos 34 pods en producción
- Ruido: cero, son fanless
Requisitos previos#
Hardware#
| Nodo | Rol | Specs |
|---|---|---|
| zima3 | Control Plane | ZimaBoard 2, Intel N150, 16GB RAM |
| zima1 | Worker | ZimaBoard 2, Intel N150, 16GB RAM |
| zima2 | Worker | ZimaBoard 2, Intel N150, 16GB RAM |
Software#
ZimaOS instalado en las 3 placas y Tailscale configurado y conectado en los 3 nodos.
IPs de Tailscale#
Cada nodo tiene su IP dentro de la red Tailscale. En mi caso:
| Nodo | IP Tailscale |
|---|---|
| zima3 (CP) | 100.64.1.10 |
| zima1 (Worker) | 100.64.1.20 |
| zima2 (Worker) | 100.64.1.30 |
Sustituye estas IPs por las que te asigne Tailscale a ti.
Antes de empezar: cómo funciona el almacenamiento en ZimaOS#
Esto es lo primero que tienes que entender. ZimaOS no es Debian. Tiene una estructura de almacenamiento rara y si no la tienes en cuenta, vas a perder datos:
| |
K3s guarda sus datos en /var/lib/rancher/, que está en RAM. Si no lo mueves a /DATA, se llena la RAM, los pods entran en “Evicted” por DiskPressure, y al reiniciar se pierde todo.
La solución es mover los datos a /DATA con un symlink. Lo veremos en el paso 2.4.
Paso 1: Preparar los nodos#
1.1 Acceso SSH#
Abre 3 terminales y conéctate a cada nodo:
| |
1.2 Configurar hostnames#
En ZimaOS los hostnames se configuran desde el panel web. Cada nodo tiene que tener su nombre correcto (zima1, zima2, zima3).
1.3 Añadir hosts de Tailscale#
Ejecuta en los 3 nodos (con tus IPs):
| |
Paso 2: Instalar K3s en el Control Plane (zima3)#
2.1 Instalar K3s server#
ZimaOS tiene /usr/local/bin en solo lectura, así que instalamos en /opt/bin:
| |
Qué hace cada flag:
INSTALL_K3S_BIN_DIR=/opt/bindirectorio escribible en ZimaOS--node-ip/--advertise-addressla IP de Tailscale del nodo--flannel-iface=tailscale0la red overlay pasa por Tailscale--disable=traefiklo quitamos para usar otro ingress después--write-kubeconfig-mode=644para no necesitar sudo con kubectl
2.2 Verificar instalación#
| |
Deberías ver algo como:
| |
2.3 Guardar el token#
| |
Copia este token. Lo necesitas para unir los workers.
2.4 Mover datos a /DATA (obligatorio)#
Este paso no es opcional en ZimaOS:
| |
Si después de reiniciar el nodo ves que no arranca, comprueba que el symlink sigue ahí. ZimaOS a veces recrea /var/lib/rancher como directorio vacío al reiniciar.
Paso 3: Unir los Workers (zima1 y zima2)#
Puedes hacer los dos en paralelo.
3.1 Instalar K3s agent en zima1#
| |
3.2 Instalar K3s agent en zima2#
| |
3.3 Mover datos a /DATA en los workers#
Igual que en el control plane. En cada worker:
| |
En workers el servicio se llama k3s-agent, no k3s.
3.4 Verificar el clúster completo#
Desde zima3:
| |
| |
Tres nodos Ready. El clúster funciona sobre Tailscale.
Paso 4: Almacenamiento, lo que funciona y lo que no#
Longhorn: no funciona en ZimaOS#
Intenté instalar Longhorn (almacenamiento distribuido) y no va en ZimaOS. Detecta /var/lib/longhorn como tmpfs y el longhorn-driver-deployer entra en CrashLoopBackOff. No hay forma limpia de arreglarlo.
Si necesitas Longhorn, instala Debian o Ubuntu en las ZimaBoard en vez de ZimaOS. Yo acabé haciendo eso y funciona perfecto.
Lo que sí funciona: local-path#
K3s trae local-path como StorageClass por defecto. Funciona para la mayoría de aplicaciones:
| |
Es almacenamiento local, no distribuido. Para un homelab suele bastar.
Paso 5: Instalar Helm#
Lo necesitas para instalar Rancher, Portainer y cualquier chart:
| |
ZimaOS tiene /root en solo lectura, así que hay que configurar directorios alternativos para Helm:
| |
A partir de aquí, usa siempre sudo -E con Helm para que coja estas variables.
Paso 6: Paneles de gestión#
Probé tres: Rancher, Portainer y el Dashboard oficial de Kubernetes.
Opción A: Rancher (completo pero pesado)#
| |
Accede a https://rancher.100.64.1.10.nip.io (con tu IP).
Si da 404, es el problema del tmpfs otra vez. /var/lib/rancher-data está en RAM:
| |
Si el ingress no funciona, usa port-forward:
| |
Rancher consume unos 2GB de RAM. Ponle replicas=1 o te quedas sin espacio.
Opción B: Portainer (ligero, familiar si vienes de Docker)#
| |
Accede a https://TU_IP:30779
Unos 100MB de RAM. Detecta el clúster solo.
Opción C: Kubernetes Dashboard (minimalista)#
El más ligero, unos 50MB:
| |
Accede a https://TU_IP:30443 con el token.
Cuál elegir#
| Panel | RAM | Para quién |
|---|---|---|
| Rancher | 2GB | Gestión completa de varios clústeres |
| Portainer | 100MB | Si vienes de Docker |
| K8s Dashboard | 50MB | Lo oficial, lo mínimo |
Yo probé los tres y me quedé con Portainer para el día a día. Rancher lo abro cuando necesito algo más complejo.
Lo que NO funcionó: KubeSphere#
Las imágenes de KubeSphere en Docker Hub están obsoletas. kubesphere/ks-installer:v3.2.1 no existe. No pierdas el tiempo.
Troubleshooting#
Pods en “Evicted” o “DiskPressure”#
El problema más común en ZimaOS. /var se llenó:
| |
Si ya moviste datos a /DATA, limpia pods fallidos:
| |
Los nodos no se ven entre sí#
| |
Helm da “permission denied” o “read-only file system”#
Tres cosas:
- Que tengas definidas las variables
HELM_CACHE_HOME,HELM_CONFIG_HOME,HELM_DATA_HOME - Que uses
sudo -E(preserva las variables de entorno) - Que pongas siempre
--kubeconfig /etc/rancher/k3s/k3s.yaml
El resultado#
| |
12 cores, 46GB RAM, 34 pods. Consumo: menos de 20W. Todo por Tailscale, sin puertos abiertos.
Lo más pesado fue pelear con ZimaOS (el tmpfs en /var, el filesystem en solo lectura, los paths de Helm). Una vez resuelto eso, K3s va igual que en cualquier otro Linux. Si vas en serio, plantéate poner Debian directamente en las ZimaBoard. Te ahorras los workarounds de ZimaOS y Longhorn funciona sin problema.
Pero si lo que quieres es aprender Kubernetes con hardware real, bajo consumo y sin ruido, tres ZimaBoard 2 con K3s es un setup difícil de mejorar por el precio.
Dónde comprar#
- ZimaBoard 2 1664 (16GB) en Amazon.es (la versión que uso yo)
- Tienda oficial IceWhale