SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-24

Dọn kernel cũ trên Ubuntu để giải phóng /boot

Khi /boot đầy, apt báo lỗi và không thể cấu hình package. Xem kernel đang chạy, tìm linux-image có thể xóa an toàn, rồi giải phóng dung lượng đúng thứ tự.

Vì sao apt ngừng hoạt động khi /boot đầy các kernel cũ

Trên Ubuntu, mỗi lần cập nhật kernel sẽ ghi thêm một bộ file mới vào /boot và giữ lại các file của những kernel trước đó. Vì vậy, phân vùng /boot nhỏ có thể bị đầy và apt không thể hoàn tất quá trình cài đặt. Cách sửa gồm 2 bước. Xác định package nào trên máy là kernel và kernel nào đang được boot, sau đó dùng apt autoremove --purge để xóa các package còn lại.

Thứ tự thực hiện rất quan trọng. Kernel đang chạy là package không được xóa. Máy cũng có thể đã ở trạng thái khiến apt hoàn toàn không chạy được. Hãy chẩn đoán trước.

Hình thức thực tế của lỗi

Một version kernel cài 2 file lớn vào /boot: kernel đã nén (vmlinuz-<version>) và initramfs (initial RAM filesystem, initrd.img-<version>, archive nhỏ mà kernel giải nén trước khi mount root thực). initramfs được build trên máy của bạn trong lúc cài đặt. Vì vậy, quá trình cài cần dung lượng trống chứ không chỉ cần bandwidth để download. Khi không còn chỗ trống, bước build fail và kéo theo package fail.

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 1

Chuỗi version sẽ khác trên máy của bạn. Tên compressor lấy từ COMPRESS= trong /etc/initramfs-tools/initramfs.conf. Vì vậy, một image mới có thể dùng tên zstd, còn image cũ dùng gzip. Hai dòng xác định vấn đề này là No space left on device và dòng dpkg: error processing package ngay bên dưới.

Sau đó, package ở trạng thái half-configured. Mỗi lần chạy apt tiếp theo đều cố configure package này, fail theo cùng cách và kết thúc bằng E: Sub-process /usr/bin/dpkg returned an error code (1). Đây là điểm quan trọng ngoài vấn đề disk space: unattended-upgrades chạy theo timer, gặp lại cùng lỗi rồi dừng. Server vẫn có vẻ hoạt động bình thường nhưng âm thầm ngừng áp dụng security patch. Điều này cũng khiến mọi lần install package không liên quan đều fail với cùng dòng lỗi đó. Lỗi sẽ bị quy cho package bạn đang thêm vào lúc đó. Vì vậy, lỗi cài Tailscale trên Ubuntu nên được đọc và xử lý như một lỗi apt trước tiên. Nếu apt update fail trước khi đến bước này, đó là một vấn đề riêng, thường là entry bị trùng sau khi chuyển sang sources deb822.

Kiểm tra xem /boot có phải là một phân vùng riêng không

Trước khi xóa bất kỳ thứ gì, hãy xác định chính xác bạn đang giải phóng dung lượng ở đâu.

findmnt /boot
findmnt -T /boot
df -h /boot /

Lệnh đầu tiên chỉ in một dòng nếu /boot là mount point riêng. Lệnh thứ hai luôn in kết quả và cho biết filesystem thực sự chứa /boot. Nếu cả hai lệnh đều chỉ đến filesystem giống /, thì /boot chỉ là một thư mục trên root filesystem và không thể tự đầy riêng: root filesystem của bạn đã đầy, còn kernel cũ chỉ là một trong nhiều nguyên nhân. Trong trường hợp đó, sudo apt clean sẽ xóa các file .deb đã tải xuống trong /var/cache/apt/archives và giúp giải phóng dung lượng. Trên máy có phân vùng /boot thực sự, apt clean hoàn toàn không giải phóng dung lượng trên phân vùng đó, vì cache nằm trên filesystem khác.

Bây giờ hãy lấy giá trị bạn sẽ dùng để đối chiếu.

df -h /boot
ls -lh /boot/vmlinuz-$(uname -r) /boot/initrd.img-$(uname -r)

So sánh cột Avail với kích thước của hai file đó. initrd là file lớn hơn. Lần cập nhật kernel tiếp theo cần thêm dung lượng cho một cặp file có kích thước xấp xỉ như vậy, nên nếu Avail nhỏ hơn initrd hiện tại thì lần cập nhật tiếp theo chắc chắn sẽ thất bại.

Tìm kernel đang chạy

uname -r
cat /var/run/reboot-required.pkgs

uname -r in chuỗi release của kernel hiện đang được nạp trong bộ nhớ. Sao chép chuỗi đó vào một nơi khác. Đây là phiên bản bạn tuyệt đối không được xóa.

File thứ hai chỉ tồn tại khi một package yêu cầu reboot. Một dòng linux-image trong file này nghĩa là trên disk đã có kernel mới hơn nhưng chưa được sử dụng, vì máy chưa reboot kể từ khi kernel đó được cài đặt. Nếu có thể, hãy reboot trước khi cleanup. apt bảo vệ kernel đang chạy và kernel mới nhất, vì vậy cleanup khi đang chạy kernel cũ sẽ giữ lại thêm một phiên bản không cần thiết.

Liệt kê các package kernel và đọc trạng thái của chúng

dpkg --list | grep -E 'linux-(image|modules|headers|tools)' | awk '{print $1, $2}'

Trường đầu tiên là mã trạng thái của dpkg. ii nghĩa là package đã được cài đặt và cấu hình hoàn tất. iF nghĩa là package đã được cài đặt nhưng mới cấu hình một phần. Đây chính xác là trạng thái mà lần nâng cấp bị lỗi ở trên để lại. rc nghĩa là package đã bị gỡ nhưng cấu hình vẫn còn trên disk. Trạng thái này không chiếm dung lượng trong /boot và có thể purge an toàn.

Trường thứ hai cho biết loại package. Tên có chứa version, chẳng hạn linux-image-6.8.0-64-generic, là một kernel cụ thể. Tên không chứa version, chẳng hạn linux-image-generic, linux-headers-generic hoặc linux-generic, là meta package. Meta package không chứa kernel. Nhiệm vụ duy nhất của nó là phụ thuộc vào kernel có version mới nhất để apt upgrade kéo kernel mới về. Gỡ meta package sẽ khiến máy không nhận được các bản cập nhật kernel nữa, và sau đó không có cảnh báo nào cho bạn.

Các family được chia như sau. linux-image-* chứa kernel đã nén trong /boot. linux-modules-* và linux-modules-extra-* chứa driver trong /lib/modules. linux-headers-* chứa header phục vụ build trong /usr/src. Vì vậy, purge header sẽ giải phóng dung lượng trên root filesystem, không phải dung lượng trong /boot. Nếu vấn đề của bạn là phân vùng /boot đã đầy, các image package là những package cần tìm.

ls -1 /boot/vmlinuz-*
ls -1 /lib/modules/

Hai danh sách này phải khớp với nhau và khớp với output của dpkg --list. Một directory trong /lib/modules không có package tương ứng đang được cài đặt là phần còn sót lại do ai đó xóa file thủ công.

Cách apt quyết định những kernel nào cần giữ lại

apt autoremove sẽ không xóa kernel mà nó xem là được bảo vệ. Tập kernel được bảo vệ bao gồm kernel bạn đang chạy. Chính sách giữ lại đã thay đổi giữa các bản phát hành Ubuntu, vì vậy hãy đọc chính sách trên chính máy của bạn thay vì tin vào một con số được ghi ở đâu đó.

apt-config dump | grep -i -e neverautoremove -e versionedkernel
ls -l /etc/apt/apt.conf.d/01autoremove /etc/apt/apt.conf.d/01autoremove-kernels

APT::NeverAutoRemove là danh sách các mẫu tên package mà apt autoremove từ chối xử lý. APT::VersionedKernelPackages là danh sách các tiền tố tên mà apt dùng để xác định package kernel có phiên bản ngay từ đầu. Trên các bản phát hành tạo ra /etc/apt/apt.conf.d/01autoremove-kernels, file đó được /etc/kernel/postinst.d/apt-auto-removal ghi lại mỗi khi cài một kernel package. Vì vậy, chỉnh sửa file thủ công không có tác dụng: lần cài kernel tiếp theo sẽ ghi đè thay đổi của bạn. Trên các bản phát hành không có file này, apt áp dụng cùng cơ chế bảo vệ ở bên trong. Dù theo cách nào, apt-config dump vẫn hiển thị các quy tắc đang được áp dụng trên máy của bạn. Kết quả đó là câu trả lời chính xác cho bản phát hành bạn đang dùng.

Dọn dẹp an toàn để thực hiện

sudo apt update
sudo apt autoremove --purge --dry-run

--dry-run không thay đổi gì trên disk và in chính xác những gì lần chạy thật sẽ xóa. Hãy đọc danh sách này. Có hai trường hợp bạn phải dừng lại. Một meta package như linux-generic hoặc linux-image-generic xuất hiện trong danh sách gỡ bỏ nghĩa là có thành phần đã đánh dấu package đó là automatic. Gỡ nó sẽ khiến hệ thống không còn cập nhật kernel. Chuỗi từ uname -r xuất hiện trong danh sách gỡ bỏ nghĩa là kernel đang chạy không được bảo vệ. Điều này không được xảy ra và cần điều tra trước khi tiếp tục.

Nếu danh sách đúng, hãy chạy lệnh thật.

sudo apt autoremove --purge
df -h /boot

Phần --purge cũng xóa cấu hình còn sót lại cùng với package. Nó chỉ giải phóng thêm một ít dung lượng, nhưng giúp dpkg --list không tích lũy các dòng rc, nhờ đó lần audit tiếp theo dễ đọc hơn.

Sau đó xác nhận boot menu đã được rebuild. Việc gỡ một kernel package sẽ chạy update-grub, vì vậy menu chỉ nên tham chiếu đến những file vẫn còn tồn tại.

sudo grep -o 'vmlinuz-[^ ]*' /boot/grub/grub.cfg | sort -u
ls -1 /boot/vmlinuz-*

Mọi version trong output đầu tiên phải xuất hiện trong output thứ hai. Một menu entry trỏ đến file đã bị xóa có thể khiến server đang hoạt động dừng tại GRUB prompt. Đây là một trong những nguyên nhân dẫn đến VPS không boot được sau khi cập nhật kernel, và xử lý lỗi này từ rescue console khó hơn nhiều so với việc ngăn lỗi xảy ra ngay từ đầu.

Vì sao apt autoremove đôi khi không xóa gì

apt autoremove chỉ xóa các package được đánh dấu là tự động, tức là các package được cài làm dependency của thành phần khác. Kernel bạn tự cài bằng apt install linux-image-6.8.0-40-generic được đánh dấu là manual, nên autoremove sẽ không bao giờ xóa kernel đó, dù nó đã cũ đến đâu.

apt-mark showmanual | grep -E '^linux-'

Mọi kernel có version xuất hiện trong kết quả đó đều không được autoremove xử lý. Hãy xóa chúng bằng cách dùng các chuỗi version trong danh sách của chính bạn:

sudo apt-mark auto linux-image-6.8.0-40-generic linux-modules-6.8.0-40-generic
sudo apt autoremove --purge --dry-run

Hãy giữ các meta package ở trạng thái manual. Chúng phải được đánh dấu manual vì đó là các package bạn yêu cầu cài.

Xóa có chủ đích một kernel cụ thể

Đôi khi bạn muốn xóa ngay một phiên bản cụ thể thay vì chờ đến khi policy cho phép. Chỉ định image package và để apt tự xử lý phần còn lại.

sudo apt purge linux-image-6.8.0-40-generic

apt in danh sách các package sẽ bị xóa trước khi thực hiện, vì linux-modules-extra-* phụ thuộc vào image package và phải được xóa trong cùng transaction. Danh sách này là bước kiểm tra an toàn thực tế. Đây cũng là nơi bạn phát hiện meta package bị kéo ra cùng với phiên bản mà bạn định xóa. Trả lời n nếu danh sách có bất kỳ mục nào không mong muốn. Sau đó chạy sudo apt autoremove --purge để thu gom các module package và header package không còn lý do tồn tại.

Vì sao không bao giờ xóa kernel đang chạy

Kernel đã được nạp vào memory vẫn tiếp tục chạy sau khi các file của nó bị xóa, nên ban đầu không có lỗi rõ ràng. Lỗi xảy ra với mọi thứ mà kernel chưa nạp. Purge linux-modules-$(uname -r) sẽ xóa /lib/modules/$(uname -r)/, nên lần nạp module tiếp theo sẽ fail:

modprobe: FATAL: Module nf_tables not found in directory /lib/modules/6.8.0-64-generic

Từ thời điểm đó, reload firewall sẽ fail. Việc mount một filesystem type mà kernel này chưa dùng kể từ lúc boot cũng fail. Trong khi đó, /boot/vmlinuz-$(uname -r) đã bị xóa, nên boot menu không còn cung cấp kernel đang chạy. Lần reboot tiếp theo sẽ khởi động vào một kernel khác. Máy vẫn tiếp tục xử lý network traffic nhưng đã không thể boot. Mỗi lần kiểm tra danh sách cần xóa, hãy đối chiếu với uname -r.

Khi /boot quá đầy khiến apt hoàn toàn không thể chạy

Đây là tình trạng khiến mọi người tìm đến trang này. apt autoremove cần dpkg hoàn tất cấu hình package kernel đang ở trạng thái cấu hình dở dang trước, và bước đó sẽ rebuild initramfs. Bước này cần dung lượng trong /boot, nhưng phân vùng này không còn chỗ trống. Hãy phá vòng lặp này bằng tay một lần.

uname -r
ls -1 /boot/initrd.img-*

Chọn một initrd có version không phải chuỗi uname -r đã cung cấp, rồi xóa đúng file đó.

sudo rm /boot/initrd.img-6.8.0-40-generic
sudo apt --fix-broken install
sudo apt autoremove --purge
sudo update-grub

Mỗi dòng đều có lý do. rm là một ngoại lệ có chủ ý, khiến dpkg vẫn tin rằng một file tồn tại dù thực tế không có. apt --fix-broken install hoàn tất việc cấu hình đã thất bại, vì lúc này đã có chỗ cho initramfs. Sau đó, autoremove --purge xóa package chứa file bạn đã xóa cùng với các version cũ khác, đưa dpkg trở lại đồng bộ với disk. update-grub rebuild menu dựa trên những file thực sự tồn tại. Không reboot giữa rm và update-grub, vì trong khoảng thời gian đó menu vẫn có thể trỏ đến file bạn vừa xóa. Nếu dpkg báo rằng tiến trình bị gián đoạn, sudo dpkg --configure -a thực hiện cùng cách repair như apt --fix-broken install.

Công việc tương tự trên các hệ thống dùng dnf

Nếu VPS của bạn chạy Fedora hoặc một trong các bản rebuild của RHEL như Rocky Linux, cơ chế này hoạt động ngược lại. Debian và Ubuntu bảo vệ kernel bằng các quy tắc autoremove của apt, rồi để bạn hoặc unattended-upgrades thực hiện việc dọn dẹp, trong khi dnf áp dụng một số lượng có tên là installonly_limit và tự động xóa kernel cũ nhất ngay khi cài đặt kernel mới khiến số lượng vượt quá giới hạn này. Đọc giá trị đang được áp dụng bằng grep installonly_limit /etc/dnf/dnf.conf và man 5 dnf.conf, đồng thời xóa các kernel tồn đọng bằng sudo dnf remove --oldinstallonly. Kernel đang chạy cũng được bảo vệ trong cơ chế này. Để xem bảng đối chiếu rộng hơn giữa hai package manager, hãy xem các lệnh tương đương giữa dnf và apt.

Ngăn lỗi này lặp lại

Dọn dẹp dựa vào việc bạn nhớ thực hiện sẽ sớm hoặc muộn bị bỏ sót, vì vậy hãy đưa cấu hình đó vào thành phần cài đặt kernel. Mở /etc/apt/apt.conf.d/50unattended-upgrades và tìm các khóa sau. File được cung cấp đã có sẵn chúng dưới dạng các dòng comment:

Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";

Bỏ comment các dòng này thay vì thêm một bản sao thứ hai vào cuối file. Trong cấu hình apt, phép gán cuối cùng của một khóa sẽ được áp dụng. Vì vậy, khóa trùng lặp khiến file tự mâu thuẫn và không còn rõ giá trị nào đang có hiệu lực. Kiểm tra giá trị mà parser đã nhận được và theo dõi một lần chạy không thay đổi gì:

apt-config dump | grep -i 'Unattended-Upgrade::Remove'
sudo unattended-upgrade --dry-run --debug
sudo tail -n 40 /var/log/unattended-upgrades/unattended-upgrades.log

Log là bằng chứng. Log ghi lại mọi lần chạy, vì vậy một lần upgrade thất bại do thiếu dung lượng sẽ xuất hiện ở đó từ lâu trước khi có người nhận ra máy chủ đang thiếu các bản vá. Phần còn lại của cấu hình này được trình bày trong cập nhật bảo mật tự động trên Ubuntu.

Trước khi kernel tiếp theo được cài đặt, bạn cần kiểm tra một giá trị. Đây cũng là cặp lệnh đã dùng ở đầu hướng dẫn này:

df -h /boot
ls -lh /boot/initrd.img-$(uname -r)

Nếu Avail không lớn hơn file đó một cách đủ an toàn, kernel tiếp theo sẽ thất bại đúng như mô tả ở trên. Vì vậy, hãy sửa ngay bây giờ thay vì chờ đến lúc upgrade. Bạn nên dành một phút kiểm tra cùng với các kiểm tra tình trạng disk trên VPS khác. Việc này đặc biệt quan trọng ngay trước một release upgrade, vì nâng Ubuntu 24.04 lên 26.04 sẽ cài kernel mới ngay từ đầu quá trình và do-release-upgrade sẽ từ chối tiếp tục khi /boot không đủ dung lượng. Nếu LTS server của bạn chưa được cung cấp upgrade đó, nguyên nhân là do thời điểm chứ không phải lỗi, vì Ubuntu trì hoãn upgrade từ LTS lên LTS cho đến khi bản phát hành 26.04.1 được phát hành. Nhờ vậy, bạn có một khoảng thời gian rõ ràng để chuẩn bị /boot trước.

FAQ

Vì sao Ubuntu giữ lại các kernel cũ thay vì xóa chúng?

Vì nếu một kernel không khởi động được, bạn sẽ không còn kernel khác để chọn. Giữ lại phiên bản trước đó giúp khôi phục sau một bản cập nhật lỗi từ menu GRUB, thay vì phải dùng rescue console của nhà cung cấp. apt vì vậy bảo vệ một nhóm kernel package khỏi bị tự động gỡ, luôn bao gồm kernel đang chạy. Chạy apt-config dump | grep -i neverautoremove để xem chính xác các pattern mà bản release của bạn bảo vệ, vì chính sách này đã thay đổi giữa các bản release.

Chạy apt autoremove --purge trên production server có an toàn không?

Có, nếu bạn đọc dry run trước. Chạy sudo apt autoremove --purge --dry-run, lệnh này không ghi thay đổi nào, rồi kiểm tra danh sách được in ra. Dừng lại nếu danh sách chứa meta package như linux-generic hoặc linux-image-generic, vì gỡ một trong các package đó sẽ chấm dứt những lần cập nhật kernel sau này. Cũng dừng lại nếu danh sách chứa chuỗi phiên bản mà uname -r in ra. Nếu không có mục nào trong hai loại trên, các package sẽ bị gỡ là kernel cũ và dependency mồ côi.

apt autoremove không gỡ gì và /boot vẫn đầy. Bây giờ phải làm gì?

Các kernel cũ gần như chắc chắn đang được đánh dấu là manual, còn autoremove chỉ xử lý các package được đánh dấu là automatic. Chạy apt-mark showmanual | grep -E '^linux-'. Mọi kernel có phiên bản được liệt kê ở đó đều từng được cài thủ công. Đánh dấu kernel đó là automatic bằng sudo apt-mark auto linux-image-<version> rồi chạy dry run lại, hoặc purge trực tiếp phiên bản đó bằng sudo apt purge linux-image-<version>.

Tôi có thể tự xóa file trong /boot không?

Chỉ nên làm một lần có chủ đích, khi /boot đầy đến mức apt không thể cấu hình kernel package đang bị lỗi. Xóa một file initrd.img-<version> duy nhất có phiên bản không xuất hiện trong output của uname -r, rồi ngay lập tức chạy sudo apt --fix-broken install, sudo apt autoremove --purge và sudo update-grub. Xóa file mà không thực hiện các bước tiếp theo sẽ khiến dpkg ghi nhận các package đã mất file, đồng thời để lại các mục trong menu GRUB trỏ đến những file không còn tồn tại. Khi đó máy sẽ fail ở lần reboot tiếp theo, thay vì fail ngay lúc bạn mắc lỗi.