ram dump 사용법

운영 서버가 커널 패닉으로 죽으면 그 순간의 메모리 상태를 확인해야 원인을 알 수 있는데, 재부팅이 끝나면 그 상태는 그대로 사라진다. dmesg에 남는 마지막 몇 줄만으로는 콜스택 전체나 락 상태 같은 정보를 볼 수 없다. kdump는 패닉이 발생한 순간 미리 예약해둔 별도의 캡처 커널로 kexec해서 원래 커널의 메모리 전체를 파일(vmcore)로 남기는 메커니즘이다. 이 글에서는 Ubuntu에서 kdump-tools를 설치하고, 실제로 커널 패닉을 유발해 덤프가 남는 과정을 그대로 정리한다.

kdump-tools 설치와 crashkernel 예약

패닉 시 kexec할 캡처 커널이 들어갈 메모리를 부팅 시점에 미리 떼어놔야 하므로, 설치 과정에서 grub 커맨드라인에 crashkernel= 파라미터가 자동으로 추가된다.

$ sudo apt install kdump-tools
$ cat /etc/default/grub.d/kdump-tools.cfg
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT crashkernel=2G-4G:320M,4G-32G:512M,..."

이 파라미터는 재부팅해야 커널 커맨드라인에 반영된다. 재부팅 후 확인한 결과다.

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-7.0.0-28-generic ... crashkernel=2G-4G:320M,4G-32G:512M,...

$ kdump-config show
DUMP_MODE:      kdump
USE_KDUMP:      1
KDUMP_COREDIR:  /var/crash
current state:  ready to kdump
crashkernel suggested size: 284M

덤프 크기·보관 개수 설정

설치 직후 /etc/default/kdump-tools는 최소한의 값만 켜져 있다.

$ grep -v '^#' /etc/default/kdump-tools | grep -v '^$'
USE_KDUMP=1
KDUMP_KERNEL=/var/lib/kdump/vmlinuz
KDUMP_INITRD=/var/lib/kdump/initrd.img
KDUMP_COREDIR="/var/crash"

주석 처리된 나머지 옵션 중 실무에서 자주 건드리는 것들이다.

옵션기본값(주석)설명
MAKEDUMP_ARGS"-c -d 31"-c 압축 저장, -d 31은 0(free)·1(캐시)·2(캐시 프라이빗)·4(유저)·8(free 재확인)·16(zero) 페이지를 모두 제외해 크기를 줄임
KDUMP_NUM_DUMPS공백(무제한)디스크 꽉 차는 것 방지용 보관 개수 제한
KDUMP_COREDIR/var/crashvmcore 저장 경로 — 루트 파티션 여유공간을 고려해 별도 파티션으로 바꾸기도 함

이번 실습에서는 MAKEDUMP_ARGS를 기본값(주석 상태) 그대로 두고도 195MB짜리 vmcore가 남았다. -d 31을 켜서 free/캐시성 페이지까지 제외하면, 실사용 메모리가 훨씬 큰 서버일수록 그만큼 vmcore 크기를 더 줄일 수 있다.

실제 패닉 유발과 덤프 확인

sysrqc 명령으로 즉시 커널 패닉을 일으켰다. 디스포저블 테스트 호스트에서만 실행할 것 — 실행하는 즉시 시스템이 크래시하고 재부팅된다.

$ echo 1 | sudo tee /proc/sys/kernel/sysrq
$ echo c | sudo tee /proc/sysrq-trigger

재부팅 후 /var/crash에 타임스탬프 디렉터리가 생기고 그 안에 vmcore(dump.*)와 dmesg.*가 남아있었다.

$ sudo ls -la /var/crash/202608040015/
-rw------- 1 root whoopsie     61415 dmesg.202608040015
-rw-r--r-- 1 root whoopsie 203555522 dump.202608040015

dmesg.*에는 패닉 직전 콜스택이 그대로 남아 있어, sysrq로 인위적으로 유발했다는 사실과 트리거 경로(write_sysrq_triggersysrq_handle_crashpanic)까지 그대로 보인다.

[   96.262561] sysrq: Trigger a crash
[   96.262568] Kernel panic - not syncing: sysrq triggered crash
[   96.262572] CPU: 2 ... Kdump: loaded Not tainted 7.0.0-28-generic
[   96.262578] Call Trace:
[   96.262593]  panic+0x5f/0x60
[   96.262602]  sysrq_handle_crash+0x1a/0x20
[   96.262606]  __handle_sysrq+0xe5/0x260
[   96.262611]  write_sysrq_trigger+0x62/0x90
[   96.262621]  vfs_write+0x10d/0x480

주의사항

crash 유틸리티로 vmcore를 바로 열면 포맷 문제로 실패할 수 있다.

$ file dump.202608040015
dump.202608040015: Flattened kdump compressed dump v6, ...

$ sudo crash /boot/vmlinuz-7.0.0-28-generic dump.202608040015
crash: /boot/vmlinuz-7.0.0-28-generic: not a supported file format

kdump-tools 기본 설정은 vmcore를 network dump 등에도 그대로 쓸 수 있게 flattened 포맷으로 남기는데, crash나 다른 분석 도구는 이 포맷을 직접 읽지 못한다. makedumpfile -R로 먼저 재조립해야 한다.

$ sudo makedumpfile -R vmcore.reassembled < dump.202608040015
makedumpfile Completed.

$ sudo makedumpfile --dump-dmesg vmcore.reassembled dmesg_extracted.txt
The dmesg log is saved to dmesg_extracted.txt.

재조립한 파일에서 dmesg는 별도 심볼 없이 바로 추출되지만, crash로 스택·자료구조까지 깊이 들여다보려면 실행 중인 커널과 빌드 옵션까지 정확히 일치하는 디버그 심볼(vmlinux-dbgsym)이 따로 필요하다 — 이 환경에는 설치하지 않아 이 부분은 검증하지 못했다. 그 밖에 crashkernel=로 예약한 메모리(이 환경 기준 320M~)는 평상시 시스템이 못 쓰는 영역이므로, 메모리가 빠듯한 서버라면 예약 크기를 신중히 잡아야 한다.

마무리

kdump는 설치와 crashkernel 예약, 재부팅만 해두면 이후 패닉이 나도 재현 없이 그 순간의 전체 메모리를 vmcore로 확보할 수 있다는 점이 핵심이다. vmcore 자체는 남지만 깊이 있는 분석에는 커널 버전에 맞는 디버그 심볼이 따로 필요하다는 점을 미리 감안해두는 게 좋다.

참고

Ubuntu Server - Kernel Crash Dump
kernel.org - kdump 문서

답글 남기기