2 puntos por GN⁺ 2025-05-06 | 1 comentarios | Compartir por WhatsApp
  • En servidores personales y VPS pequeños, la automatización declarativa de Kubernetes resulta atractiva, pero la carga de CPU y memoria y la complejidad operativa pueden superar los beneficios reales
  • Kubernetes automatiza tareas como la coordinación de Pods y la renovación de certificados TLS manteniendo continuamente el estado deseado, pero para eso conserva en ejecución permanente un runtime bastante grande
  • En experimentos con Azure Kubernetes Service, Microk8s, K3S y Raspberry Pi, el uso de recursos en reposo, el calor y el ruido de los ventiladores fueron problemas recurrentes
  • Podman puede convertir contenedores en servicios systemd y detectar y reemplazar imágenes nuevas con io.containers.autoupdate y podman auto-update
  • La combinación de Podman, systemd y user lingering ofrece de forma más simple la mayor parte de la automatización que se buscaba en Kubernetes, aunque la integración con systemd se está moviendo hacia Quadlet

Por qué la automatización de Kubernetes era pesada para un servidor personal

  • Kubernetes está compuesto por varios componentes, servicios web, sidecars y webhooks, pero su funcionamiento central se parece a un bucle que compara continuamente el estado actual con el estado deseado y aplica las diferencias
    • Si debería existir un Pod y no existe, lo crea
    • Si debería haber 3 replicas pero hay 4, elimina una
  • Este modelo fue especialmente útil en extensiones como cert-manager
    • Se declara que debe existir un certificado TLS válido para un dominio específico
    • Si se indica cómo solicitar el certificado, cuando no existe o está cerca de vencer, obtiene uno nuevo y lo instala en el servidor web
  • Para experimentos personales era divertido y tenía valor de aprendizaje, pero para operación real se acercaba a ser una herramienta excesiva
  • La carga de recursos se repitió en varios entornos
    • En una NUC, la computadora seguía funcionando, se calentaba y generaba ruido de ventilador, lo que dificultaba dormir
    • En Azure Kubernetes Service, la implementación de Kubernetes ocupaba mucha RAM y usaba alrededor de 7–10% de CPU en reposo en el worker node
    • Una instancia única de Microk8s en un VPS x86_64 de 2 vCPU tenía una CPU en reposo de alrededor de 12%
    • K3S en una máquina Ampere A1 de 2 vCPU es conocido como una implementación más ligera, pero usaba cerca de 6% de CPU constante
    • Tampoco en Raspberry Pi se encontró una implementación que dejara suficiente CPU para la carga de trabajo sin problemas de calor o ventilador

La automatización reemplazada con Podman y systemd

  • La razón principal para seguir usando Kubernetes era la automatización de despliegues
    • Con GitOps y Flux, los cambios eran fáciles
    • Con automatización de imágenes de contenedor y webhooks de Flux v2, al publicar una imagen nueva el servidor la recibía en segundos y ejecutaba la aplicación en producción
  • Las alternativas existentes fuera de Kubernetes no resultaban satisfactorias
    • El enfoque de recordar todos los argumentos originales de la línea de comandos para recrear el contenedor implicaba mucha carga de administración
    • Tampoco se preferían herramientas que exigieran control total sobre docker.sock
  • Podman auto-updating se acercaba a la funcionalidad necesaria
    • Podman puede verse como una alternativa al CLI de Docker
    • Después de crear un contenedor, puede generar un archivo de servicio systemd
    • Al iniciar el servicio, crea o reemplaza el contenedor; al detenerlo, elimina el contenedor
  • Las actualizaciones automáticas funcionan con la etiqueta io.containers.autoupdate
    • Se ejecutan una vez al día con un timer o ejecutando directamente podman auto-update
    • Si hay una imagen nueva, recrea el contenedor con esa imagen
  • Auto-updating Podman containers with systemd, de Fedora Magazine, aportó la mayor parte del método de implementación, y además hicieron falta dos configuraciones
    • systemctl --user enable mycontainer.service para que el contenedor se inicie automáticamente al iniciar sesión
    • loginctl enable-linger para que la sesión de usuario funcione al arrancar el servidor
  • Con la combinación de Podman, systemd y user lingering se obtiene alrededor del 99% de las ventajas que daba Kubernetes, con mucha menos complejidad y carga de CPU y memoria
  • Se trasladó todo el servicio desde el VPS existente a un VPS nuevo con la mitad de vCPU y RAM y, tras varias horas de ejecución, resultó más ligero y rápido, además de tener menor costo de cómputo
  • Sin embargo, la integración de Podman con systemd parece estar ya discontinuada, y la definición de contenedores se está discutiendo en dirección a archivos Quadlet

1 comentarios

 
GN⁺ 2025-05-06
Opiniones de Hacker News
  • Me identifico totalmente con lo que siente el autor del texto original. En el trabajo administramos con relativa facilidad varios clústeres de Kubernetes con decenas de microservicios, pero en proyectos personales sin ingresos el presupuesto es tan chico que, aunque quisiera usar Kubernetes, no puedo
    En un VPS de USD 10 al mes con 1 vCPU compartida y 2 GB de RAM, Kubernetes es demasiado pesado. En vez de Deployments, ejecuto manualmente docker compose up/down por SSH; en vez de Ingress, dependo de la función de descubrimiento de contenedores de Traefik; y como no puedo usar CronJobs, hasta hice un pequeño script para administrar crontab de forma idempotente
    Lo que realmente quiero es una alternativa ligera que ofrezca una API compatible con Kubernetes y que funcione bien incluso en VPS baratos. La brecha entre la orquestación de contenedores de nivel empresarial y el hosting económico para hobbies sigue siendo demasiado grande

    • Según el alcance de la Kube API que necesites, Podman podría cumplir ese papel. Puede crear contenedores y pods a partir de manifiestos de Kubernetes, así que funciona como un docker compose que usa manifiestos de Kubernetes
      También se puede usar junto con unidades de systemd, como el enfoque descrito en el artículo. Podman además soporta la mayor parte, o quizá toda, la API de Docker, por lo que docker compose también funciona, y puedes conectarte a un socket remoto por SSH para trabajar
      https://docs.podman.io/en/latest/markdown/podman-kube-play.1...
      https://docs.podman.io/en/latest/markdown/podman-systemd.uni...
    • Me pregunto si viste k0s o k3s. Hay bastantes casos de gente que los usa bien a pequeña escala: https://news.ycombinator.com/item?id=43593269
    • No quiero sonar como publicidad de Oracle, pero el Oracle Cloud Free Tier es abrumadoramente generoso. Puedes correr bastantes cosas, incluido un clúster pequeño de k8s, y el servicio del plano de control de k8s también es gratis
      Te dan gratis 4 núcleos ARM64 y 24 GB de RAM, que puedes dividir en 1 a 4 nodos según prefieras
      https://www.oracle.com/cloud/free/
    • Puedes usar algo a la vieja usanza, como Ansible. Administro por completo algunos servidores dedicados con Ansible, y se puede usar como una especie de docker compose reforzado
      Con Traefik y etiquetas puedes generalizar el reverse proxy y los certificados TLS, y agregar Authelia como proveedor de autenticación simple. Hay muchos proyectos de ejemplo en GitHub, y con un fin de semana de configuración queda un sistema bastante fácil de administrar
    • Como ya dijiste que el costo de usar Kubernetes es demasiado alto, según el eje con el que midas la eficiencia, una solución hecha por ti mismo podría ser incluso más eficiente
  • A systemd se le critica mucho, pero resuelve muchísimos problemas, así que no hay que descartarlo tan fácilmente. En gran parte, a la gente no le gustó cuando empezó a venir por defecto en las distribuciones porque tenían que cambiar
    Incluye contenedores, machinectl, nspawn, que es un chroot más potente, vmspawn para cuando se necesita virtualización completa, importctl para descargar, importar y exportar máquinas, y homed/homectl, que facilitan el cifrado de directorios home y el control de permisos
    En vez de fstab, trata los montajes como unidades, controla el orden de arranque y el inicio/detención de servicios, y también ofrece timers más potentes que cron. Por ejemplo, permite saber si una tarea no se ejecutó porque la máquina estaba apagada, o ejecutarla con demora bajo ciertas condiciones después del arranque
    Las unidades de servicio permiten controlar las tareas con mucho detalle y limitar permisos, y con systemctl edit se pueden crear configuraciones de override sin tocar la configuración original. Aprenderlo al principio es un poco molesto, pero si vas a hacer cosas complejas, de todos modos no existe una herramienta para la que nunca tengas que mirar la documentación

    • Que systemd recibiera críticas durante sus primeros años, quizá casi una década, no fue porque el proyecto en sí fuera malo. Al contrario, era tan bueno que logró imponerse a pesar de varios problemas
      El problema fue la actitud de los mantenedores. Rompían sin más cosas que funcionaban bien y no ofrecían correcciones adecuadas. Si no sufriste por systemd, puede que hayas llegado tarde, o que tus necesidades coincidieran por casualidad con las de los mantenedores principales
    • Lo único que no me gusta de systemd es que un binario salido de una base de código enorme, casi incontable, asuma el rol de PID 1, y que durante las actualizaciones haga cosas aún más complejas intentando hacerse exec a sí mismo en el mismo lugar
      Un programa que haga exactamente el 100% de lo que debe hacer PID 1 y nada más podría ser mucho más pequeño. Si arrancas systemd desde ahí, aunque algo falle en systemd no termina de inmediato en un kernel panic
      Fuente: https://ewontfix.com/14/
    • Me cuesta aceptar eso de olvidarse de cron. Funcionó bien durante 50 años, y de pronto resulta que está muy mal y, por supuesto, debe ser reemplazado por systemd
    • Si te olvidas de fstab y usas montajes de systemd, las reglas de automontaje son complejas y, aunque las alinees 1:1 con la documentación, a veces simplemente no funcionan, por lo que el sistema de archivos puede no montarse a tiempo
    • systemd es excelente para un Linux moderno de escritorio o servidor, o usos similares. Pero si intentas hacer algo que se salga de la forma prevista por el proyecto, te vas a encontrar con burlas y resistencia. Pregúntale al equipo de musl
      Para las distribuciones o los upstreams les facilita muchísimo la vida, pero el costo es agregar una complejidad cada vez mayor en las capas más bajas del sistema. Según el punto de vista, cosas como journalctl, timedatectl, la dependencia de dbus o sus reemplazos pueden verse como algo que no encaja con la filosofía Unix
      Si el objetivo es simplemente coordinar procesos, ejecutarlos en el orden correcto y garantizar la activación automática, me parece una herramienta del nivel adecuado, más que k8s o Docker
  • Estuve operando mi homelab durante un tiempo con podman-systemd, es decir, Quadlet, y cada vez que revisaba alguna nueva variante de k8s no valía la pena asumir la molestia adicional. Con un viejo playbook de Ansible que ya descarga las imágenes por adelantado y pone los archivos de unidad en su lugar, alcanza
    También corro todo el stack de mi impresora 3D Voron con podman-systemd, de modo que puedo actualizar y hacer rollback de todos los componentes de una vez. Aunque ahora también estoy evaluando un enfoque con mkosi y systemd-sysupdate para actualizar y revertir una imagen de disco completa de una sola vez
    El principal problema es que la gente por lo general solo distribuye archivos docker-compose, así que hay que convertirlos a unidades de systemd, y que algunas imágenes Docker tienen una complejidad innecesaria para Podman en la configuración de usuarios y permisos. En particular, si el contenedor se niega a ejecutarse como root o cambia a otro usuario, a veces se necesitan molestos mapeos de ID de userns
    Aun así, en general es mucho menos complejo que cualquier configuración de k8s o de una variante de k8s. También me gusta que esté integrado tanto con systemd como con journald y no quede dividido en dos lugares

    • Uso un enfoque similar desde hace años: https://github.com/Mati365/hetzner-podman-bunjs-deploy. Está basado en Podman y systemd, y en todo este tiempo no se ha roto nada
      Es muy estable y simple porque solo hay que poner las unidades
    • Para convertir archivos compose en archivos Quadlet, se puede usar podlet: https://github.com/containers/podlet
    • Al final, me parece que esto es un solo nodo, o un conjunto de nodos independientes. Podman/systemd/Quadlet puede ser un detalle de implementación de cómo un nodo de k8s ejecuta contenedores, algo parecido al CRI
      Pero no reemplaza la abstracción de orquestación y scheduling sobre múltiples nodos que ofrece k8s. Falta la parte de “aquí están las máquinas que pueden ejecutar archivos Podman-systemd, y aquí está la especificación de lo que quiero ejecutar; distribúyelo automáticamente”
    • Tuve una experiencia parecida. El flujo de trabajo es levantar el contenedor con un comando podman run, verificar que funcione bien, luego crear un archivo de contenedor básico con podlet, y terminar ajustando ese archivo separando los volúmenes y la red en otros archivos Quadlet
      El proyecto podman-compose parece seguir manteniéndose activamente y podría ser una buena alternativa a docker-compose. Pero la integración entre Podman y systemd es tan satisfactoria
  • El siguiente paso para simplificar más esto es administrar contenedores dentro de systemd con Quadlet. Hay más detalles en https://www.redhat.com/en/blog/quadlet-podman

    • Quadlet es justamente ese camino. Es una forma realmente buena de ejecutar contenedores y, una vez configurada, se siente como algo de lo que puedes olvidarte. En Fedora o Rocky Linux, al menos, ni siquiera hace falta instalar paquetes adicionales
    • Se trató hacia el final del artículo, pero el autor todavía no lo había revisado. Como la integración de Podman con systemd ya parece deprecated y ahora se habla de definir contenedores con archivos “Quadlet”, lo dejó como algo para aprender más adelante
    • Vine a ver los comentarios para confirmar si alguien había mencionado Quadlet. La semana pasada migré mi servidor casero de docker compose a Podman Quadlet rootless, y aunque la transición fue difícil, estoy muy satisfecho con el resultado
    • Este artículo también ayudó mucho a migrar el homelab a Quadlet sin problemas: https://news.ycombinator.com/item?id=43456934
  • Creé skate: https://github.com/skateco/skate. Básicamente sirve para este propósito, pero soporta múltiples hosts y también manifiestos de k8s. Internamente usa Podman y systemd

    • Me gusta mucho este enfoque. Es realmente frustrante que no haya una forma simple de ejecutar Docker/Podman en varios hosts. Docker Swarm, lamentablemente, está en la práctica abandonado desde 2019
      Dicho eso, considero que k8s tiene una API y una experiencia de usuario pésimas. La especificación de Docker Compose es mucho más amigable, así que actualmente estoy experimentando con docker-compose para múltiples hosts: https://github.com/psviderski/uncloud
  • Volví a empaquetar todo como paquetes deb y a ejecutarlo directamente con systemd en instancias EC2, y ya no uso contenedores. Las instancias están en un Auto Scaling Group con un ALB, y al arrancar un ansible-pull simple instala el deb
    Es un enfoque bastante crudo, pero me cansé del HCL dentro de YAML dentro de JSON interminable. Ahora solo quiero lidiar, como mucho, con YAML de Ansible

    • Lo bueno de este enfoque es que, cuando hay un bug en una biblioteca común, puedes ejecutar apt full-upgrade y reiniciar solo los procesos en ejecución para quedar protegido
      No hace falta reconstruir nada ni averiguar cómo actualizar una biblioteca enterrada en las profundidades de un contenedor que quizá construiste tú, o quizá no
    • Tomé el mismo camino con una aplicación muy simple. systemd resultó ser sorprendentemente agradable, y me pareció bastante bueno ejecutar el servicio con privilegios mínimos usando una cuenta de usuario asignada por el sistema
      Gracias al soporte de cgroups, también es útil para correr varios servicios en un solo VPS
    • Da vértigo pensar en la cantidad de vida humana desperdiciada en el área problemática de “gestionar YAML a gran escala”
  • Como el artículo tiene más de un año, ahora incluso existe ParticleOS, una distribución de SO con soporte oficial para flujos de trabajo inmutables en systemd
    https://github.com/systemd/particleos
    https://news.ycombinator.com/item?id=43649088

    • El siguiente paso lógico sería reemplazar el kernel de Linux por systemd-kernel, y con eso quedaría completo
  • Después de leerlo, parece que todo esto podría reemplazarse con el comando docker compose y algo como Caddy, que obtiene certificados automáticamente
    Con solo tener compose.yaml, básicamente basta con una línea: docker compose up -d --pull always. Para la configuración de CI, también alcanza con scp compose.yaml user@remote-host:~/ seguido de ssh user@remote-host 'docker compose up -d --pull always'
    La ventaja es que es simple y también funciona en una máquina de desarrollo. Claro que, si el objetivo secundario es probar algo interesante y aprender, Quadlet, k8s y systemd también son buenas opciones

    • Solo hay que ejecutar una vez docker context create --docker 'host=ssh://user@remote-host' remote-host
      Después se puede usar docker -c remote-host compose -f compose.yaml up -d --pull always, sin necesidad de copiar el archivo. Además, si configuras la información de usuario en ~/.ssh/config, no hace falta escribir user@ en las llamadas SSH, lo que facilita que el equipo copie y use la documentación o los comandos
    • Se puede hacer como en el comentario hermano, o configurar la variable de entorno DOCKER_HOST. Solo hay que tener en cuenta que para la interpolación del archivo compose se usan las variables de entorno locales
  • Como pienso que desplegar en un solo servidor no debería ser tan complicado, creé una herramienta que despliega de la forma que quería: https://harbormaster.readthedocs.io/
    Harbormaster encuentra repositorios a partir de un archivo YAML, los clona y actualiza periódicamente, y luego ejecuta los archivos Docker Compose que hay dentro. También guarda todo el estado en un único directorio, así que es fácil de respaldar
    Si solo necesitas un servidor, es la herramienta de orquestación de contenedores más fácil y útil que he visto hasta ahora. Me gusta que toda la configuración se declare en el repositorio, que todo el estado esté en un directorio y que todo sean simplemente archivos Compose

  • Leer estos comentarios me hace sentir viejo. Me pregunto si ya nadie usa solo ssh y nginx
    Metes todo en una sola caja, haces copias de seguridad agresivas de esa caja, y listo. Para uso en casa, realmente no hace falta llegar a administrar microservicios

    • Yo solo uso nginx y algunos servicios personalizados, pero eso es posible porque mis requisitos son muy pequeños. En cuanto se vuelve un poco más complejo, o si necesitas levantar varios nodos para tener redundancia, los contenedores empiezan a tener muchísimo sentido