RHEL 上級 #2 カーネルチューニング — sysctl、tuned、kdump
#1 ブートプロセス でカーネルがどうメモリに上がるかを見ました。この記事はその次の段階です。ブートが終わったカーネルに対して、ワークロードに合うようパラメータを調整し、ワークロードプロファイルを 1 行で切り替え、万が一カーネルがパニックで死んだときにその時点のメモリダンプを取って事後解析するツールまで 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
3 つのツールの位置づけ #
| ツール | 何を調整するか | 適用タイミング |
|---|---|---|
sysctl | カーネルパラメータ (vm、net、kernel、fs) | ランタイム即時 + ブートごと |
tuned | 事前定義されたワークロードプロファイル (sysctl + cpufreq + io-scheduler 束) | プロファイル適用時に即時 |
kdump | カーネルパニック時点でメモリダンプキャプチャ | パニック発生時点 |
sysctl は 1 行単位で直接触るツール、tuned はその 1 行をワークロード単位で束ねて一度に適用する抽象化、kdump はカーネルが死んだときだけ働くセーフティネットです。3 つを揃えて使うと運用で扱える 1 セットになります。
sysctl — ランタイムカーネルパラメータ #
Linux カーネルは /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 | システム全体のファイルディスクリプタ上限 | 200 万 ~ |
kernel.pid_max | PID 最大値 | コンテナが多い場合 4194304 |
DB ワークロード、Web サーバ、コンテナホストで触るキー束が違います。それぞれの標準束を一度決めて /etc/sysctl.d/ に配ると、新しいマシンを立てるたびにこのファイルだけコピーするやり方で一貫性を保てます。
変更が効かないケース #
- 読み取り専用パラメータ —
kernel.osreleaseのようにブート後は変えられないキー。変更を試みるとpermission denied。 - ブート時にだけ意味のあるパラメータ — 一部の
vm.*はランタイム変更可能ですが、kernel.numa_balancingのような値はブートパラメータで渡さないと意図通り動きません。 - コンテナの中 —
/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 の核心は カーネルを 2 つメモリに置いておく ことです。
- ブート時点で正常カーネルとは別に crash kernel が事前にメモリに展開されます (kexec 機構)
- 正常カーネルがパニックすると、ハードウェアリセットを経ずに、メモリ上に展開された 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 が入っており、一次診断にはそれで足りる場面が多いです。
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) 1 つ見るだけで、どの関数でパニックが起きたかが見えます。深い解析は別の話題ですが、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 |
| 1 ファイルだけ適用 | 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で事後解析。- 3 つの位置 — sysctl は 1 行単位、tuned はワークロード束、kdump はパニックセーフティネット。同一キーが衝突したら片側に統一。
次回はカーネルが順調に動いているマシンで 何が時間を食っているか を覗き込むパフォーマンス分析です。sar、top/htop、iostat、vmstat、perf をどんな場面でどんなシグナルを見て取り出すかを整理します。