Remover kernels antigos do Ubuntu e liberar /boot
Veja o erro que impede o apt de configurar pacotes quando /boot lota, identifique o kernel em execução e remova com segurança as versões antigas.
Por que o apt deixa de funcionar quando o /boot fica cheio de kernels antigos
No Ubuntu, cada atualização do kernel grava um novo conjunto de ficheiros em /boot e mantém os anteriores, por isso uma partição /boot pequena fica cheia e o apt já não consegue concluir uma instalação. A reparação tem duas etapas. Identifique quais pacotes instalados no sistema são kernels e qual deles está em execução. Depois, remova os restantes com apt autoremove --purge.
A ordem é importante. O kernel em execução é o pacote que não pode ser removido, e o sistema pode já estar num estado em que apt não consegue ser executado. Faça primeiro o diagnóstico.
Como é o erro na prática
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 a raiz 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 não resta espaço, a criação falha e o pacote também falha.
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 de 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 imagem 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 imediatamente 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 além do espaço em disco: unattended-upgrades é executado de acordo com o seu temporizador, encontra o mesmo erro e para. O servidor parece estar saudável, mas deixa silenciosamente de aplicar atualizações de segurança. Isto também significa que qualquer instalação não relacionada que tente fazer falha com a mesma linha, e a culpa recai sobre o 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, muitas vezes uma entrada duplicada depois da migração das fontes para deb822.
Verifique se /boot é uma partição separada
Antes de apagar 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 contém realmente /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 por si só: 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 esvazia os ficheiros .deb transferidos em /var/cache/apt/archives, liberta espaço. Numa máquina com uma partição /boot real, apt clean não liberta 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. 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.
Identificar o kernel em execução
uname -r
cat /var/run/reboot-required.pkgsuname -r imprime 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 remover.
O segundo ficheiro só existe quando um pacote solicita um reboot. Uma linha linux-image nesse ficheiro indica que há 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.
Liste os pacotes do kernel e consulte 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 é precisamente o estado deixado pela atualização que falhou acima. rc significa removido, mas com a configuração ainda no disco, o que não ocupa espaço em /boot e pode ser eliminado 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, identifica um kernel específico. Um nome sem versão, como linux-image-generic, linux-headers-generic ou linux-generic, é um meta-pacote. Não contém nenhum kernel. A sua única função é depender da versão mais recente do kernel, para que apt upgrade instale novos kernels. Remover um meta-pacote impede a máquina de receber atualizações do kernel, sem apresentar qualquer aviso posteriormente.
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 eliminar os cabeçalhos liberta espaço no sistema de ficheiros raiz, mas não espaço em /boot. Se o problema for uma partição /boot cheia, deve procurar os pacotes de imagens.
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 resíduo deixado por alguém que eliminou ficheiros manualmente.
Como o apt decide quais kernels manter
apt autoremove não remove um kernel que considere protegido, e o conjunto protegido inclui o kernel que está a executar agora. A política de retenção mudou entre versões do Ubuntu, por isso consulte-a na sua própria máquina em vez de confiar num número registado em qualquer lugar.
apt-config dump | grep -i -e neverautoremove -e versionedkernel
ls -l /etc/apt/apt.conf.d/01autoremove /etc/apt/apt.conf.d/01autoremove-kernelsAPT::NeverAutoRemove é a lista de padrões de nomes de pacotes que apt autoremove se recusa a alterar. APT::VersionedKernelPackages é a lista de prefixos de nomes que apt considera, desde logo, pacotes de kernel com versões. Nas versões que geram /etc/apt/apt.conf.d/01autoremove-kernels, esse ficheiro é reescrito por /etc/kernel/postinst.d/apt-auto-removal sempre que um pacote de kernel é instalado, por isso editá-lo manualmente não produz qualquer efeito: a instalação seguinte de um kernel substitui a sua edição. Nas versões em que o ficheiro não existe, apt aplica internamente a mesma proteção. Em qualquer dos casos, apt-config dump mostra as regras em vigor na sua máquina, e esse resultado é a resposta correta para a sua versão.
A limpeza segura para 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. Dois itens devem fazer a execução parar. Um metapacote como linux-generic ou linux-image-generic na lista de remoção indica 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 indica que o kernel em execução não está protegido. Isso não deveria acontecer e precisa ser investigado antes de prosseguir.
Se a lista estiver correta, execute o comando efetivamente.
sudo apt autoremove --purge
df -h /bootA opção --purge também remove a configuração restante, além do pacote. Ela libera pouco espaço adicional e mantém dpkg --list livre do acúmulo de linhas rc, o que torna a próxima auditoria mais fácil de ler.
Em seguida, confirme que o menu de boot foi reconstruído. A remoção de um pacote do kernel executa update-grub automaticamente, portanto 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 na primeira saída deve aparecer na segunda. Uma entrada do menu que aponta para um ficheiro inexistente pode fazer um servidor funcional parar no prompt do GRUB. Essa é uma das formas de chegar a um VPS que não arranca depois de uma atualização do kernel, e é muito mais difícil corrigir o problema numa consola de recuperação do que evitá-lo neste ponto.
Por que 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, fica marcado como manual, e o autoremove nunca o remove, por mais antigo que seja.
apt-mark showmanual | grep -E '^linux-'Qualquer kernel com versão apresentada nessa saída é ignorado pelo autoremove. Volte a marcá-lo como automático usando as versões listadas no seu sistema:
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. Essa é a marcação esperada, porque foi você que pediu a instalação deles.
Remover intencionalmente um kernel específico
Às vezes, é necessário remover já uma versão específica, em vez de esperar até que a política permita a remoção. 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 também tem de ser removido na mesma transação. Essa lista é a sua verificação de segurança efetiva. É nela que pode detetar a remoção de um metapacote juntamente com a versão que pretendia remover. Responda n se houver algum item inesperado. Depois, execute sudo apt autoremove --purge para recolher os pacotes de módulos e cabeçalhos que já não têm motivo para permanecer instalados.
Por que nunca se remove o kernel em execução
O kernel que já está na memória continua em execução depois de os seus ficheiros serem eliminados, por isso nada parece falhar inicialmente. O que falha é tudo o que o kernel ainda não carregou. A remoção de linux-modules-$(uname -r) elimina /lib/modules/$(uname -r)/, por isso o carregamento seguinte de um 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 tenha utilizado desde o arranque. Entretanto, /boot/vmlinuz-$(uname -r) desaparece, por isso o menu de arranque deixa de disponibilizar o kernel em execução, e o próximo reboot inicia outro kernel. A máquina continua a servir tráfego, mas já não arranca. 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. O apt autoremove precisa do dpkg para concluir primeiro a configuração do pacote de kernel parcialmente configurado, e esse passo recria um initramfs, que precisa de espaço num /boot que não tem espaço disponível. 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 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 um ficheiro existe quando ele não existe. O apt --fix-broken install conclui a configuração que falhou, agora que existe espaço para o initramfs. O autoremove --purge remove então 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 recria o menu com base nos ficheiros que realmente existem. 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 será inverso. Debian e Ubuntu protegem os kernels com regras de remoção automática do apt e deixam a limpeza a seu cargo ou ao 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. Leia 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 fica protegido. Para consultar o mapeamento mais abrangente entre os dois gestores de pacotes, veja os equivalentes dos comandos dnf e apt.
Impedir que volte a acontecer
A limpeza que depende de se lembrar dela 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. Na configuração do apt, prevalece a última atribuição de uma chave. Uma duplicação deixa o ficheiro incoerente e oculta qual é o valor efetivo. Confirme o resultado obtido pelo analisador 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 reparar que a máquina está atrasada nas correções. O restante dessa configuração é explicado em atualizações de segurança automáticas no Ubuntu.
Antes de instalar o próximo kernel, há um valor a verificar. É o mesmo par de comandos apresentado 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 outras verificações de integridade do disco num VPS. É especialmente importante antes de uma atualização de versão, porque atualizar o Ubuntu 24.04 para o 26.04 instala um kernel novo no início do processo e do-release-upgrade recusa continuar quando /boot tem pouco espaço disponível. Se o seu servidor LTS ainda não recebeu essa atualização, o motivo é o calendário, não uma falha. O Ubuntu adia as atualizações de LTS para LTS até ser lançada a versão de manutenção 26.04.1, o que lhe dá uma janela conhecida para organizar primeiro /boot.
FAQ
Por que o Ubuntu mantém kernels antigos em vez de os eliminar?
Porque um kernel que falha ao arrancar deixa-o sem outra versão para selecionar. Manter a versão anterior permite recuperar de uma atualização com problemas 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 metapacote como linux-generic ou linux-image-generic, porque remover um desses pacotes impede futuras atualizações do kernel. Pare também se ela contiver a cadeia de versão apresentada por uname -r. Se nenhuma das duas condições 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ó processa pacotes marcados como automáticos. Execute apt-mark showmanual | grep -E '^linux-'. Qualquer kernel com versão listado 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 eliminar ficheiros de /boot manualmente?
Apenas de forma deliberada e pontual, quando /boot está tão cheio que apt não consegue configurar o pacote de kernel com problemas. Elimine 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. Eliminar ficheiros sem estes passos posteriores deixa dpkg a registar pacotes cujos ficheiros já não existem e deixa entradas no menu do GRUB a apontar para ficheiros ausentes. A máquina falha no arranque seguinte, em vez de falhar no momento em que o erro foi cometido.