RHEL 고급 #2 커널 튜닝 — sysctl, tuned, kdump
#1 부팅 프로세스에서 커널이 어떻게 메모리에 올라오는지를 봤습니다. 이번 글은 그다음 단계입니다. 부팅이 끝난 커널이 워크로드에 맞게 동작하도록 파라미터를 조정하고, 워크로드 프로파일을 한 줄로 갈아끼우고, 만에 하나 커널이 패닉으로 죽었을 때 그 시점의 메모리 덤프를 받아서 사후 분석하는 도구까지 한 사이클로 다루겠습니다.
RHEL 고급 시리즈에서 이번 글의 위치:
- #1 부팅 프로세스 — GRUB2, dracut, 복구 모드
- #2 커널 튜닝 — sysctl, tuned, kdump ← 이번 글
- #3 성능 분석 — sar, top/htop, iostat, vmstat, perf
- #4 SELinux 고급 — 정책 작성, audit2allow
- #5 보안 강화 — auditd, OpenSCAP, FIPS
- #6 Subscription / Satellite / Insights
- #7 Cockpit으로 GUI 관리와 web console
세 도구의 쓰임 #
| 도구 | 무엇을 조정하나 | 적용 시점 |
|---|---|---|
sysctl | 커널 파라미터 (vm, net, kernel, fs) | 런타임 즉시 + 부팅마다 |
tuned | 사전 정의된 워크로드 프로파일 (sysctl + cpufreq + io-scheduler 묶음) | 프로파일 적용 시 즉시 |
kdump | 커널 패닉 시점에 메모리 덤프 캡처 | 패닉 발생 시점 |
sysctl은 한 줄 단위로 직접 손대는 도구, tuned는 그 한 줄들을 워크로드 단위로 묶어두고 한 번에 적용하는 추상화, kdump는 커널이 죽었을 때만 일하는 안전망입니다. 셋이 같이 가야 운영에서 손에 잡히는 한 묶음이 됩니다.
sysctl — 런타임 커널 파라미터 #
리눅스 커널은 /proc/sys/ 아래에 자기 파라미터를 파일처럼 노출합니다. sysctl은 그 파일들을 읽고 쓰는 명령입니다.
# 모든 파라미터 보기
$ sudo sysctl -a | less
# 특정 파라미터 읽기
$ sudo sysctl vm.swappiness
vm.swappiness = 30
# 즉시 변경 (재부팅 시 사라짐)
$ sudo sysctl -w vm.swappiness=10vm.swappiness 같은 점 구분 키는 /proc/sys/vm/swappiness의 표기일 뿐입니다.
$ sudo sysctl vm.swappiness
$ cat /proc/sys/vm/swappiness # 같은 값영구 설정 — /etc/sysctl.d/ #
부팅마다 적용하려면 파일에 적어둬야 합니다. RHEL 9의 표준은 /etc/sysctl.d/*.conf 에 모듈식으로 적는 것입니다.
# 메모리/스왑
vm.swappiness = 10
vm.dirty_ratio = 20
vm.dirty_background_ratio = 5
# 네트워크
net.core.somaxconn = 4096
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
# 파일 디스크립터
fs.file-max = 2097152# 특정 파일만
$ sudo sysctl -p /etc/sysctl.d/99-tune.conf
# 표준 위치 전부 (부팅 시 자동으로 일어나는 동작)
$ sudo sysctl --system/etc/sysctl.conf 라는 단일 파일도 호환을 위해 남아 있지만, 운영에선 /etc/sysctl.d/의 분리 파일 이 표준입니다. 변경 출처를 파일명으로 추적하기 쉽고, Ansible/패키지로 한 묶음씩 떨어뜨리기에도 좋습니다.
우선순위와 파일명 규칙 #
sysctl --system은 다음 디렉터리들을 사전식 순서로 읽습니다.
/etc/sysctl.d/*.conf
/run/sysctl.d/*.conf
/usr/lib/sysctl.d/*.conf
/etc/sysctl.conf같은 디렉터리 안에서는 파일명 알파벳 순. 그래서 운영 설정은 보통 99- 접두사를 붙여 마지막에 적용되도록 합니다 (예: 99-tune.conf).
자주 만지는 키 #
운영에서 빈번히 손대는 키 묶음.
| 키 | 의미 | 권장 |
|---|---|---|
vm.swappiness | 페이지 캐시 vs 스왑 선호도 (0=스왑 회피, 100=적극 스왑) | 서버 10, DB 1 ~ 5 |
vm.dirty_ratio | 더티 페이지 한계(%) — 넘으면 동기 flush | 20 |
vm.overcommit_memory | 메모리 오버커밋 정책 | DB/Redis 면 1 |
net.core.somaxconn | listen() 대기열 최대 크기 | 4096 ~ |
net.ipv4.tcp_max_syn_backlog | SYN 대기열 | 4096 ~ |
net.ipv4.ip_local_port_range | ephemeral 포트 범위 | 1024 65535 |
fs.file-max | 시스템 전체 파일 디스크립터 한계 | 2 백만 ~ |
kernel.pid_max | PID 최대값 | 컨테이너 다수 시 4194304 |
DB 워크로드, 웹 서버 워크로드, 컨테이너 호스트가 만지는 키 묶음이 다릅니다. 각각의 표준 묶음을 한 번 잡아두고 /etc/sysctl.d/에 떨어뜨려 두면, 새 머신을 띄울 때마다 이 파일만 복사해두는 식으로 일관성을 잡을 수 있습니다.
변경이 안 먹는 케이스 #
- 읽기 전용 파라미터 —
kernel.osrelease처럼 부팅 후에는 못 바꾸는 키. 변경 시도 시permission denied. - 부팅 시점에만 의미 있는 파라미터 — 일부
vm.*는 런타임 변경 가능하지만,kernel.numa_balancing같은 일부 값은 boot parameter로 줘야 의도대로 동작. - 컨테이너 안에서 —
/proc/sys/의 일부는 컨테이너 namespace가 격리. 호스트에서 바꿔야 효과.
tuned — 워크로드 프로파일 #
tuned는 sysctl 값들 + CPU governor + I/O scheduler + 디스크 readahead 같은 여러 튜닝 항목을 프로파일 한 묶음으로 묶어 한 번에 적용해주는 데몬입니다. RHEL 9에 기본 설치돼 있고 부팅 시점에 자동 시작합니다.
$ sudo systemctl status tuned
$ sudo systemctl enable --now tuned프로파일 보기와 적용 #
# 사용 가능한 프로파일 목록
$ sudo tuned-adm list
Available profiles:
- accelerator-performance
- balanced - General non-specialized tuned profile
- desktop
- hpc-compute
- latency-performance - Optimize for low latency at the cost of throughput
- network-latency
- network-throughput
- powersave
- throughput-performance - Broadly applicable tuning that provides excellent...
- virtual-guest - Optimize for running inside a virtual guest
- virtual-host - Optimize for running KVM guests
Current active profile: throughput-performance
# 현재 프로파일
$ sudo tuned-adm active
# 프로파일 변경
$ sudo tuned-adm profile virtual-guest
# 권장 프로파일 (RHEL이 머신 환경을 보고 추천)
$ sudo tuned-adm recommend
virtual-guesttuned-adm recommend는 베어메탈/가상머신/노트북을 자동으로 구분해서 제안합니다. EC2 같은 가상 인스턴스에서 RHEL을 띄우면 virtual-guest를 추천하는 식입니다.
자주 쓰는 프로파일 #
| 프로파일 | 용도 |
|---|---|
throughput-performance | 일반 서버 기본. CPU governor performance, dirty ratio 완화 |
latency-performance | 응답시간이 첫 번째 — 거래 시스템, 실시간 처리 |
network-latency | latency-performance + 네트워크 큐 튜닝 |
network-throughput | 큰 처리량 네트워크 (10G+ NIC) |
virtual-guest | KVM/AWS/GCP 게스트 기본 |
virtual-host | KVM 호스트 |
powersave | 전력 절약 (노트북 등) |
accelerator-performance | GPU/가속기 워크로드 |
DB가 도는 머신이라면 throughput-performance 또는 latency-performance, 클라우드 게스트라면 virtual-guest를 시작점으로.
프로파일 안에 무엇이 들어 있나 #
$ ls /usr/lib/tuned/throughput-performance/
tuned.conf
$ cat /usr/lib/tuned/throughput-performance/tuned.conf
[main]
summary=...
include=latency-performance
[cpu]
force_latency=cstate.id:3|3
governor=performance
energy_perf_bias=performance
min_perf_pct=100
[disk]
readahead=>4096
[sysctl]
kernel.sched_min_granularity_ns = 10000000
kernel.sched_wakeup_granularity_ns = 15000000
vm.dirty_ratio = 40
vm.dirty_background_ratio = 10
vm.swappiness=10
net.core.busy_read=50
net.core.busy_poll=50
net.ipv4.tcp_fastopen=3[sysctl] 섹션을 보면 결국 sysctl 키들의 묶음입니다. tuned가 적용되는 동안에는 그 키들이 프로파일 값으로 잡혀 있고, 프로파일을 끄거나 다른 프로파일로 갈아끼우면 새 값으로 다시 적용됩니다.
커스텀 프로파일 #
기존 프로파일을 상속해서 일부만 덮어쓰는 게 일반적입니다.
$ sudo mkdir -p /etc/tuned/myapp-throughput
$ sudo vi /etc/tuned/myapp-throughput/tuned.conf[main]
summary=Custom throughput profile for myapp
include=throughput-performance
[sysctl]
net.core.somaxconn = 16384
net.ipv4.tcp_max_syn_backlog = 16384
vm.swappiness = 1
[vm]
transparent_hugepages=never$ sudo tuned-adm profile myapp-throughput
$ sudo tuned-adm active
Current active profile: myapp-throughput/etc/tuned/는 사용자 정의 영역, /usr/lib/tuned/는 패키지가 제공하는 기본 영역. 사용자 정의가 같은 이름으로 있으면 사용자 쪽이 이깁니다.
tuned와 sysctl.d의 관계 #
tuned가 적용한 sysctl 값과 /etc/sysctl.d/에 적은 값이 충돌할 수 있습니다. 우선순위는 단순합니다 — 나중에 적용된 값이 이깁니다. 부팅 순서에서는 보통 tuned가 sysctl --system보다 먼저 도므로 /etc/sysctl.d/가 결국 이깁니다. 다만 tuned-adm profile X를 런타임에 다시 돌리면 그 시점에 프로파일 값이 다시 덮어씁니다.
운영 권장:
- 시스템 전반 정책 —
/etc/sysctl.d/ - 워크로드 묶음 —
tuned프로파일 - 둘이 같은 키를 다루면 한쪽으로 통일. 보통은 tuned 프로파일에 키를 옮기고 sysctl.d에서 빼는 쪽이 깔끔합니다.
kdump — 커널 패닉 시점의 메모리 덤프 #
커널이 패닉으로 죽었을 때 그 시점의 메모리 상태를 덤프 파일(vmcore)로 받아두면, 재부팅 후에 crash 같은 도구로 사후 분석할 수 있습니다. kdump가 그 일을 담당합니다.
어떻게 동작하나 #
kdump의 핵심은 두 개의 커널을 메모리에 띄워두는 것 입니다.
- 부팅 시점에 정상 커널과 별도로 crash kernel 이 미리 메모리에 적재됨 (kexec 메커니즘)
- 정상 커널이 패닉하면 hardware reset 없이 메모리 위에 적재된 crash kernel로 즉시 점프
- crash kernel이 정상 커널의 메모리 영역을 vmcore 파일로 디스크에 기록
- 그 뒤 정상 재부팅
crash kernel 용 메모리는 부팅 시점에 미리 떼어둡니다. 그래서 RAM의 일부(보통 256MB ~ 수 GB)를 평소엔 쓸 수 없게 됩니다. 가벼운 비용은 아니지만, 패닉 분석이 필요한 운영 머신에서는 거의 필수.
활성화 #
RHEL 9는 보통 기본으로 활성화돼 있습니다. 확인:
$ sudo systemctl status kdump
$ sudo kdumpctl status
# 메모리 적재 상황
$ sudo cat /sys/kernel/kexec_crash_loaded
1 # 1이면 적재됨비활성이라면:
$ sudo dnf install -y kexec-tools
$ sudo systemctl enable --now kdumpcrashkernel 파라미터 #
부팅 시점에 떼어둘 메모리를 GRUB의 커널 인자로 지정합니다. RHEL 9는 보통 crashkernel=auto 또는 명시 값을 자동으로 잡아주지만, 워크로드에 따라 손대야 할 때가 있습니다.
$ cat /proc/cmdline
... crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M ...
# 특정 값으로 변경
$ sudo grubby --update-kernel=ALL --args="crashkernel=512M"
$ sudo rebootcrashkernel=512M은 무조건 512MB. crashkernel=1G-4G:192M,4G-64G:256M,...은 RAM 크기에 따라 다른 값을 적용하는 표기. RHEL 9 기본 표기를 그대로 두는 게 보통 안전합니다.
vmcore 저장 위치 #
/etc/kdump.conf에서 vmcore를 어디에 저장할지 정합니다.
# 기본: 로컬 디스크
path /var/crash
core_collector makedumpfile -l --message-level 7 -d 31
# NFS로 보내기
# nfs nfs.example.com:/srv/crash
# SSH로 보내기
# ssh user@dump-server.example.com
# sshkey /root/.ssh/kdump_id_rsa
# 디스크에 떨어뜨리지 못하면 reboot만
# default reboot| 키 | 의미 |
|---|---|
path | vmcore 저장 경로 |
core_collector makedumpfile -d 31 | 덤프에서 빈 페이지/페이지 캐시 등을 제외해 크기 축소 (-d 31 권장) |
nfs / ssh | 원격 저장. 로컬 디스크가 망가졌을 때를 대비 |
default | 덤프 실패 시 동작 (reboot, halt, poweroff, shell, dump_to_rootfs) |
설정 변경 후:
$ sudo kdumpctl rebuild
$ sudo systemctl restart kdump테스트 — 일부러 패닉 일으키기 #
운영 머신에는 절대 시도하지 말고, 분리된 테스트 머신에서만:
$ sudo sysctl -w kernel.sysrq=1
$ echo c | sudo tee /proc/sysrq-trigger머신이 즉시 패닉하면서 vmcore가 /var/crash/<날짜>/vmcore에 떨어집니다. 재부팅 후 확인.
$ ls /var/crash/
127.0.0.1-2026-04-27-10:30:00/
$ ls /var/crash/127.0.0.1-2026-04-27-10:30:00/
vmcore vmcore-dmesg.txtvmcore-dmesg.txt만 봐도 패닉 직전의 dmesg가 들어 있어 1차 진단에 충분한 경우가 많습니다.
crash로 분석 #
$ sudo dnf install -y crash
$ sudo dnf install -y kernel-debuginfo-$(uname -r) --enablerepo=rhel-9-for-x86_64-baseos-debug-rpms
$ sudo crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux \
/var/crash/127.0.0.1-2026-04-27-10:30:00/vmcore
crash> bt # 패닉 시점 스택 트레이스
crash> log # 커널 로그
crash> ps # 프로세스 목록
crash> mod # 적재된 모듈
crash> sys # 시스템 정보bt (backtrace) 한 줄만 봐도 어떤 함수에서 패닉이 일어났는지 보입니다. 깊은 분석은 별개 주제지만, vmcore가 손에 있다는 사실 자체가 운영의 안전망입니다.
흔한 함정 #
sysctl -w만 쓰고 파일에 안 적기 — 재부팅하면 사라집니다. 영구 적용은 반드시/etc/sysctl.d/./etc/sysctl.conf단일 파일에 다 적기 — 변경 출처 추적이 안 됩니다. 모듈별로99-app.conf,99-network.conf식으로 분리 권장.tuned와sysctl.d가 같은 키 충돌 — 마지막에 적용된 값이 이깁니다. 한쪽으로 통일.- kdump 디스크 공간 부족 — vmcore가 수 GB가 될 수 있습니다.
/var/crash가 있는 파일시스템에 여유 공간 확보. kdump.conf변경 후kdumpctl rebuild누락 — 변경이 반영되지 않습니다. 항상 rebuild → restart.crashkernel=인자 제거 — 누가 GRUB 인자를 정리하다가 빼면 다음 부팅부터 kdump가 동작 안 합니다.cat /proc/cmdline으로 정기 확인.- 컨테이너 호스트에서
vm.overcommit_memory=1함부로 — 일부 워크로드에는 OOM 패턴이 바뀝니다. 워크로드별로 검증.
기억해 둘 명령 #
| 작업 | 명령 |
|---|---|
| sysctl 값 보기/일시 변경 | sysctl <key> / sysctl -w <key>=<v> |
| sysctl.d 적용 | sudo sysctl --system |
| 한 파일만 적용 | sudo sysctl -p /etc/sysctl.d/99-tune.conf |
| tuned 활성 프로파일 | sudo tuned-adm active |
| tuned 프로파일 변경 | sudo tuned-adm profile <name> |
| tuned 추천 | sudo tuned-adm recommend |
| kdump 상태 | sudo kdumpctl status |
| crash kernel 적재 확인 | cat /sys/kernel/kexec_crash_loaded |
| kdump 재구성 | sudo kdumpctl rebuild && sudo systemctl restart kdump |
| vmcore 분석 | sudo crash <vmlinux> <vmcore> |
정리 #
sysctl— 런타임 커널 파라미터 조정 +/etc/sysctl.d/*.conf로 영구 분리.99-접두로 마지막 적용 보장.tuned— 워크로드 프로파일 묶음.throughput-performance(서버 기본),virtual-guest(클라우드 게스트), 커스텀은/etc/tuned/에 상속해서 일부만 덮어쓰기.kdump— 커널 패닉 시점 메모리 덤프 캡처. crash kernel 용 메모리를crashkernel=으로 미리 떼어두고, vmcore는/var/crash또는 NFS/SSH로.crash로 사후 분석.- 셋의 쓰임 — sysctl은 한 줄 단위, tuned는 워크로드 묶음, kdump는 패닉 안전망. 동일 키 충돌 시 한쪽으로 통일.
다음 글은 커널이 잘 돌고 있는 머신에서 무엇이 시간을 먹고 있는지 를 들여다보는 성능 분석입니다. sar, top/htop, iostat, vmstat, perf를 어느 상황에서 어떤 신호를 보고 꺼내드는지 정리하겠습니다.