拯救boot分区空间不足的Ubuntu Server

apt在更新内核的时候不会移除旧版本内核。随着内核的不断更新,新的内核装进来,老的内核不会被删除,于是默认只有不到500MiB的/boot 慢慢变得不堪重负,塞满了内核和initrd。终于有一天,你在愉快地apt update && apt full-upgrade 的时候遇到了这样的错误:

gzip: stdout: No space left on device
E: mkinitramfs failure cpio 141 gzip 1
update-initramfs: failed for /boot/initrd.img-4.10.0-37-generic with 1.
run-parts: /etc/kernel/postinst.d/initramfs-tools exited with return code 1
dpkg: error processing package linux-image-extra-4.10.0-37-generic (--purge):
 subprocess installed post-removal script returned error exit status 1
Removing linux-image-extra-4.10.0-40-generic (4.10.0-40.44~16.04.1) ...
run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 4.10.0-40-generic /boot/vmlinuz-4.10.0-40-generic
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 4.10.0-40-generic /boot/vmlinuz-4.10.0-40-generic
update-initramfs: Generating /boot/initrd.img-4.10.0-40-generic

那么让我们试试修复这台服务器。

注意,因为每台服务器配置不尽相同,以下命令可能造成该服务器无法使用或数据损毁!请在知道你在做什么的前提下操作,事先做好备份工作,并且中途不要重启。作者对造成的任何损失概不负责。

首先我们来试试用正常的办法卸载不需要用到的内核包。

# 移除所有 initramfs 以便给接下来的操作留出空间
sudo update-initramfs -d -k all
# 删除所有不必要的包
sudo apt-get -f autoremove
# 修复安装中断的包
sudo dpkg --configure -a
sudo apt-get -f install
# 删掉所有仍然存在但是不必要的内核(以及其它包)
sudo apt-get autoremove

一般来说,这样就能解决问题了。但是有些时候由于一些包处于中间状态(half-installed)导致initrd之类的没有办法完全删除,就必须用下面的方法彻底删除掉所有相关文件然后重新安装最新版本内核了。

# 删除所有内核包
dpkg --get-selections | grep -E "linux-image(-extra)?-[0-9]" | cut -f1 | xargs -n1 sudo dpkg --purge --force-all
# 删除所有残留的内核相关文件
sudo update-initramfs -d -k all
dpkg -S /boot/initrd.img* /boot/vmlinuz* /boot/System.map* /boot/retpoline* 2>&1 >/dev/null | grep "no path" | awk 'NF>1{print $NF}' | xargs sudo rm 
# 装一个最新版内核(这边假设 generic 的内核包没有被卸载掉;否则请自行去装一个 generic 的内核包)
sudo dpkg --configure -a
sudo apt-get -f install
dpkg --get-selections | grep "linux-image-[0-9]\+" | cut -f1 | xargs -n1 sudo apt-get install --reinstall
# 确认新内核装完后立即重启,因为刚刚在用的内核应该已经被删掉了
sudo reboot

下次升级的时候,不要再忘记卸载老版本内核哦!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据