Cómo configurar k3s para homelab: Kubernetes ligero en 2026
TL;DR — Lo que vas a tener al final
- Tiempo de setup: Cluster mínimo en 2 horas, producción en 1 día.
- Requisitos: CPU con VT-x, 8+ GB RAM, 3+ nodos para HA.
- Resultado: Kubernetes con HA, escalado automático, service discovery.
- Troubleshooting: kubectl logs, kubectl describe, dashboards Grafana oficiales.
¿Qué es k3s y por qué conviene en un homelab?
k3s es una distribución de Kubernetes certificada por la CNCF, empaquetada por Rancher Labs (ahora SUSE). Reduce el peso del binario a menos de 100 MB, fusiona el control plane y elimina dependencias como etcd por SQLite embebido (sustituible por etcd si quieres HA). El resultado es un cluster funcional que arranca en menos de un minuto, incluso en una Raspberry Pi 4 con 1 GB de RAM.
En un homelab típico no necesitas los 12+ servicios del upstream Kubernetes; necesitas un cluster que puedas levantar rápido, que consuma poca RAM, que tenga preinstalado lo que más usas (Helm, Traefik, local-path storage) y que se recupere solo cuando un nodo se cae. k3s cumple todo eso. Y si mañana decides migrar a K8s upstream en un proveedor cloud, los mismos manifests funcionan, porque k3s es 100% compatible con la API de Kubernetes.
Un cluster mínimo viable en homelab luce así: un servidor como control plane (puede ser tu NAS, un mini-PC viejo, o una Pi 5 con 4 GB), y dos o tres nodos workers adicionales donde realmente corres las cargas. Para experimentación basta con un solo nodo, donde k3s corre el control plane y los pods en la misma máquina.
Requisitos de hardware y consideraciones previas
Antes de instalar, conviene dimensionar correctamente. k3s es frugal, pero hay mínimos.
Para un cluster de un solo nodo (modo agent-less, perfecto para aprender o para servicios que no requieren alta disponibilidad):
- 1 CPU virtual (k3s soporta ARM y x86_64)
- 1 GB de RAM (recomendado 2 GB si corres workloads reales)
- 4 GB de disco libre
Para un cluster multi-nodo en HA (3 servers como control plane + N workers):
- 2 CPUs virtuales en cada nodo
- 4 GB de RAM en cada nodo de control plane
- 2 GB de RAM en cada worker
- Red Gigabit entre nodos (latencia < 5 ms)
El sistema operativo soportado es cualquier Linux moderno: Debian 11+, Ubuntu 20.04+, RHEL 8+, Fedora 36+, openSUSE Leap 15.4+. Raspberry Pi OS y Ubuntu Server para ARM funcionan sin trucos adicionales. Eso importa porque k3s publica binarios ARM64 además de AMD64, y los nodos de control plane no requieren binarios distintos.
Sobre la red: k3s usa por defecto la red de pods 10.42.0.0/16 y la red de servicios 10.43.0.0/16. Verifica que esas subredes no choquen con tu LAN (192.168.5.0/24 por ejemplo). Si chocan, las defines al instalar con --cluster-cidr y --service-cidr. Más adelante veremos esos flags.
Instalación del primer nodo (servidor)
El instalador oficial es un script que ejecuta como root. Descarga el binario k3s, lo instala en /usr/local/bin, registra un systemd unit y arranca el servicio. Antes de correrlo, abre una terminal al server y comprueba que tienes curl y acceso a internet.
curl -sfL https://get.k3s.io | sh -
Este comando hace tres cosas: baja la última versión estable, la instala como /usr/local/bin/k3s, y crea el unit /etc/systemd/system/k3s.service. Al finalizar el script, verifica que el servicio está activo:
systemctl status k3s --no-pager
active (running) es lo que quieres ver. Si el status dice failed, casi siempre es por falta de memoria o porque el kernel no soporta cgroups v2. En kernels antiguos (Debian 10, Ubuntu 18.04) necesitas agregar GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1" y reiniciar.
El siguiente paso es verificar que kubectl puede hablar con el cluster. El instalador guarda automáticamente el kubeconfig en /etc/rancher/k3s/k3s.yaml, pero ese archivo solo es legible por root. Para usarlo desde tu usuario normal, cópialo y ajusta permisos:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
chmod 600 ~/.kube/config
Ahora sí, comprueba que el nodo aparece como Ready:
kubectl get nodes -o wide
Listará un nodo con rol control-plane,master y estado Ready. Si ves NotReady, espera 30 segundos y vuelve a consultar. El primer arranque puede tardar más si tiene que descargar imágenes.
Para diagnosticar el problema, journalctl -u k3s -f muestra los logs en vivo. Si ves errores de cgroup o de bridge, el patrón típico es que ya había un CNI anterior instalado; limpia con sudo rm -rf /etc/cni/net.d y reinicia k3s.service.
Unir workers al cluster
Cuando el servidor funciona, necesitas el token de cluster y la dirección del servidor. El token vive en /var/lib/rancher/k3s/server/node-token en el nodo master. Sin ese archivo, ningún worker puede autenticarse.
sudo cat /var/lib/rancher/k3s/server/node-token
Copia el token (es una cadena larga aleatoria). En cada worker, ejecuta el instalador apuntando al master:
curl -sfL https://get.k3s.io | K3S_URL=https://<IP_MASTER>:6443 K3S_TOKEN=<TOKEN> sh -
Reemplaza por la IP LAN del nodo control plane (no uses localhost, los workers siempre son externos al master). Si tu LAN usa DNS, puedes usar el hostname en lugar de la IP.
Notas importantes:
- El firewall del master debe tener abierto el puerto 6443 TCP (API) y los puertos 10250 (kubelet), 8472 (flannel VXLAN si usas el default CNI). Si corres firewalld o ufw, los workers no podrán unirse hasta que abras esos puertos.
- Si el worker no aparece en
kubectl get nodesdespués de un minuto, ejecutajournalctl -u k3s-agent -fen el worker. Los errores más comunes: token incorrecto, IP inalcanzable, y firewall corporativo. - Los workers heredan la misma versión del agente que el servidor. Si actualizas el servidor, los workers deben actualizarse también; k3s soporta auto-upgrade con
--node-labelosystem-upgrade-controller(lo cubrimos más adelante).
Recursos esenciales preinstalados
A diferencia del K8s upstream, k3s trae servicios ya configurados para que tengas un cluster funcional sin pasos extra. Conoce qué hay antes de empezar a deployar para no duplicar.
| Servicio | Qué hace | Notas |
|---|---|---|
| Traefik | Ingress controller | Default en puerto 80/443, helm release preconfigurado |
| local-path | StorageClass por defecto | Crea PersistentVolumes en /var/lib/rancher/k3s/storage |
| ServiceLB | LoadBalancer | Implementa MetalLB-lite vía annotations |
| Helm | Package manager | Binario helm ya disponible |
Para verificar que Traefik está corriendo:
kubectl -n kube-system get pods -l app.kubernetes.io/name=traefik
El pod debe mostrar Running y 1/1 en Ready. El Helm release vive en kube-system con nombre traefik. Si quieres desinstalarlo y poner otro Ingress (Nginx o Caddy), primero borra el Helm release: helm uninstall traefik -n kube-system.
Sobre el storage: cuando creas un PVC sin especificar StorageClass, k3s usa local-path. Esto es perfecto para homelab: los datos quedan en el host, no en un NFS remoto. Pero si tu nodo muere, los datos mueren. Para homelab con discos locales eso está bien; para producción real, monta un NFS o Longhorn.
Deployar tu primer workload
El hello world de Kubernetes es un deployment de nginx. No necesitas escribir YAML desde cero; usa el comando imperativo:
kubectl create deployment nginx --image=nginx:alpine
kubectl expose deployment nginx --port=80 --type=ClusterIP
Verifica que el pod está corriendo:
kubectl get pods -l app=nginx
STATUS debe decir Running. Si dice Pending, normalmente es por falta de recursos o porque la imagen no se descargó. Revisa con kubectl describe pod en la sección Events.
Para exponer el deployment fuera del cluster, crea un Ingress que apunte al Service:
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: nginx.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
EOF
Para que nginx.local resuelva, agrégalo a /etc/hosts apuntando a la IP del master: 192.168.5.10 nginx.local. Y abre el navegador en http://nginx.local. Si Traefik responde OK, verás la página por defecto de nginx.
Troubleshooting usual: si el navegador no carga, primero verifica que el Ingress tiene IP: kubectl get ingress. Luego que el Service tiene endpoints: kubectl get endpoints nginx. Si el Service no tiene endpoints, el selector del Service no coincide con las labels del Deployment (revisa con kubectl get pods --show-labels).
Storage persistente en homelab
El homelab necesita persistencia, aunque sea modesta. Hay tres rutas comunes en k3s según tu hardware.
Ruta 1: local-path (default). k3s ya viene con local-path configurado. Cuando pides un PVC sin StorageClass, lo aprovisiona automáticamente. Los datos viven en /var/lib/rancher/k3s/storage/ en el nodo donde corre el pod. Es simple, rápido, y suficiente para bases de datos pequeñas o Nextcloud casero.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: datos-app
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Si borras el PVC, los datos se borran con él. Eso es la regla, no la excepción.
Ruta 2: NFS para compartir entre nodos. Si tienes TrueNAS o un Synology, monta un NFS export y crea manualmente un PersistentVolume que apunte a la export. La definición es larga; la forma más limpia es usar la Helm chart nfs-subdir-external-provisioner. Primero instala Helm si no lo tienes:
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner
--set nfs.server=192.168.5.10
--set nfs.path=/volume1/k8s-storage
--namespace nfs-provisioner --create-namespace
Luege marca ese provisioner como default StorageClass, o crea PVCs con storageClassName: nfs-client.
Ruta 3: Longhorn para HA real. Longhorn es un sistema de bloques distribuidos de Rancher. Replica los volúmenes entre nodos y maneja snapshots. Es ideal para bases de datos serias (Postgres, MariaDB) porque si un nodo cae, los pods se reasignan sin perder datos. Pero consume RAM extra (1 GB por nodo) y no es para hardware viejo.
Para instalarlo:
helm repo add longhorn https://charts.longhorn.io
helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace
Accede al dashboard en http:// después de unos minutos. La primera vez toma más porque descarga los binarios de Longhorn Manager.
Alta disponibilidad: 3 servidores como control plane
El modo más interesante de k3s es HA real, donde tres nodos actúan como control plane y se votan entre sí para garantizar consenso. La instalación es casi idéntica, pero con un paso previo: registrar un datastore externo.
Tienes dos opciones. La recomendada es usar una base de datos SQL externa (MySQL o PostgreSQL) accesible por los tres nodos. La más simple es un cluster de etcd embebido que k3s levanta solo.
Para etcd embebido, el primer nodo se inicia así:
curl -sfL https://get.k3s.io | sh -s - server --cluster-init
--cluster-init genera un token de cluster y arranca etcd. Los otros dos nodos de control plane se unen con esa misma URL:
curl -sfL https://get.k3s.io | K3S_URL=https://<IP_NODO1>:6443 K3S_TOKEN=<TOKEN> sh -s - server
Después de unir los tres, kubectl get nodes mostrará los tres servidores con rol control-plane,etcd. Si uno cae, los otros dos mantienen quorum (>50%) y el cluster sigue funcionando.
Errores típicos al montar HA:
- No usar IP única por nodo cuando hay varias NICs. Pasa
--node-ippara forzar la IP correcta. - El cluster-init genera un nuevo token, pero los nodos posteriores necesitan también el token original capturado. Si lo pierdes, no hay forma de recuperarlo; debes reiniciar el primer nodo.
- Time skew entre nodos. etcd rechaza leader election y writes si los relojes difieren más de 1 segundo (default MaxTimeDrift). Instala chrony en los tres y verifica con
chronyc trackingque el offset es menor a 10 ms.
Actualizaciones en producción
Actualizar k3s en un homelab es trivial porque la API es 100% compatible y los rollbacks son fáciles. Una sola línea:
sudo k3s upgrade
Esto descarga la última versión estable y reinicia el servicio. El pod se queda en estado NotReady durante el upgrade, pero los pods que corren en él se reasignan a otros nodos si hay disponibilidad. Si tu cluster es de un solo nodo, hay downtime de 30 a 60 segundos.
Para evitar ese downtime en clusters multi-nodo, actualiza primero los workers, uno por uno, y el servidor al final. Los workers usan el agente, no el servidor:
sudo k3s-agent upgrade
Si quieres más control, instala system-upgrade-controller (proyecto de Rancher) y declara plans. Eso automatiza batches de nodos, espera a que los pods drenen, y aplica health checks antes de continuar.
Sobre versiones: k3s sigue el calendario de Kubernetes upstream con un retraso de 4 a 6 semanas. Las releases estables se numeran como v1.30.x+k3s1. Evita saltar más de dos minor versions a la vez; el proceso de upgrade puede fallar en saltos grandes.
Seguridad mínima para homelab
k3s es seguro por defecto, pero hay decisiones que debes tomar antes de exponer el cluster a internet.
Cierra el puerto 6443. Por defecto k3s abre 6443 en todas las interfaces. Si tu NAS o control plane está en una LAN con IP pública (o detrás de un NAT con reenvío), eso es un riesgo. Cambia el bind a la interfaz LAN:
sudo nano /etc/systemd/system/k3s.service
Agrega --bind-address= a la línea ExecStart. Después:
sudo systemctl daemon-reload
sudo systemctl restart k3s
El cluster sigue funcionando desde la LAN, pero ya no es accesible desde internet.
Firewall de nodos entre sí. Los workers deben hablar con el control plane. En cada worker, abre solo esos puertos específicos:
sudo ufw allow from 192.168.5.0/24 to any port 6443 proto tcp
sudo ufw allow from 192.168.5.0/24 to any port 10250 proto tcp
sudo ufw allow from 192.168.5.0/24 to any port 8472 proto udp
Adicionalmente, los workers no necesitan acceso a internet. Si puedes aislarlos (VLAN de servidores, por ejemplo), házlo.
Secrets encriptados. El Secret de Kubernetes en su forma nativa es solo base64. Para cifrarlos en reposo, edita /etc/rancher/k3s/config.yaml y agrega:
secrets-encryption: true
Después aplica la flag y reinicia. Los Secrets existentes se migrarán automáticamente.
RBAC y usuarios. El kubeconfig por defecto lleva un certificado de admin con permisos totales. Para uso compartido, crea ServiceAccounts por aplicación y limita los permisos con Roles. Para uso personal, deja el admin pero cambia la contraseña del cluster y rota los tokens periódicamente.
Comandos útiles del día a día
Terminamos con un cheat sheet de comandos que vas a usar más de lo que crees, todos probados contra un cluster k3s funcional.
# Ver el estado del cluster y nodos
kubectl cluster-info
kubectl get nodes -o wide
# Logs en vivo de un pod específico
kubectl logs -f <pod-name> -n <namespace>
# Entrar a un pod interactivo
kubectl exec -it <pod-name> -- /bin/sh
# Recurso por namespace
kubectl get all -n <namespace>
# Top de uso por pod (requiere metrics-server)
kubectl top pods -A
# Reiniciar un deployment de forma limpia
kubectl rollout restart deployment/<name>
# Ver el contenido de un ConfigMap o Secret
kubectl get configmap <name> -o yaml
kubectl get secret <name> -o yaml
# Diagnosticar un pod que no arranca
kubectl describe pod <pod-name>
kubectl get events --sort-by='.lastTimestamp' -A
# Aplicar un manifiesto desde un archivo
kubectl apply -f manifest.yaml
# Listar Helm releases instaladas
helm list -A
# Ver el contexto actual
kubectl config current-context
Ahí tienes con qué sobrevivir el día a día. Conforme el cluster crezca, vas a añadir kubectx y kubens para saltar entre contextos y namespaces sin escribir el nombre completo cada vez.
¿Y ahora qué?
Con k3s instalado en tu homelab tienes la base para correr cualquier workload contenerizado. Lo natural después de esto es explorar el catálogo de Helm charts e instalar los servicios que más uses: Plex, Nextcloud, Paperless, Gitea, incluso un Minecraft server. k3s los corre igual que lo haría un cluster cloud de pago, pero sin la factura.
Para profundizar en Kubernetes en general, la lectura oficial recomendada es la documentación de Kubernetes, que aplica al 100% a k3s salvo en los componentes propios que k3s ya trae incorporados. Si vas a usar k3s en producción real con alta disponibilidad, lee la documentación de arquitectura HA de k3s — cubre los modos de embedded etcd, datastore externo y failover.
Si prefieres acompañar la lectura con un cluster real en la nube, los labs interactivos de Killercoda son la mejor forma de practicar antes de tocar tu cluster.
Preguntas frecuentes
¿Por qué Cómo configurar k3s para homelab: Kubernetes ligero en 2026 es relevante para sysadmins Linux?
Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.
¿Qué necesito para empezar con Cómo configurar k3s para homelab:?
Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.
¿Cuáles son los errores más comunes con Cómo configurar k3s para homelab:?
Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.
¿Cuándo usar Cómo configurar k3s para homelab: y cuándo una alternativa?
Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.
¿Cómo migro desde una configuración previa a Cómo configurar k3s para homelab:?
Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.
Lee también
- Guía Fedora 44: Novedades, Instalación y Upgrade para Sysadmins Linux
- Configura VLANs en Linux con nmcli: Guía paso a paso para sysadmins
- Protege tu SSH: Guía esencial para configurar Fail2ban en Linux
- Guía Definitiva: Configura Kubernetes con kubeadm en Ubuntu para Sysadmins Linux
- Configura Prometheus y Grafana: Guía DevOps para SysAdmins Linux

Pingback: Drone CI vs Woodpecker CI: el fork open source que migra usuarios - Soy Linux