Ubuntu /boot 파티션 용량 부족 및 오래된 커널 삭제 방법
Ubuntu에서 /boot 파티션이 가득 차 apt 설치가 중단되는 현상을 해결합니다. 현재 부팅된 커널을 제외한 불필요한 linux-image 패키지를 안전하게 식별하고 제거하여 디스크 공간을 확보하는 정확한 절차를 안내합니다.
/boot 파티션이 오래된 커널로 가득 찰 때 apt가 작동을 멈추는 이유
Ubuntu에서는 커널이 업데이트될 때마다 새로운 파일 세트가 /boot에 기록되며, 이전 파일들은 그대로 남습니다. 이로 인해 용량이 작은 /boot 파티션이 가득 차게 되고, apt은 설치 작업을 완료할 수 없게 됩니다. 복구는 두 단계로 진행됩니다. 시스템에 설치된 패키지 중 커널인 것을 확인하고 현재 부팅된 커널을 제외한 나머지를 apt autoremove --purge로 제거해야 합니다.
순서가 중요합니다. 실행 중인 커널은 절대 제거해서는 안 되는 패키지이며, 시스템은 이미 apt이 전혀 실행되지 않는 상태일 수 있습니다. 먼저 진단을 수행하십시오.
실제 장애 현상
커널 버전이 설치되면 /boot 디렉터리에 두 개의 큰 파일이 생성됩니다. 압축된 커널 파일인 vmlinuz-<version>와, 커널이 실제 루트 파일 시스템을 마운트하기 전에 압축을 해제하는 작은 아카이브인 initramfs(initial RAM filesystem, initrd.img-<version>)입니다. initramfs는 설치 시점에 로컬 머신에서 빌드되므로, 단순히 다운로드 대역폭뿐만 아니라 충분한 여유 공간이 필요합니다. 디스크 공간이 부족하면 빌드 과정이 실패하고 패키지 설치도 함께 중단됩니다.
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버전 문자열은 사용자의 환경에 따라 다릅니다. 압축 프로그램 이름은 /etc/initramfs-tools/initramfs.conf 파일의 COMPRESS= 설정에 따라 결정되므로, 최신 이미지에서는 zstd를 사용하고 이전 버전에서는 gzip을 사용할 수 있습니다. 이 문제를 식별할 수 있는 두 줄은 No space left on device과 그 아래에 있는 dpkg: error processing package 라인입니다.
이후 패키지는 설정이 완료되지 않은 상태로 남습니다. 이후에 실행되는 모든 apt 명령은 해당 패키지를 다시 설정하려고 시도하지만 동일한 이유로 실패하며 E: Sub-process /usr/bin/dpkg returned an error code (1) 메시지로 종료됩니다. 디스크 공간 문제보다 더 중요한 점은 unattended-upgrades가 타이머에 맞춰 실행되다가 같은 오류를 만나 중단된다는 것입니다. 서버는 정상적으로 작동하는 것처럼 보이지만, 보안 패치 적용이 조용히 멈추게 됩니다. 또한, 이 상태에서는 다른 패키지를 설치하려 해도 동일한 오류가 발생하며, 그 원인이 당시 설치하려던 패키지에 있는 것처럼 보일 수 있습니다. 이것이 바로 Ubuntu에서 실패하는 Tailscale 설치 사례를 먼저 apt 오류로 확인해야 하는 이유입니다. 만약 이 단계에 도달하기 전에 apt update이 실패한다면, 이는 별개의 문제이며 주로 deb822 소스 마이그레이션 후 발생하는 중복 항목 문제일 가능성이 큽니다.
/boot가 별도의 파티션인지 확인하기
무언가를 삭제하기 전에, 실제로 확보할 수 있는 공간이 어느 정도인지 확인해야 합니다.
findmnt /boot
findmnt -T /boot
df -h /boot /첫 번째 명령어는 /boot이 자체 마운트 지점인 경우에만 한 줄을 출력합니다. 두 번째 명령어는 항상 출력하며, 실제로 /boot을 포함하고 있는 파일 시스템의 이름을 보여줍니다. 만약 두 명령어가 /와 동일한 파일 시스템을 가리킨다면, /boot은 루트 파일 시스템 내의 디렉터리일 뿐이며 단독으로 용량이 꽉 찰 수 없습니다. 즉, 루트 파일 시스템 자체가 가득 찬 상태이며, 오래된 커널은 여러 원인 중 하나일 뿐입니다. 이 경우 /var/cache/apt/archives 아래에 다운로드된 .deb 파일을 비우는 sudo apt clean 명령어를 실행하여 공간을 확보할 수 있습니다. 별도의 /boot 파티션이 있는 시스템에서는 캐시가 다른 파일 시스템에 위치하므로 apt clean를 실행해도 해당 파티션의 공간은 확보되지 않습니다.
이제 작업 대상이 될 수치를 확인합니다.
df -h /boot
ls -lh /boot/vmlinuz-$(uname -r) /boot/initrd.img-$(uname -r)Avail 열의 값을 해당 두 파일의 크기와 비교하십시오. initrd 파일이 더 큽니다. 다음 커널 업데이트 시에는 대략 그 정도 크기의 파일 쌍이 추가로 들어갈 공간이 필요합니다. 따라서 Avail의 여유 공간이 현재 initrd 파일보다 작다면, 다음 업데이트는 이미 실패할 가능성이 높습니다.
현재 실행 중인 커널 확인하기
uname -r
cat /var/run/reboot-required.pkgsuname -r은 현재 메모리에 로드된 커널의 릴리스 문자열을 출력합니다. 이 문자열을 어딘가에 복사해 두십시오. 이 버전은 절대 삭제해서는 안 되는 커널입니다.
두 번째 파일은 패키지가 재부팅을 요청했을 때만 존재합니다. 파일 안에 linux-image 줄이 있다면, 디스크에는 더 최신 커널이 설치되어 있으나 시스템이 재부팅되지 않아 사용되지 않고 있다는 뜻입니다. 가능하다면 정리 작업을 수행하기 전에 재부팅하십시오. apt은 실행 중인 커널과 가장 최신 커널을 보호합니다. 따라서 구형 커널을 실행 중인 상태에서 정리하면 필요한 것보다 한 버전 더 많은 커널이 유지됩니다.
커널 패키지 목록을 나열하고 상태 확인하기
dpkg --list | grep -E 'linux-(image|modules|headers|tools)' | awk '{print $1, $2}'첫 번째 필드는 dpkg의 상태 코드입니다. ii은 설치 및 설정 완료를 의미합니다. iF는 설치는 되었으나 설정이 완료되지 않은 상태를 의미하며, 이는 위에서 언급한 업그레이드 실패 시 발생하는 전형적인 결과입니다. rc은 패키지는 제거되었으나 설정 파일이 디스크에 남아 있는 상태를 의미합니다. 이 상태는 /boot 공간을 차지하지 않으므로 안전하게 삭제(purge)할 수 있습니다.
두 번째 필드는 패키지의 종류를 나타냅니다. linux-image-6.8.0-64-generic와 같이 이름 안에 버전이 포함된 것은 특정 커널 패키지입니다. 반면 linux-image-generic, linux-headers-generic, linux-generic처럼 버전이 없는 이름은 메타 패키지입니다. 메타 패키지는 커널 자체를 포함하지 않습니다. 이 패키지의 유일한 역할은 최신 버전의 커널에 의존성을 걸어 apt upgrade가 새로운 커널을 자동으로 가져오도록 하는 것입니다. 메타 패키지를 제거하면 시스템이 더 이상 커널 업데이트를 받지 않게 되며, 이후에 이를 경고해 주는 장치도 없습니다.
커널 패키지군은 다음과 같이 나뉩니다. linux-image-*은 /boot에 압축된 커널을 담고 있습니다. linux-modules-*와 linux-modules-extra-*은 /lib/modules 경로에 드라이버를 포함합니다. linux-headers-*는 /usr/src 경로에 빌드 헤더를 포함하며, 따라서 헤더를 삭제하면 /boot 공간이 아닌 루트 파일 시스템 공간이 확보됩니다. 만약 /boot 파티션이 가득 찬 것이 문제라면, 이미지 패키지를 정리해야 합니다.
ls -1 /boot/vmlinuz-*
ls -1 /lib/modules/이 두 목록은 서로 일치해야 하며 dpkg --list 출력 결과와도 부합해야 합니다. /lib/modules 디렉터리에 존재하지만 설치된 패키지 목록에 없는 디렉터리는 사용자가 수동으로 파일을 삭제한 뒤 남은 찌꺼기입니다.
apt가 커널 유지 여부를 결정하는 방식
apt autoremove은 보호 대상으로 간주하는 커널을 삭제하지 않으며, 현재 실행 중인 커널은 보호 대상에 포함됩니다. 유지 정책은 Ubuntu 릴리스마다 변경되었으므로, 어딘가에 적힌 숫자를 맹신하기보다 본인의 시스템에서 직접 확인해야 합니다.
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는 apt autoremove이 삭제를 거부하는 패키지 이름 패턴 목록입니다. APT::VersionedKernelPackages는 apt가 버전이 지정된 커널 패키지로 취급하는 이름 접두사 목록입니다. /etc/apt/apt.conf.d/01autoremove-kernels을 생성하는 릴리스에서는 커널 패키지가 설치될 때마다 /etc/kernel/postinst.d/apt-auto-removal이 해당 파일을 다시 작성하므로, 수동으로 편집해도 소용이 없습니다. 다음 커널 설치 시 편집 내용이 덮어쓰이기 때문입니다. 해당 파일이 없는 릴리스에서는 apt이 내부적으로 동일한 보호 정책을 적용합니다. 어느 경우든 apt-config dump를 실행하면 현재 시스템에 적용된 규칙을 확인할 수 있으며, 해당 출력값이 본인의 릴리스에 대한 정확한 답변입니다.
안전하게 실행할 수 있는 정리 작업
sudo apt update
sudo apt autoremove --purge --dry-run--dry-run은 디스크의 내용을 변경하지 않으며, 실제 실행 시 삭제될 항목을 그대로 출력합니다. 목록을 확인하십시오. 중단을 고려해야 할 두 가지 상황이 있습니다. 삭제 목록에 linux-generic이나 linux-image-generic와 같은 메타 패키지가 포함되어 있다면, 이는 해당 패키지가 자동으로 표시되었음을 의미하며 이를 삭제하면 커널 업데이트가 중단됩니다. 삭제 목록에 uname -r 문자열이 포함되어 있다면 현재 실행 중인 커널이 보호되지 않고 있다는 뜻입니다. 이는 발생해서는 안 되는 상황이므로 진행하기 전에 원인을 조사해야 합니다.
목록이 올바르다면 실제로 실행하십시오.
sudo apt autoremove --purge
df -h /boot--purge 옵션은 패키지뿐만 아니라 남아 있는 설정 파일까지 삭제합니다. 추가로 확보되는 공간은 적지만, dpkg --list 파일이 rc 줄로 가득 차는 것을 방지하여 다음 감사 시 가독성을 유지해 줍니다.
그다음 부팅 메뉴가 재구성되었는지 확인하십시오. 커널 패키지를 삭제하면 자동으로 update-grub이 실행되므로, 메뉴는 존재하는 파일만을 참조해야 합니다.
sudo grep -o 'vmlinuz-[^ ]*' /boot/grub/grub.cfg | sort -u
ls -1 /boot/vmlinuz-*첫 번째 출력에 나타난 모든 버전은 두 번째 출력에도 나타나야 합니다. 존재하지 않는 파일을 가리키는 메뉴 항목이 있으면 정상 작동하던 서버가 GRUB 프롬프트에서 멈추게 됩니다. 이는 커널 업데이트 후 부팅되지 않는 VPS로 이어지는 경로 중 하나이며, 여기서 예방하는 것보다 복구 콘솔에서 수정하는 것이 훨씬 어렵습니다.
apt autoremove가 때때로 아무것도 삭제하지 않는 이유
apt autoremove은 자동으로 설치된 패키지, 즉 다른 패키지의 의존성으로 설치된 패키지만 삭제합니다. apt install linux-image-6.8.0-40-generic를 사용하여 직접 설치한 커널은 수동 설치로 표시되므로, 아무리 오래되어도 autoremove가 이를 삭제하지 않습니다.
apt-mark showmanual | grep -E '^linux-'해당 출력에 나타나는 버전이 지정된 커널은 autoremove가 인식하지 못합니다. 본인의 목록에 있는 버전 문자열을 사용하여 직접 삭제하십시오:
sudo apt-mark auto linux-image-6.8.0-40-generic linux-modules-6.8.0-40-generic
sudo apt autoremove --purge --dry-run메타 패키지는 수동 설치 상태로 두십시오. 메타 패키지는 사용자가 직접 요청한 것이므로 수동 설치로 표시되는 것이 정상입니다.
특정 커널을 의도적으로 제거하기
정책에 따라 자동으로 삭제되기를 기다리지 않고 특정 버전을 즉시 제거해야 할 때가 있습니다. 이미지 패키지 이름을 지정하면 apt이 나머지 작업을 처리합니다.
sudo apt purge linux-image-6.8.0-40-genericapt은 작업을 수행하기 전에 제거 목록을 출력합니다. linux-modules-extra-*가 해당 이미지 패키지에 의존하고 있어 동일한 트랜잭션에서 함께 제거되어야 하기 때문입니다. 출력된 목록은 실제 안전 점검 수단이며, 제거하려는 버전과 함께 메타 패키지가 삭제되는지 확인할 수 있는 곳입니다. 예상치 못한 항목이 포함되어 있다면 n으로 응답하십시오. 이후 sudo apt autoremove --purge를 실행하여 더 이상 존재 이유가 없어진 모듈 및 헤더 패키지를 정리하십시오.
실행 중인 커널을 삭제하면 안 되는 이유
커널 파일이 삭제되어도 메모리에 이미 로드된 커널은 계속 실행되므로 처음에는 아무런 문제가 없는 것처럼 보입니다. 문제가 발생하는 지점은 커널이 아직 로드하지 않은 모든 기능입니다. linux-modules-$(uname -r)를 사용하여 삭제하면 /lib/modules/$(uname -r)/이 제거되므로, 이후 모듈을 로드하려고 할 때 실패합니다.
modprobe: FATAL: Module nf_tables not found in directory /lib/modules/6.8.0-64-generic이 시점부터 방화벽 재로드가 실패하며, 부팅 이후 해당 커널이 다루지 않았던 파일 시스템 유형을 마운트하는 작업도 실패합니다. 한편 /boot/vmlinuz-$(uname -r)이 삭제되었으므로 부팅 메뉴는 더 이상 현재 실행 중인 커널을 제공하지 않으며, 다음 재부팅 시 시스템은 다른 상태로 진입하게 됩니다. 서버는 계속 트래픽을 처리하고 있지만 이미 부팅이 불가능한 상태가 된 것입니다. 매번 삭제 목록을 확인하여 uname -r과 대조하십시오.
/boot 파티션이 가득 차서 apt가 전혀 실행되지 않을 때
이 상태가 되면 사용자는 이 페이지를 찾게 됩니다. apt autoremove는 반쯤 설정된 커널 패키지의 설정을 먼저 완료하기 위해 dpkg을 필요로 합니다. 이 과정에서 initramfs를 다시 빌드하는데, 이때 /boot에 공간이 없으면 작업이 실패합니다. 이 루프를 수동으로 한 번 끊어내야 합니다.
uname -r
ls -1 /boot/initrd.img-*uname -r가 출력한 문자열과 일치하지 않는 버전의 initrd를 하나 선택하여 해당 파일 하나만 삭제합니다.
sudo rm /boot/initrd.img-6.8.0-40-generic
sudo apt --fix-broken install
sudo apt autoremove --purge
sudo update-grub각 줄에는 이유가 있습니다. rm은 dpkg가 존재하지 않는 파일을 존재하는 것으로 인식하게 만드는 의도적인 예외 처리입니다. apt --fix-broken install는 initramfs를 위한 공간이 확보되었으므로 실패했던 설정을 완료합니다. 그 후 autoremove --purge은 삭제한 파일의 패키지와 다른 구버전 패키지들을 제거하여 dpkg이 디스크 상태와 다시 동기화되도록 합니다. update-grub은 실제로 존재하는 파일들을 바탕으로 메뉴를 다시 빌드합니다. rm와 update-grub 사이에는 재부팅하지 마십시오. 그 사이에는 메뉴가 방금 삭제한 파일을 가리키고 있을 수 있기 때문입니다. 만약 dpkg이 중단되었다는 오류를 내면, sudo dpkg --configure -a를 실행하여 apt --fix-broken install과 동일한 복구 작업을 수행하십시오.
dnf 시스템에서의 동일한 작업
Fedora나 Rocky Linux와 같은 RHEL 기반 배포판을 사용하는 VPS에서는 메커니즘이 반대로 작동합니다. Debian과 Ubuntu는 apt autoremove 규칙으로 커널을 보호하며 사용자가 직접 정리하거나 unattended-upgrades가 트리거하도록 두지만, dnf은 installonly_limit이라는 개수 제한을 강제하여 새 커널이 설치될 때 제한을 초과하면 가장 오래된 커널을 자동으로 삭제합니다. 현재 적용된 값은 grep installonly_limit /etc/dnf/dnf.conf 및 man 5 dnf.conf 명령으로 확인하고, 기존에 쌓인 커널은 sudo dnf remove --oldinstallonly으로 정리할 수 있습니다. 실행 중인 커널은 해당 시스템에서도 보호됩니다. 두 패키지 관리자 간의 더 자세한 대응 관계는 dnf 및 apt 명령어 대응표를 참조하십시오.
재발 방지
기억에 의존하는 정리 작업은 결국 실패하게 마련이므로, 커널을 설치하는 도구에 해당 설정을 포함해야 합니다. /etc/apt/apt.conf.d/50unattended-upgrades 파일을 열고 다음 키들을 찾으십시오. 배포된 파일에는 이미 주석 처리된 형태로 포함되어 있습니다.
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";파일 끝에 두 번째 복사본을 추가하지 말고, 기존 주석을 해제하십시오. apt 설정에서는 마지막에 할당된 값이 우선하므로, 중복된 설정이 있으면 파일 내부에서 모순이 발생하여 실제 적용되는 값을 파악하기 어렵습니다. 파서가 최종적으로 어떤 값을 인식하는지 확인하고, 아무런 변경 사항이 없는 실행 과정을 지켜보십시오.
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로그가 곧 증거입니다. 로그에는 각 실행 기록이 남으므로, 공간 부족으로 실패한 업그레이드는 시스템이 패치에서 뒤처졌다는 사실을 누군가 알아차리기 훨씬 전에 로그에 나타납니다. 해당 설정의 나머지 부분은 Ubuntu의 자동 보안 업데이트에서 다룹니다.
다음 커널이 배포되기 전에 확인해야 할 수치가 하나 있으며, 이는 이 가이드의 시작 부분에서 사용한 동일한 명령어 쌍입니다.
df -h /boot
ls -lh /boot/initrd.img-$(uname -r)Avail의 용량이 해당 파일보다 충분히 크지 않다면, 다음 커널 설치 시 위에서 설명한 것과 동일한 문제가 발생합니다. 따라서 업그레이드 도중이 아니라 지금 미리 수정하십시오. 이 확인 작업은 다른 VPS 디스크 상태 점검과 함께 1분 정도 투자할 가치가 있습니다. 특히 릴리스 업그레이드 직전에 가장 중요한데, Ubuntu 24.04에서 26.04로 전환하는 과정에서 초기 단계에 새로운 커널을 설치하게 되며, 이때 /boot의 공간이 부족하면 do-release-upgrade은 진행을 거부하기 때문입니다.
FAQ
Ubuntu는 왜 이전 커널을 삭제하지 않고 유지합니까?
부팅에 실패하는 커널이 발생했을 때 선택할 수 있는 다른 대안이 없기 때문입니다. 이전 버전을 유지하면 업데이트가 잘못되었을 때 제공자의 복구 콘솔을 통하지 않고도 GRUB 메뉴에서 복구할 수 있습니다. apt는 따라서 자동 삭제 대상에서 커널 패키지 세트를 보호하며, 여기에는 항상 현재 실행 중인 커널이 포함됩니다. 릴리스마다 정책이 변경되었으므로 apt-config dump | grep -i neverautoremove을 실행하여 현재 릴리스에서 보호하는 정확한 패턴을 확인하십시오.
운영 서버에서 apt autoremove --purge을 실행해도 안전합니까?
네, 먼저 dry run 결과를 확인한다면 안전합니다. 아무것도 삭제하지 않고 목록만 출력하는 sudo apt autoremove --purge --dry-run을 실행하여 결과를 확인하십시오. 만약 목록에 linux-generic나 linux-image-generic 같은 메타 패키지가 포함되어 있다면 중단하십시오. 이를 삭제하면 향후 커널 업데이트가 중단되기 때문입니다. 또한 uname -r이 출력하는 버전 문자열이 포함되어 있어도 중단하십시오. 두 경우 모두 해당하지 않는다면 삭제 대상은 오래된 커널과 고아 의존성 패키지들입니다.
apt autoremove를 실행해도 아무것도 삭제되지 않고 /boot가 여전히 가득 찼습니다. 어떻게 해야 합니까?
오래된 커널들이 수동 설치(manual)로 표시되어 있을 가능성이 높습니다. autoremove는 자동 설치(automatic)로 표시된 패키지만 처리합니다. apt-mark showmanual | grep -E '^linux-'을 실행하십시오. 목록에 나타나는 버전이 지정된 커널은 과거 어느 시점에 수동으로 설치된 것입니다. sudo apt-mark auto linux-image-<version>를 사용하여 해당 커널을 자동 설치로 표시한 뒤 다시 dry run을 수행하거나, sudo apt purge linux-image-<version>를 사용하여 해당 버전을 직접 삭제하십시오.
/boot의 파일을 직접 삭제해도 됩니까?
/boot이 너무 가득 차서 apt이 손상된 커널 패키지를 구성할 수 없는 경우와 같은, 의도적인 일회성 작업일 때만 가능합니다. uname -r의 출력 결과에 포함되지 않은 버전의 initrd.img-<version> 파일을 하나 삭제한 뒤, 즉시 sudo apt --fix-broken install, sudo apt autoremove --purge, sudo update-grub를 실행하십시오. 이러한 후속 조치 없이 파일만 삭제하면 dpkg은 파일이 사라진 패키지를 계속 기록하게 되며, GRUB 메뉴 항목은 존재하지 않는 파일을 가리키게 됩니다. 이 경우 실수를 저지른 시점이 아니라 다음 재부팅 시점에 시스템이 부팅되지 않는 문제가 발생합니다.