Cómo instalar k3s en tu homelab
Índice de contenidos
- Puntos clave
- Qué quita k3s de Kubernetes y qué trae ya montado
- Qué hardware necesitas de verdad
- Cómo instalar k3s en un solo nodo
- Qué le hace el instalador a tu sistema
- Cómo añadir un segundo nodo
- Cómo llegar al clúster desde tu portátil
- Qué viene encendido y cuándo apagarlo
- Una primera carga real, con Ingress y volumen
- Almacenamiento en un homelab, sin adornos
- Cómo desinstalar k3s sin dejar restos
- Cuándo Docker Compose sigue siendo la respuesta correcta
- Preguntas frecuentes
- ¿Puedo instalar k3s en una Raspberry Pi?
- ¿Necesito etcd o me vale SQLite?
- ¿Cuánto cuesta k3s en dinero y en cuota de recursos?
- Conclusión
- Fuentes
k3s es una distribución de Kubernetes conforme que cabe en un binario de 68 MiB y se instala con una sola orden. Trae containerd, Flannel, CoreDNS, Traefik, ServiceLB y almacenamiento local ya montados, guarda el estado en SQLite y deja un nodo funcionando en tres segundos.
Llevas dos años con Docker Compose, tienes tres máquinas encendidas en casa y quieres aprender Kubernetes sin alquilar un clúster gestionado. k3s es la vía corta: un binario, una orden y un clúster funcionando. Esta guía lo instala de verdad, añade un segundo nodo, despliega una carga con Ingress y volumen persistente, y termina explicando cuándo deberías quedarte con Compose.
Puntos clave
- k3s quita de Kubernetes los controladores de almacenamiento y el proveedor de nube integrados en el árbol, y a cambio empaqueta containerd, Flannel, CoreDNS, Traefik, ServiceLB y un aprovisionador de volúmenes locales.
- La versión estable el 30 de agosto de 2026 es la v1.36.4+k3s1, publicada tres días antes. El binario arm64 pesa 71.368.866 bytes.
- El mínimo oficial son 2 núcleos y 2 GB para un servidor, pero el perfilado del propio proyecto mide 1.596 MB de RAM con carga real: una Raspberry Pi de 2 GB va justa como servidor y sobrada como agente.
- El estado vive en SQLite mientras solo tengas un servidor. Para alta disponibilidad hacen falta tres servidores con etcd embebido.
- Traefik y ServiceLB vienen encendidos y ocupan los puertos 80 y 443 del anfitrión. Si ya tienes un proxy inverso en casa, apágalos con
--disable.
Qué quita k3s de Kubernetes y qué trae ya montado
k3s no es una bifurcación de Kubernetes ni una versión recortada en funciones. Sus preguntas frecuentes lo dicen sin adornos: "K3s is a CNCF-certified Kubernetes distribution, and can do everything required of a standard Kubernetes cluster. It is just a more lightweight version". El proyecto entró en la CNCF el 19 de agosto de 2020 en nivel Sandbox, se publica bajo licencia Apache-2.0 y acumula 33.850 estrellas y 2.714 bifurcaciones en su repositorio.
Lo que sí quita son dos cosas concretas: los controladores de almacenamiento integrados en el árbol de Kubernetes y el proveedor de nube integrado. El repositorio justifica la decisión porque ambos tienen sustituto fuera del árbol, mediante CSI y CCM, y dependen de servicios de nube que solo están delante si ejecutas k3s dentro de ese proveedor. Si tu clúster vive en un armario, un controlador de discos de AWS no te sirve de nada.
Lo interesante es lo que añade, y ahí está el motivo real por el que la gente elige k3s en casa. Un Kubernetes recién instalado con kubeadm te deja sin red de contenedores, sin DNS interno, sin Ingress, sin balanceador y sin almacenamiento. Con k3s vienen resueltas las cinco piezas: containerd, Flannel, CoreDNS, Traefik, ServiceLB y un aprovisionador de volúmenes en disco local. Ese paquete convierte una tarde de trabajo en tres minutos.
Qué hardware necesitas de verdad
La documentación pide 2 núcleos y 2 GB de RAM para un servidor, y 1 núcleo y 512 MB para un agente. Esa cifra es el suelo teórico. El perfilado de recursos que publica el propio proyecto es mucho más útil, porque mide máquinas con carga encima:
| Papel | Máquina | CPU | RAM |
|---|---|---|---|
| Servidor con carga | Intel 8375C | 6% de un núcleo | 1.596 MB |
| Servidor con carga | Raspberry Pi 4B | 30% de un núcleo | 1.588 MB |
| Solo agente | Intel 8375C | 3% de un núcleo | 275 MB |
| Solo agente | Raspberry Pi 4B | 10% de un núcleo | 268 MB |
La lectura práctica: una Pi de 2 GB aguanta como agente con muchísimo margen, y como servidor se queda sin aire en cuanto le pongas cuatro aplicaciones. Si vas a montar el plano de control en una Pi, que sea de 4 GB u 8 GB.
El disco importa más de lo que parece, porque la base de datos del clúster escribe constantemente. El proyecto pide 10 IOPS y 500 KiB/s con latencia por debajo de 10 ms para SQLite, y sube a 50 IOPS y menos de 5 ms para etcd embebido. Su recomendación es directa: "it is recommended that you use an external SSD. etcd is write intensive; SD cards and eMMC cannot handle the IO load". Una tarjeta microSD funciona hasta que un día deja de funcionar, y suele hacerlo un domingo.
En cuanto a red, el agente necesita alcanzar el puerto 6443/TCP del servidor. Todos los nodos hablan entre sí por 8472/UDP para el túnel de Flannel y por 10250/TCP para las métricas del kubelet. La documentación avisa de un riesgo que se olvida con facilidad: "The VXLAN port on nodes should not be exposed to the world as it opens up your cluster network to be accessed by anyone".
Cómo instalar k3s en un solo nodo
El proceso completo, en el orden en que lo hice:
- Descarga el instalador y léelo antes de ejecutarlo:
curl -sfL https://get.k3s.io -o k3s-install.sh. Son 1.218 líneas de shell contra un dominio de terceros, y merece la pena mirarlas. - Ejecuta el guion con
sh k3s-install.sh. Sin variables de entorno instala el canal estable como servidor. - Comprueba que la unidad arrancó con
systemctl status k3s. - Exporta el fichero de configuración con
export KUBECONFIG=/etc/rancher/k3s/k3s.yamly pide los nodos conkubectl get nodes.
Esa es toda la instalación. La salida real del instalador en la máquina de pruebas, un Debian 13 sobre arm64, fue esta:
[INFO] Finding release for channel stable
[INFO] Using v1.36.4+k3s1 as release
[INFO] Downloading binary https://github.com/k3s-io/k3s/releases/download/v1.36.4%2Bk3s1/k3s-arm64
[INFO] Verifying binary download
[INFO] Installing k3s to /usr/local/bin/k3s
[INFO] Creating /usr/local/bin/kubectl symlink to k3s
[INFO] Creating killall script /usr/local/bin/k3s-killall.sh
[INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO] systemd: Creating service file /etc/systemd/system/k3s.service
[INFO] systemd: Starting k3s
Un detalle que sorprende la primera vez: kubectl, crictl y ctr no son programas aparte. Son enlaces simbólicos al mismo binario de k3s, que cambia de comportamiento según el nombre con el que lo invocas.
Qué le hace el instalador a tu sistema

El guion escribe cinco cosas y ninguna está escondida. Deja el binario en /usr/local/bin/k3s, los tres enlaces simbólicos y los guiones k3s-killall.sh y k3s-uninstall.sh al lado. Añade la unidad /etc/systemd/system/k3s.service con su fichero de entorno y la activación para que arranque sola. Todo el estado del clúster va a parar a /var/lib/rancher/k3s.
El arranque es más rápido de lo que cabría esperar de Kubernetes. En el registro de systemd de mi prueba la unidad empieza a las 11:02:24 y a las 11:02:27 el servidor ya declara Kube API server is now running. Tres segundos hasta la API. Los siete pods del sistema tardaron unos cuarenta segundos más, que es lo que cuesta arrancar las imágenes.
Conviene medir lo que ocupa. El directorio /var/lib/rancher/k3s pesaba 994 MB tras la instalación, de los cuales solo 16 MB son la base de datos: el resto son las imágenes de los componentes empaquetados. Y en reposo, con un solo nodo y sin cargas propias, el cgroup de la unidad k3s.service marcaba 528.551.936 bytes, unos 504 MiB. No es Docker Compose, y quien te diga que k3s no consume nada no lo ha medido.
Las versiones que trae la v1.36.4+k3s1, leídas de los pods en marcha, son containerd 2.3.4, CoreDNS 1.14.6, Traefik 3.7.8, local-path-provisioner v0.0.37, metrics-server v0.9.0 y klipper-lb v0.4.17. Si te interesa la pieza de abajo, tenemos un artículo sobre containerd, el motor de contenedores que sostiene Kubernetes.
Cómo añadir un segundo nodo
Aquí aparece la única distinción de vocabulario que hay que tener clara. Un servidor ejecuta k3s server e incluye el plano de control y la base de datos. Un agente ejecuta k3s agent y solo aporta kubelet, motor de contenedores y red. Lo normal en casa es un servidor y tantos agentes como máquinas te sobren.
El agente se da de alta con dos variables: la dirección del servidor y el testigo de unión, que el servidor genera solo y guarda en /var/lib/rancher/k3s/server/node-token.
sudo cat /var/lib/rancher/k3s/server/node-token
Con ese valor en la mano, la máquina nueva se une con una sola orden:
curl -sfL https://get.k3s.io |
K3S_URL=https://192.168.1.10:6443
K3S_TOKEN=K10a1d125286...
sh -
El instalador detecta que le has pasado K3S_URL y cambia de modo: crea k3s-agent.service en lugar de k3s.service, y deja k3s-agent-uninstall.sh en lugar del guion del servidor. En mi prueba el nodo nuevo apareció como Ready ocho segundos después de arrancar el servicio, y el DaemonSet de ServiceLB levantó al momento un pod svclb-traefik en él sin que yo tocara nada.
Un aviso que la documentación repite y que cuesta un rato de depuración cuando lo ignoras: "Each machine must have a unique hostname". Si clonaste la imagen de la Pi tres veces, tienes tres máquinas llamadas raspberrypi y el clúster se va a confundir. O cambias el nombre del anfitrión, o pasas K3S_NODE_NAME.
Cómo llegar al clúster desde tu portátil
El fichero de configuración vive en /etc/rancher/k3s/k3s.yaml con permisos 0600 y propietario root, así que sin sudo no lo lees. Dentro tiene una línea que hay que cambiar sí o sí:
clusters:
- cluster:
server: https://127.0.0.1:6443
Esa dirección de bucle local funciona en el servidor y en ningún otro sitio. Copia el fichero a ~/.kube/config, sustituye 127.0.0.1 por la dirección real del servidor y ya tienes kubectl apuntando a casa.
Hay una trampa con las copias que conviene conocer antes de que te muerda: "K3s will automatically update the certificates within the admin kubeconfig every time it starts. If you make a copy of this file, you will need to manually update those copies to ensure that the inline certificates do not expire". Traducido: el fichero del servidor se refresca solo, tu copia no. Un día el portátil deja de conectar y no es la red.
Si prefieres que el fichero sea legible por tu usuario en el propio servidor, el servidor admite --write-kubeconfig-mode 0644. Es cómodo y es peor: ese fichero da acceso de administrador al clúster entero.
Qué viene encendido y cuándo apagarlo
Al arrancar, un servidor de k3s despliega cuatro componentes con manifiesto propio, coredns, traefik, local-storage y metrics-server, más el controlador servicelb, que va embebido. Los manifiestos aterrizan en /var/lib/rancher/k3s/server/manifests y el servidor los reescribe en cada arranque, así que editarlos a mano no sirve de nada: la personalización de Traefik va en un recurso HelmChartConfig aparte.
Para quitar cualquiera de ellos se usa --disable, cuyos valores válidos son exactamente coredns, servicelb, traefik, local-storage, metrics-server y runtimes.
| Componente | Qué hace | Cuándo apagarlo |
|---|---|---|
| Traefik | Controlador de Ingress con Service de tipo LoadBalancer en 80 y 443 | Ya tienes Nginx Proxy Manager o Traefik en Docker ocupando esos puertos |
| ServiceLB | Un DaemonSet que publica el puerto del Service en cada nodo | Tienes MetalLB, o no quieres que cada nodo escuche en el 80 |
| local-storage | Aprovisiona volúmenes en el disco del nodo | Vas a usar Longhorn o NFS desde el principio |
| metrics-server | Alimenta kubectl top y el autoescalado |
Casi nunca; ocupa poco y hace falta |
| CoreDNS | DNS interno del clúster | Casi nunca; sin él los servicios no se resuelven por nombre |
La decisión que más gente se salta es la primera. Si en tu red ya hay algo escuchando en el 80 y el 443, instalar k3s con Traefik encendido te deja dos cosas peleándose por el mismo puerto. El clúster parece roto sin estarlo.
Una corrección sobre la documentación: la portada de docs.k3s.io lista Spegel, el espejo de registro distribuido, entre las dependencias incluidas. Va incluido en el binario, sí, pero está apagado. La ayuda de k3s server es clara: --embedded-registry ... (default: false).
Una primera carga real, con Ingress y volumen
Un clúster vacío no demuestra nada. Esto es lo mínimo que ejercita las tres piezas que k3s te regala: la clase de almacenamiento, el Service y el Ingress.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: web-datos
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: local-path
resources:
requests:
storage: 1Gi
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
rules:
- host: web.casa.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port: {number: 80}
Con el Deployment de nginx y su Service aplicados, la comprobación es una petición contra la dirección del nodo con la cabecera correcta:
$ curl -H "Host: web.casa.local" http://192.168.1.10/
Hola desde k3s
$ curl -o /dev/null -w "%{http_code}n" http://192.168.1.10/
404
Ese 404 de la segunda llamada es Traefik haciendo su trabajo: sin una regla que encaje con la cabecera Host no hay nada que servir. No es un fallo de la instalación, aunque asuste la primera vez.
Lo que ocurrió por dentro merece un vistazo. El volumen se creó en /var/lib/rancher/k3s/storage/pvc-8b99304a-..._default_web-datos, un directorio normal en el disco del nodo con index.html dentro, y el PersistentVolume salió con una afinidad de nodo fijada a la máquina donde se programó el pod.
Almacenamiento en un homelab, sin adornos
Esa afinidad de nodo es la frase importante de todo el artículo. La documentación la escribe así: el aprovisionador local "does result in permanently binding the pod to the node hosting the volume". El pod ya no puede ir a ninguna otra máquina, porque sus datos están en el disco de esa.
Con lo que eso significa hay que ser honesto. Si el nodo que guarda el volumen se apaga, el pod no se reprograma en otro sitio: se queda en Pending esperando a que vuelva. Has montado un clúster de tres máquinas y tu aplicación sigue dependiendo de una sola. La clase de almacenamiento por defecto es local-path, con política Delete y modo WaitForFirstConsumer, que es justo lo que retrasa la creación del volumen hasta saber en qué nodo va a vivir el pod.
En un homelab de un solo nodo esto está bien y no hay que arreglarlo. Un servidor de fotos o un panel de métricas toleran estar clavados a una máquina, y tu copia de seguridad ya se lleva ese directorio.
Deja de estar bien el día que quieres que algo sobreviva a la caída de un nodo. La respuesta entonces es Longhorn, que replica los volúmenes a costa de más memoria, más disco y más piezas que entender. La única restricción documentada es que "Longhorn does not support ARM32", así que con Pi de 64 bits no hay problema.
Cómo desinstalar k3s sin dejar restos
Esto es de las cosas que k3s hace mejor que casi cualquier alternativa: la desinstalación es un guion que ya está en tu disco.
sudo /usr/local/bin/k3s-uninstall.sh ## en un servidor
sudo /usr/local/bin/k3s-agent-uninstall.sh ## en un agente
Leyendo el guion se ve qué se lleva por delante. Llama a k3s-killall.sh para parar los contenedores, desactiva la unidad de systemd, borra el fichero de servicio y su entorno y quita los enlaces simbólicos. Después desmonta y elimina /var/lib/rancher/k3s, /etc/rancher/k3s, /run/k3s, /run/flannel y /var/lib/kubelet, y finalmente se borra a sí mismo. En sistemas con SELinux también quita el paquete k3s-selinux.
El aviso de la documentación es de una línea y va en serio: "Uninstalling K3s may cause data loss!". Ahí dentro están tus volúmenes local-path. Cópialos antes.
Cuándo Docker Compose sigue siendo la respuesta correcta
Después de todo lo anterior, la parte incómoda. En un homelab de una sola máquina, y probablemente el tuyo lo sea, Docker Compose es mejor herramienta que k3s, y decirlo cuesta poco.
Si tienes una sola máquina con quince contenedores, k3s te añade 504 MiB de residente en reposo. Añade también un plano de control que mantener, certificados que caducan, una base de datos que respaldar y una capa de conceptos entre tú y docker logs. A cambio no te da nada que no tuvieras: con una máquina, la reprogramación automática de pods no existe. Y si lo que buscabas era ver todos tus contenedores desde una consola, eso lo resuelve Portainer con Docker Compose en cinco minutos y sin cambiar de modelo mental.
k3s empieza a compensar cuando se cumple alguna de estas condiciones: tienes más de una máquina y quieres que las cargas se muevan solas entre ellas; quieres declarar el estado deseado en YAML versionado y que algo lo reconcilie; necesitas practicar Kubernetes en serio porque en el trabajo lo vas a tocar; o quieres las piezas que solo existen en este ecosistema, como los operadores. Si tu motivo es el tercero, k3s es la mejor inversión de una tarde que hay, y lo que aprendas se traslada tal cual a un clúster de verdad. Los cambios de cada versión los repasamos en artículos como el balance de Kubernetes 1.35 GA y el resumen de la 1.34.
Lo que no deberías hacer es montar k3s porque Compose te parezca poco serio. Compose es serio. Es que resuelve otro problema.
Preguntas frecuentes
¿Puedo instalar k3s en una Raspberry Pi?
Sí, y es uno de los casos que el proyecto persigue explícitamente: hay binarios e imágenes multiarquitectura para arm64 y ARMv7. Como agente, una Pi de 2 GB va sobrada, con 268 MB medidos. Como servidor, apunta a 4 GB y arranca desde SSD por USB: la documentación avisa de que las tarjetas microSD y el eMMC no aguantan la escritura del datastore.
¿Necesito etcd o me vale SQLite?
Con un solo servidor, SQLite es el valor por defecto y funciona perfectamente. La documentación es tajante en el límite: "SQLite cannot be used on clusters with multiple servers". Para alta disponibilidad necesitas tres servidores con etcd embebido, o dos servidores contra una base de datos externa como PostgreSQL o MySQL.
¿Cuánto cuesta k3s en dinero y en cuota de recursos?
Cero en dinero: es Apache-2.0 y no hay edición de pago. En recursos, ocupa medio giga de memoria residente para el plano de control en reposo. En disco, cerca de un giga solo para el directorio de datos recién instalado, más lo que ocupen tus imágenes. Si estás midiendo el coste de un clúster con más ambición, Kubecost y OpenCost hacen ese trabajo.
Conclusión
Instalar k3s es una orden y tres segundos; entender qué te acaba de instalar lleva algo más. Lo que compras es un Kubernetes conforme, con la red, el DNS, el Ingress, el balanceador y el almacenamiento ya resueltos. Todo eso cabe en un binario de 68 MiB, con una desinstalación que de verdad limpia. Lo que pagas es medio giga de memoria en reposo, un volumen que ata cada pod a su nodo y un modelo mental nuevo.
Si tienes una máquina, quédate con Compose. Si tienes tres y ganas de aprender, esta tarde tienes clúster. La versión en inglés de esta guía está en How to install k3s in your homelab.
Fuentes
- k3s, arranque rápido
- k3s, requisitos de hardware y red
- k3s, perfilado de recursos
- k3s, servicios de red y Traefik
- k3s, almacenamiento y local-path
- k3s, componentes empaquetados
- k3s, desinstalación
- k3s, acceso al clúster
- k3s, preguntas frecuentes
- k3s-io/k3s, repositorio del proyecto
- CNCF, ficha del proyecto k3s
- k3s, canales de publicación
Código fuente
Accede a todo el código fuente de este artículo en GitHub.
Ver en GitHub