Substituindo Kubernetes por systemd (2024)
(blog.yaakov.online)- Em servidores pessoais e VPSs pequenos, a automação declarativa do Kubernetes é atraente, mas a carga de CPU e memória e a complexidade operacional podem superar os ganhos reais
- O Kubernetes automatiza tarefas como ajustar Pods e renovar certificados TLS mantendo continuamente o estado desejado, mas para isso mantém um runtime consideravelmente grande sempre em execução
- Em experimentos com Azure Kubernetes Service, Microk8s, K3S e Raspberry Pi, o uso de recursos em idle, o aquecimento e o ruído das ventoinhas se repetiram como problemas
- O Podman pode transformar contêineres em serviços systemd e detectar e substituir novas imagens com
io.containers.autoupdateepodman auto-update - A combinação de Podman, systemd e user lingering oferece de forma mais simples a maior parte da automação desejada no Kubernetes, mas a integração com systemd está migrando para a direção do Quadlet
Por que a automação do Kubernetes era pesada para servidores pessoais
- O Kubernetes é composto por vários componentes, serviços web, sidecars e webhooks, mas seu funcionamento central se aproxima de um loop que compara continuamente o estado atual com o estado desejado e aplica as diferenças
- Se um Pod deveria existir e não existe, ele o cria
- Se deveria haver 3 réplicas, mas há 4, ele remove uma
- Esse modelo foi especialmente útil em extensões como o cert-manager
- Declara-se que deve existir um certificado TLS válido para um determinado domínio
- Ao informar como solicitar o certificado, se ele não existir ou estiver perto de expirar, um novo certificado é obtido e instalado no servidor web
- Para experimentos pessoais, era divertido e tinha valor de aprendizado, mas para operação real ficava mais próximo de uma ferramenta excessiva
- A carga de recursos se repetiu em vários ambientes
- Em um NUC, o computador ficava rodando continuamente, esquentava e gerava ruído de ventoinha, dificultando dormir
- No Azure Kubernetes Service, a implementação do Kubernetes ocupava muita RAM e usava cerca de 7–10% da CPU em idle no worker node
- Uma instância única do Microk8s em um VPS x86_64 com 2 vCPUs ficava com cerca de 12% de CPU em idle
- O K3S em uma máquina Ampere A1 com 2 vCPUs é conhecido como uma implementação mais leve, mas usava cerca de 6% de CPU constante
- Mesmo no Raspberry Pi, não foi encontrada uma implementação que deixasse CPU suficiente para a carga de trabalho sem problemas de aquecimento e ventoinha
O modelo de automação adotado com Podman e systemd
- O principal motivo para continuar usando Kubernetes era a automação de deploy
- Com GitOps e Flux, fazer mudanças era fácil
- Com a automação de imagens de contêiner e os webhooks do Flux v2, ao enviar uma nova imagem, em poucos segundos o servidor a baixava e executava a aplicação em produção
- As alternativas existentes encontradas fora do Kubernetes não eram satisfatórias
- A abordagem de lembrar todos os argumentos originais da linha de comando para recriar o contêiner gerava muita carga de gerenciamento
- Ferramentas que exigiam controle total do
docker.socktambém não eram preferidas
- A atualização automática do Podman era próxima do recurso necessário
- O Podman pode ser visto como uma alternativa à CLI do Docker
- Depois de criar um contêiner, é possível gerar um arquivo de serviço systemd
- Ao iniciar o serviço, ele cria ou substitui o contêiner; ao parar o serviço, ele remove o contêiner
- A atualização automática funciona pela tag
io.containers.autoupdate- Ela é executada uma vez por dia por um timer, ou
podman auto-updateé executado diretamente - Se houver uma nova imagem, o contêiner é recriado com essa imagem
- Ela é executada uma vez por dia por um timer, ou
- O artigo Auto-updating Podman containers with systemd, da Fedora Magazine, forneceu a maior parte do método de implementação, e foram necessárias mais duas configurações
systemctl --user enable mycontainer.servicepara fazer o contêiner iniciar automaticamente ao fazer loginloginctl enable-lingerpara fazer a sessão do usuário funcionar na inicialização do servidor
- Com a combinação de Podman, systemd e user lingering, obtêm-se cerca de 99% dos benefícios que o Kubernetes oferecia, com muito menos complexidade e carga de CPU e memória
- Todos os serviços foram movidos do VPS antigo para um novo VPS com metade da vCPU e da RAM e, com base em algumas horas de execução, ele ficou mais leve, mais rápido e com menor custo computacional
- No entanto, a integração do Podman com systemd parece já estar descontinuada, e a definição de contêineres está sendo discutida na direção dos arquivos Quadlet
1 comentários
Opiniões no Hacker News
Tenho total empatia pelo sentimento do autor original. No trabalho, gerenciamos com relativa facilidade vários clusters Kubernetes rodando dezenas de microsserviços, mas em projetos de hobby sem receita o orçamento é pequeno, então mesmo querendo usar Kubernetes, não dá
Em um VPS de US$ 10 por mês com 1 vCPU compartilhada e 2 GB de RAM, Kubernetes é pesado demais. Em vez de Deployments, acabo executando manualmente
docker compose up/downvia SSH; em vez de Ingress, dependo do recurso de descoberta de contêineres do Traefik; e, por não poder usar CronJobs, até criei um pequeno script para gerenciar o crontab de forma idempotenteO que eu realmente quero é uma alternativa leve que ofereça uma API compatível com Kubernetes e rode bem até em VPS barato. A lacuna entre orquestração de contêineres de nível corporativo e hospedagem barata para hobby ainda é grande demais
docker composeque usa manifestos KubernetesTambém pode ser usado junto com units do systemd, como no método descrito no texto. O Podman também oferece suporte à maior parte, ou talvez a toda, a API do Docker, então
docker composefunciona, e também é possível trabalhar conectando-se a um socket remoto via SSHhttps://docs.podman.io/en/latest/markdown/podman-kube-play.1...
https://docs.podman.io/en/latest/markdown/podman-systemd.uni...
Eles dão gratuitamente 4 cores ARM64 e 24 GB de RAM, que você pode dividir em 1 a 4 nós, dependendo de como quiser
https://www.oracle.com/cloud/free/
docker composereforçadoUse Traefik e labels para generalizar o proxy reverso e os certificados TLS, e adicione Authelia como um provedor simples de autenticação. Há muitos projetos de exemplo no GitHub e, com uma configuração de fim de semana, vira um sistema bem fácil de manter
O systemd recebe muitas críticas, mas resolve problemas demais para ser descartado facilmente. Grande parte da rejeição quando ele começou a vir por padrão nas distribuições era porque as pessoas precisavam mudar
Há contêineres,
machinectl,nspawn, que é um chroot mais poderoso,vmspawnpara quando é necessária virtualização completa,importctlpara baixar, importar e exportar máquinas,homed/homectl, que facilita criptografia de diretórios home e controle de permissões, e assim por dianteEm vez de
fstab, ele trata montagens como units, controla a ordem de boot e o início/parada de serviços, e também fornece timers mais poderosos quecron. Por exemplo, é possível saber sobre tarefas que não foram executadas porque a máquina estava desligada, ou executá-las com atraso após o boot sob determinadas condiçõesUnits de serviço permitem controlar tarefas de forma granular e restringir permissões, e com
systemctl edité possível criar configurações de override sem mexer na configuração original. Aprender no começo é um pouco chato, mas, para fazer coisas complexas, não existe ferramenta que dispense totalmente a leitura da documentaçãoO problema era a postura dos mantenedores. Eles quebravam coisas que funcionavam bem sem se incomodar muito e sem oferecer correções adequadas. Se você não sentiu dor por causa do systemd, talvez tenha chegado mais tarde, ou suas necessidades tenham coincidido por acaso com as necessidades dos mantenedores principais
execem si mesmo no lugarUm programa que faça exatamente 100% do que o PID 1 precisa fazer, e nada além disso, poderia ser muito menor. Se o systemd for iniciado a partir daí, algum problema no systemd não levará imediatamente a um kernel panic
Fonte: https://ewontfix.com/14/
cron. Ele funcionou bem por 50 anos, e de repente virou algo terrivelmente errado que obviamente deve ser substituído pelo systemdfstabe usar montagens do systemd, as regras de automount são complexas e, mesmo alinhando 1:1 com a documentação, às vezes simplesmente não funcionam, então o sistema de arquivos pode não ser montado a tempoPara distribuições ou upstreams, ele facilita muito a vida, mas o preço é adicionar uma complexidade cada vez maior às camadas mais baixas do sistema. Dependendo do ponto de vista, coisas como
journalctl,timedatectl, dependência de dbus ou substitutos podem ser vistas como incompatíveis com a filosofia UnixSe o objetivo for apenas coordenar processos, executá-los na ordem correta e garantir ativação automática, considero uma ferramenta em um nível mais adequado do que k8s ou Docker
Venho mantendo meu homelab há um tempo com podman-systemd, ou seja, Quadlet, e toda vez que olhava uma nova variante de k8s, não parecia valer o trabalho extra. Com playbooks antigos do Ansible, já basta baixar as imagens com antecedência e colocar os arquivos de unit no lugar certo
Também rodei toda a stack da impressora 3D Voron com podman-systemd, para conseguir atualizar e fazer rollback de todos os componentes de uma vez. Mas agora também estou avaliando atualizar e fazer rollback da imagem de disco inteira de uma vez com
mkosiesystemd-sysupdateO principal problema é que, em geral, as pessoas só distribuem arquivos
docker-compose, então é preciso convertê-los para units do systemd; e algumas imagens Docker têm complexidade desnecessária para o Podman na configuração de usuários e permissões. Em especial, quando o contêiner se recusa a rodar como root ou troca para outro usuário, às vezes é necessário lidar com o incômodo mapeamento de IDs deusernsMesmo assim, no geral é muito menos complexo do que qualquer configuração de k8s ou variante de k8s. Também gosto do fato de integrar tanto com systemd quanto com journald, sem ficar dividido em dois lugares
Como basta colocar as units, é muito estável e simples
composeem arquivos Quadlet, dá para usar opodlet: https://github.com/containers/podletMas isso não substitui a abstração de orquestração e agendamento sobre vários nós que o k8s oferece. Falta a parte de “aqui estão as máquinas capazes de executar arquivos Podman-systemd, aqui está a especificação que quero rodar; distribua isso por conta própria”
podman run, verificar se roda corretamente, gerar um arquivo básico de contêiner compodlete então ajustar esse arquivo separando volumes e redes em outros arquivos Quadlet. E prontoO projeto
podman-composetambém parece ainda ser mantido ativamente e pode ser uma boa alternativa aodocker-compose. Mas a integração entre Podman e systemd é satisfatória demaisO próximo passo para simplificar ainda mais isso é gerenciar contêineres dentro do systemd com Quadlet. Há mais detalhes em https://www.redhat.com/en/blog/quadlet-podman
docker composepara Podman Quadlet rootless; a transição foi difícil, mas fiquei muito satisfeito com o resultadoCriei o skate: https://github.com/skateco/skate. Basicamente é para esse propósito, mas com suporte a vários hosts e também a manifestos do k8s. Por baixo, usa Podman e systemd
Mas considero que o k8s tem uma API e uma experiência de usuário péssimas. A especificação do Docker Compose é muito mais amigável, então estou experimentando no momento um
docker-composepara vários hosts: https://github.com/psviderski/uncloudVoltei a empacotar tudo como pacotes deb e a executar diretamente com systemd em instâncias EC2, sem usar mais contêineres. As instâncias ficam em um Auto Scaling Group ligado a um ALB, e um
ansible-pullsimples na inicialização instala o debÉ uma abordagem bem crua, mas cansei do HCL dentro de YAML dentro de JSON sem fim. Agora quero lidar, no máximo, com YAML do Ansible
apt full-upgradee reiniciar apenas os processos em execução para ficar protegidoNão é preciso reconstruir nada nem descobrir como atualizar uma biblioteca enterrada nas profundezas de um contêiner que talvez você tenha construído — ou talvez não
Graças ao suporte a cgroups, também é bom para rodar vários serviços em um único VPS
Como o artigo tem mais de um ano, hoje existe até o ParticleOS, uma distribuição de sistema operacional com suporte oficial do systemd para fluxos de trabalho imutáveis
https://github.com/systemd/particleos
https://news.ycombinator.com/item?id=43649088
systemd-kernel, e aí estaria completoPelo que li, parece que tudo isso poderia ser substituído pelo comando
docker composee algo como o Caddy, que obtém certificados automaticamenteCom apenas um
compose.yaml, basicamente basta uma linha:docker compose up -d --pull always. A configuração de CI também se resume ascp compose.yaml user@remote-host:~/seguido dessh user@remote-host 'docker compose up -d --pull always'A vantagem é que é simples e também funciona na máquina de desenvolvimento. Claro, se o objetivo secundário for experimentar algo interessante e aprender, Quadlet, k8s e systemd também são boas escolhas
docker context create --docker 'host=ssh://user@remote-host' remote-hostDepois disso, use
docker -c remote-host compose -f compose.yaml up -d --pull always, sem precisar copiar o arquivo. Além disso, se você configurar as informações de usuário em~/.ssh/config, não precisa usaruser@nas chamadas SSH, o que facilita para a equipe copiar e usar a documentação ou os comandosDOCKER_HOST. Só é preciso tomar cuidado porque a interpolação do arquivocomposeusa variáveis de ambiente locaisEu achava que fazer deploy em um único servidor não deveria ser tão complicado, então criei uma ferramenta para fazer deploy do jeito que eu queria: https://harbormaster.readthedocs.io/
O Harbormaster encontra repositórios a partir de um arquivo YAML, clona e atualiza periodicamente, e então executa os arquivos Docker Compose dentro deles. Todo o estado também fica em um único diretório, facilitando o backup
Se você só precisa de um único servidor, é a ferramenta de orquestração de contêineres mais fácil e melhor que já vi. Gosto do fato de toda a configuração ser declarada no repositório, todo o estado ficar em um diretório e tudo ser simplesmente arquivos Compose
Lendo os comentários aqui, me sinto velho. Fico pensando se agora ninguém mais usa só ssh e nginx
É só enfiar tudo em uma única máquina e fazer backup dela de forma agressiva, e pronto. Para uso doméstico, gerenciamento de microsserviços realmente não é necessário