Como limpar kernels antigos do Ubuntu e liberar /boot
Veja quais kernels podem ser removidos com segurança quando /boot lota, o apt para de configurar pacotes e surge a falha ao criar o initramfs.
Por que o apt deixa de funcionar quando /boot fica cheio com kernels antigos
No Ubuntu, cada atualização do kernel grava um novo conjunto de ficheiros em /boot e mantém os anteriores, fazendo com que uma partição /boot pequena fique cheia e apt já não consiga concluir uma instalação. A reparação tem duas etapas. Identifique quais pacotes instalados são kernels e qual kernel foi utilizado no arranque. Depois, remova os restantes com apt autoremove --purge.
A ordem é importante. O kernel em execução é o pacote que não pode remover. O sistema pode já estar num estado em que apt não consegue ser executado. Faça primeiro o diagnóstico.
Como é que a falha se manifesta
Uma versão do kernel instala dois ficheiros grandes em /boot: o kernel comprimido (vmlinuz-<version>) e o initramfs (sistema de ficheiros RAM inicial, initrd.img-<version>, o pequeno arquivo que o kernel descompacta antes de montar o root real). O initramfs é criado na sua máquina durante a instalação. Por isso, a instalação precisa de espaço livre, e não apenas de largura de banda para a transferência. Quando já não há espaço, a criação falha e arrasta o pacote consigo.
update-initramfs: Generating /boot/initrd.img-6.8.0-64-generic
gzip: stdout: No space left on device
E: mkinitramfs failure gzip 1
update-initramfs: failed for /boot/initrd.img-6.8.0-64-generic with 1.
dpkg: error processing package linux-image-6.8.0-64-generic (--configure):
installed linux-image-6.8.0-64-generic package post-installation script subprocess returned error exit status 1A cadeia da versão será a sua. O nome do compressor vem de COMPRESS= em /etc/initramfs-tools/initramfs.conf. Por isso, uma imagem recente pode chamar-se zstd, enquanto uma mais antiga se chama gzip. As duas linhas que identificam este problema são No space left on device e a linha dpkg: error processing package que aparece abaixo.
Depois disso, o pacote fica parcialmente configurado. Cada execução posterior de apt tenta configurá-lo novamente, falha da mesma forma e termina com E: Sub-process /usr/bin/dpkg returned an error code (1). Esta é a parte que importa para além do espaço em disco: unattended-upgrades é executado pelo seu temporizador, encontra o mesmo erro e para. O servidor parece saudável e deixa silenciosamente de aplicar atualizações de segurança. Isto também significa que qualquer instalação independente que tente fazer falha com a mesma linha, e a culpa parece ser do que estava a adicionar naquele momento. Por isso, vale a pena ler uma instalação do Tailscale que falha no Ubuntu primeiro como um erro do apt. Se apt update falhar antes de chegar a este ponto, trata-se de um problema separado, frequentemente uma entrada duplicada depois da migração das fontes para deb822.
Verifique se /boot é uma partição separada
Antes de eliminar qualquer coisa, descubra exatamente o que está a libertar.
findmnt /boot
findmnt -T /boot
df -h /boot /O primeiro comando apresenta uma linha apenas se /boot for o seu próprio ponto de montagem. O segundo apresenta sempre uma linha e identifica o sistema de ficheiros que realmente contém /boot. Se ambos identificarem o mesmo sistema de ficheiros que /, então /boot é apenas um diretório no sistema de ficheiros raiz e não pode ficar cheio sozinho: o sistema de ficheiros raiz está cheio, e os kernels antigos são apenas uma das várias causas. Nesse caso, sudo apt clean, que elimina os ficheiros .deb transferidos para /var/cache/apt/archives, liberta espaço. Numa máquina com uma partição /boot real, apt clean não liberta qualquer espaço nessa partição, porque a cache está noutro sistema de ficheiros.
Agora obtenha o valor que vai usar como referência.
df -h /boot
ls -lh /boot/vmlinuz-$(uname -r) /boot/initrd.img-$(uname -r)Compare a coluna Avail com o tamanho desses dois ficheiros. O initrd é o maior dos dois. A próxima atualização do kernel precisa de espaço para outro par com aproximadamente esse tamanho. Por isso, se Avail for menor do que o initrd atual, a próxima atualização já vai falhar.
Identifique o kernel em execução
uname -r
cat /var/run/reboot-required.pkgsuname -r apresenta a string de release do kernel atualmente carregado na memória. Copie essa string para algum lugar. Essa é a versão que não deve ser removida.
O segundo ficheiro só existe quando um pacote solicitou um reboot. Uma linha linux-image nesse ficheiro indica que existe um kernel mais recente instalado no disco, mas ainda não utilizado, porque a máquina não foi reiniciada desde a instalação. Faça o reboot antes da limpeza, se possível. apt protege o kernel em execução e o mais recente. Por isso, limpar enquanto executa um kernel antigo mantém mais uma versão retida do que o necessário.
Listar os pacotes do kernel e consultar os respetivos estados
dpkg --list | grep -E 'linux-(image|modules|headers|tools)' | awk '{print $1, $2}'O primeiro campo é o código de estado do dpkg. ii significa instalado e configurado. iF significa instalado, mas parcialmente configurado, que é exatamente o estado deixado pela atualização falhada acima. rc significa removido, com a configuração ainda no disco. Isto não ocupa espaço em /boot e pode ser purgado com segurança.
O segundo campo indica o tipo de pacote. Um nome que inclui uma versão, como linux-image-6.8.0-64-generic, corresponde a um kernel específico. Um nome sem versão, como linux-image-generic, linux-headers-generic ou linux-generic, corresponde a um meta pacote. Este pacote não contém nenhum kernel. A sua única função é depender do kernel mais recente com versão, para que apt upgrade instale novos kernels. Remover um meta pacote impede a máquina de receber atualizações do kernel, e nada o avisa depois disso.
As famílias dividem-se da seguinte forma. linux-image-* contém o kernel comprimido em /boot. linux-modules-* e linux-modules-extra-* contêm os controladores em /lib/modules. linux-headers-* contém os cabeçalhos de compilação em /usr/src, o que significa que purgar os cabeçalhos liberta espaço no sistema de ficheiros root, mas não em /boot. Se o problema for uma partição /boot cheia, os pacotes de imagens são os que deve procurar.
ls -1 /boot/vmlinuz-*
ls -1 /lib/modules/Estas duas listagens devem corresponder entre si e também ao resultado de dpkg --list. Um diretório em /lib/modules sem um pacote instalado correspondente é um remanescente de uma eliminação manual de ficheiros.
Como o apt decide quais kernels manter
O apt autoremove não remove um kernel que considere protegido, e o conjunto protegido inclui o kernel que está em execução. A política de retenção mudou entre as versões do Ubuntu. Por isso, consulte-a na sua própria máquina em vez de confiar num número registado em qualquer outro lugar.
apt-config dump | grep -i -e neverautoremove -e versionedkernel
ls -l /etc/apt/apt.conf.d/01autoremove /etc/apt/apt.conf.d/01autoremove-kernelsO APT::NeverAutoRemove é a lista de padrões de nomes de pacotes que o apt autoremove se recusa a alterar. O APT::VersionedKernelPackages é a lista de prefixos de nomes que o apt trata primeiro como pacotes de kernel versionados. Nas versões que geram /etc/apt/apt.conf.d/01autoremove-kernels, esse ficheiro é reescrito pelo /etc/kernel/postinst.d/apt-auto-removal sempre que um pacote de kernel é instalado. Editá-lo manualmente não produz efeito, porque a instalação do kernel seguinte substitui a sua alteração. Nas versões em que o ficheiro não existe, o apt aplica internamente a mesma proteção. Em qualquer dos casos, o apt-config dump apresenta as regras em vigor na sua máquina. Esse resultado é a resposta correta para a sua versão.
A limpeza segura de executar
sudo apt update
sudo apt autoremove --purge --dry-run--dry-run não altera nada no disco e mostra exatamente o que a execução real removeria. Leia a lista. Duas situações devem fazê-lo parar. Um metapacote como linux-generic ou linux-image-generic na lista de remoção significa que algo o marcou como automático, e removê-lo interrompe as atualizações do kernel. A cadeia de uname -r na lista de remoção significa que o kernel em execução não está protegido. Isso não deveria acontecer e requer investigação antes de prosseguir.
Se a lista estiver correta, execute o comando efetivamente.
sudo apt autoremove --purge
df -h /bootA variante --purge também elimina a configuração restante, além do pacote. Liberta pouco espaço adicional e impede que dpkg --list acumule linhas rc, o que torna a próxima auditoria legível.
Em seguida, confirme que o menu de arranque foi reconstruído. A remoção de um pacote do kernel executa update-grub, por isso o menu deve referenciar apenas ficheiros que ainda existem.
sudo grep -o 'vmlinuz-[^ ]*' /boot/grub/grub.cfg | sort -u
ls -1 /boot/vmlinuz-*Cada versão apresentada no primeiro resultado deve aparecer no segundo. Uma entrada de menu que aponta para um ficheiro eliminado pode fazer com que um servidor funcional pare no prompt do GRUB. Essa é uma das formas de obter um VPS que não arranca depois de uma atualização do kernel, e é muito mais difícil corrigir o problema a partir de uma consola de recuperação do que evitá-lo aqui.
Por que o apt autoremove às vezes não remove nada
apt autoremove remove apenas os pacotes marcados como automáticos, ou seja, os pacotes instalados como dependência de outro pacote. Um kernel instalado manualmente, com apt install linux-image-6.8.0-40-generic, é marcado como manual, e o autoremove nunca o removerá, por mais antigo que seja.
apt-mark showmanual | grep -E '^linux-'Qualquer kernel com versão nessa saída não é considerado pelo autoremove. Marque-o novamente como automático usando as versões que aparecem na sua própria listagem:
sudo apt-mark auto linux-image-6.8.0-40-generic linux-modules-6.8.0-40-generic
sudo apt autoremove --purge --dry-runDeixe os meta pacotes marcados como manuais. Eles devem ser manuais, porque foram instalados explicitamente por si.
Remover deliberadamente um kernel específico
Por vezes, é necessário remover já uma versão específica, em vez de esperar até que a política o permita. Indique o pacote da imagem e deixe o apt determinar o restante.
sudo apt purge linux-image-6.8.0-40-genericO apt apresenta uma lista de remoção antes de executar qualquer ação, porque o linux-modules-extra-* depende do pacote da imagem e tem de ser removido na mesma transação. Essa lista é a sua verificação de segurança efetiva. É nela que deteta a remoção de um meta-pacote juntamente com a versão que pretendia remover. Responda n se houver algum item inesperado. Em seguida, use sudo apt autoremove --purge para recolher os pacotes de módulos e cabeçalhos que deixaram de ter uma razão para permanecer instalados.
Por que você nunca remove o kernel em execução
O kernel já carregado na memória continua em execução depois que os respetivos ficheiros são eliminados, por isso nada parece falhar inicialmente. O que falha é tudo o que o kernel ainda não carregou. A purga de linux-modules-$(uname -r) elimina /lib/modules/$(uname -r)/, por isso o carregamento seguinte do módulo falha:
modprobe: FATAL: Module nf_tables not found in directory /lib/modules/6.8.0-64-genericA partir desse momento, o recarregamento da firewall falha, assim como a montagem de um tipo de sistema de ficheiros que este kernel ainda não utilizou desde o arranque. Entretanto, /boot/vmlinuz-$(uname -r) desapareceu, por isso o menu de arranque já não disponibiliza o kernel em execução, e o próximo reboot inicia outro kernel. A máquina continua a servir tráfego e já não pode arrancar. Compare uname -r com a lista de remoção em todas as ocasiões.
Quando /boot está demasiado cheio para o apt funcionar
Este é o estado que leva as pessoas a procurar esta página. apt autoremove precisa de dpkg para concluir primeiro a configuração do pacote do kernel parcialmente configurado, e essa etapa reconstrói um initramfs, que precisa de espaço num /boot que não tem nenhum. Interrompa o ciclo manualmente, uma vez.
uname -r
ls -1 /boot/initrd.img-*Escolha um initrd cuja versão não seja a cadeia uname -r que lhe foi apresentada e elimine apenas esse ficheiro.
sudo rm /boot/initrd.img-6.8.0-40-generic
sudo apt --fix-broken install
sudo apt autoremove --purge
sudo update-grubCada linha tem uma razão. O rm é uma exceção deliberada que faz o dpkg acreditar que existe um ficheiro quando ele não existe. O apt --fix-broken install conclui a configuração que falhou, agora que há espaço para o initramfs. O autoremove --purge remove depois o pacote cujo ficheiro eliminou, juntamente com as outras versões antigas, o que volta a alinhar o dpkg com o conteúdo do disco. O update-grub reconstrói o menu a partir dos ficheiros que existem efetivamente. Não reinicie entre rm e update-grub, porque, nesse intervalo, o menu ainda pode apontar para o ficheiro que acabou de eliminar. Se dpkg indicar que foi interrompido, sudo dpkg --configure -a executa a mesma reparação que apt --fix-broken install.
O mesmo procedimento em sistemas dnf
Se o seu VPS executar Fedora ou uma das reconstruções do RHEL, como Rocky Linux, o mecanismo é inverso. Debian e Ubuntu protegem os kernels com regras de remoção automática do apt e deixam a limpeza a seu cargo ou para ser acionada pelo unattended-upgrades, enquanto o dnf impõe uma quantidade chamada installonly_limit e remove automaticamente o kernel mais antigo assim que uma nova instalação ultrapassaria esse limite. Consulte o valor em vigor com grep installonly_limit /etc/dnf/dnf.conf e man 5 dnf.conf e limpe os kernels antigos existentes com sudo dnf remove --oldinstallonly. O kernel em execução também é protegido nesse sistema. Para ver o mapeamento mais abrangente entre os dois gestores de pacotes, consulte os equivalentes dos comandos dnf e apt.
Evite que volte a acontecer
Uma limpeza que depende de se lembrar de a executar acabará por falhar. Por isso, configure-a no componente que instala os kernels. Abra /etc/apt/apt.conf.d/50unattended-upgrades e procure estas chaves, que o ficheiro fornecido já contém como linhas comentadas:
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";Retire o comentário dessas linhas em vez de acrescentar uma segunda cópia no fim do ficheiro. Na configuração do apt, prevalece a última atribuição de uma chave. Assim, uma chave duplicada deixa o ficheiro inconsistente e oculta qual é o valor efetivo. Verifique o resultado interpretado pelo parser e monitorize uma execução que não altere nada:
apt-config dump | grep -i 'Unattended-Upgrade::Remove'
sudo unattended-upgrade --dry-run --debug
sudo tail -n 40 /var/log/unattended-upgrades/unattended-upgrades.logO log é a prova. Regista cada execução. Assim, uma atualização que falhou por falta de espaço fica registada muito antes de alguém perceber que a máquina está sem patches. O restante dessa configuração é explicado em atualizações de segurança automáticas no Ubuntu.
Antes de o próximo kernel ser instalado, há um valor a verificar. São os mesmos dois comandos apresentados no início deste guia:
df -h /boot
ls -lh /boot/initrd.img-$(uname -r)Se Avail não for significativamente maior do que esse ficheiro, a instalação do próximo kernel falhará exatamente como descrito acima. Corrija o problema agora, e não durante a atualização. Esta verificação demora um minuto e complementa as suas verificações de integridade do disco numa VPS. É especialmente importante antes de uma atualização de release, porque atualizar o Ubuntu 24.04 para 26.04 instala um kernel novo logo no início do processo e do-release-upgrade recusa continuar quando /boot tem pouco espaço disponível.
FAQ
Por que o Ubuntu mantém kernels antigos em vez de os apagar?
Porque um kernel que não arranca deixa-o sem outra opção para selecionar. Manter a versão anterior permite recuperar de uma atualização problemática a partir do menu do GRUB, em vez de usar a consola de recuperação do fornecedor. apt protege, por isso, um conjunto de pacotes de kernel contra a remoção automática, incluindo sempre o que está em execução. Execute apt-config dump | grep -i neverautoremove para ver os padrões exatos protegidos pela sua versão, pois a política mudou entre versões.
É seguro executar apt autoremove --purge num servidor de produção?
Sim, desde que leia primeiro a simulação. Execute sudo apt autoremove --purge --dry-run, que não escreve nada, e verifique a lista apresentada. Pare se ela contiver um meta-pacote como linux-generic ou linux-image-generic, porque a remoção de um desses pacotes interrompe as futuras atualizações do kernel. Pare também se ela contiver a cadeia de versão apresentada por uname -r. Se nenhum dos dois casos ocorrer, as remoções correspondem a kernels antigos e dependências órfãs.
apt autoremove não removeu nada e /boot continua cheio. E agora?
É quase certo que os kernels antigos estão marcados como instalados manualmente, e o autoremove só atua sobre pacotes marcados como automáticos. Execute apt-mark showmanual | grep -E '^linux-'. Qualquer kernel com versão listado nesse comando foi instalado manualmente em algum momento. Marque-o como automático com sudo apt-mark auto linux-image-<version> e execute novamente a simulação, ou remova diretamente essa versão com sudo apt purge linux-image-<version>.
Posso apagar manualmente ficheiros de /boot?
Apenas como medida pontual e deliberada, quando /boot está tão cheio que apt não consegue configurar o pacote de kernel com problemas. Apague um único ficheiro initrd.img-<version> cuja versão não seja a apresentada por uname -r e execute imediatamente sudo apt --fix-broken install, sudo apt autoremove --purge e sudo update-grub. Apagar ficheiros sem estes passos seguintes deixa dpkg a registar pacotes cujos ficheiros já não existem e deixa entradas no menu do GRUB a apontar para ficheiros inexistentes. A máquina falha no arranque seguinte, e não no momento em que o erro foi cometido.