- Authors
- Name
はじめに
カーネルパラメータチューニングは、サーバーのパフォーマンスと安定性に直接影響を与える作業である。誤った値一つがOOM Killを引き起こしたり、ネットワーク接続を切断したり、セキュリティ脆弱性を生み出す可能性がある。
本記事では、sysctl(ランタイムパラメータ)とブートパラメータ(カーネルコマンドライン)を区別し、各項目の意味・推奨値・適用方法を整理し、プロダクション環境での安全な変更手順とロールバック戦略を提示する。
1. カーネルパラメータの2つの経路
| 区分 | sysctl(ランタイム) | Boot Params(ブート時) |
|---|---|---|
| 適用時点 | 即時(再起動不要) | 次回ブート時 |
| 設定ファイル | /etc/sysctl.d/*.conf | /etc/default/grub -> grub.cfg |
| 確認コマンド | sysctl <param> | cat /proc/cmdline |
| 永続化 | sysctl.d + sysctl -p | grub2-mkconfig / update-grub |
| ロールバック | 以前の値を復元 | GRUBの以前のエントリを選択 |
| 範囲 | /proc/sys/ 配下の項目 | カーネルブートオプション全体 |
2. 安全な変更手順(プロダクションプロトコル)
2.1 変更前チェックリスト
#!/usr/bin/env bash
# pre-tuning-check.sh - チューニング前の状態バックアップ
BACKUP_DIR="/root/kernel-tuning-backup/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
# 1. 現在のsysctl全体ダンプ
sysctl -a > "$BACKUP_DIR/sysctl-before.txt" 2>/dev/null
# 2. 現在のブートパラメータ
cat /proc/cmdline > "$BACKUP_DIR/cmdline-before.txt"
# 3. GRUB設定バックアップ
cp /etc/default/grub "$BACKUP_DIR/grub-before"
[[ -d /etc/sysctl.d ]] && cp -r /etc/sysctl.d "$BACKUP_DIR/sysctl.d-before"
# 4. システム状態スナップショット
free -h > "$BACKUP_DIR/memory-before.txt"
ss -s > "$BACKUP_DIR/socket-stats-before.txt"
vmstat 1 5 > "$BACKUP_DIR/vmstat-before.txt"
cat /proc/net/sockstat > "$BACKUP_DIR/sockstat-before.txt"
echo "バックアップ完了: $BACKUP_DIR"
2.2 変更ステップ
1. ステージング環境でテスト
2. カナリアサーバー1台に適用 → モニタリング(最低24時間)
3. 問題なければグループ単位でローリング適用
4. 適用後にメトリクスを比較(before vs after)
2.3 ロールバック手順
# sysctlロールバック - バックアップから特定パラメータを復元
PARAM="net.core.somaxconn"
OLD_VALUE=$(grep "^${PARAM}" /root/kernel-tuning-backup/latest/sysctl-before.txt | awk '{print $3}')
sysctl -w "${PARAM}=${OLD_VALUE}"
# 全sysctlロールバック
while IFS='= ' read -r key value; do
sysctl -w "${key}=${value}" 2>/dev/null
done < /root/kernel-tuning-backup/latest/sysctl-before.txt
# ブートパラメータのロールバック - GRUB以前の設定を復元
cp /root/kernel-tuning-backup/latest/grub-before /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL
# update-grub # Ubuntu
3. ネットワークチューニング
3.1 TCP接続管理
# /etc/sysctl.d/10-network.conf
# TCPバックログ - 高トラフィックサーバーでは必須
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# TCPソケットバッファ(バイト)
# min / default / max
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 262144 16777216
net.ipv4.tcp_wmem = 4096 262144 16777216
# TCP輻輳制御
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# TIME_WAIT管理
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_tw_buckets = 2000000
# Keepalive(ロードバランサー配下のサーバー)
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6
3.2 ネットワークパラメータ一覧表
| パラメータ | デフォルト | 推奨値 | 説明 |
|---|---|---|---|
net.core.somaxconn | 4096 | 65535 | listen()バックログ最大値 |
net.ipv4.tcp_max_syn_backlog | 1024 | 65535 | SYNキュー最大サイズ |
net.core.rmem_max | 212992 | 16MB | 受信ソケットバッファ最大値 |
net.core.wmem_max | 212992 | 16MB | 送信ソケットバッファ最大値 |
net.ipv4.tcp_congestion_control | cubic | bbr | 輻輳制御アルゴリズム |
net.ipv4.tcp_tw_reuse | 0(2) | 1 | TIME_WAITソケットの再利用 |
net.ipv4.tcp_fin_timeout | 60 | 15 | FIN-WAIT-2タイムアウト |
net.ipv4.tcp_keepalive_time | 7200 | 60 | Keepalive開始時間(秒) |
net.ipv4.ip_local_port_range | 32768-60999 | 1024-65535 | アウトバウンドポート範囲 |
3.3 BBRの有効化
# BBRカーネルモジュールのロード
modprobe tcp_bbr
echo "tcp_bbr" >> /etc/modules-load.d/bbr.conf
# sysctl適用
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr
# 確認
sysctl net.ipv4.tcp_congestion_control
# net.ipv4.tcp_congestion_control = bbr
BBR vs CUBIC: BBRはパケットロスベースではなく帯域幅推定ベースの輻輳制御を使用し、特に長距離・高遅延ネットワークでパフォーマンスが大幅に向上する。
4. メモリチューニング
4.1 仮想メモリ管理
# /etc/sysctl.d/20-memory.conf
# Swap使用傾向(0=最小、100=積極的)
# DBサーバー: 1-10、Webサーバー: 10-30
vm.swappiness = 10
# Dirtyページ比率 - ディスク書き込み遅延
vm.dirty_ratio = 40 # 全メモリに対するdirtyページの最大比率
vm.dirty_background_ratio = 10 # バックグラウンドflush開始比率
# OOM関連
vm.overcommit_memory = 0 # 0=デフォルト(ヒューリスティック)、1=常に許可、2=制限
vm.panic_on_oom = 0 # OOM時にパニックするか(0=OOM Killer実行)
# 最大メモリマップ領域(Elasticsearch、MongoDBなど)
vm.max_map_count = 262144
# ファイルシステムキャッシュ解放(緊急時のみ)
# echo 3 > /proc/sys/vm/drop_caches # 1=pagecache, 2=dentries+inodes, 3=all
4.2 メモリパラメータガイド
| パラメータ | DBサーバー | Web/APIサーバー | MLワークロード |
|---|---|---|---|
vm.swappiness | 1~5 | 10~30 | 1 |
vm.dirty_ratio | 40 | 20 | 40 |
vm.dirty_background_ratio | 10 | 5 | 10 |
vm.overcommit_memory | 0 | 0 | 1 |
vm.max_map_count | 262144 | 65530 | 262144 |
4.3 Huge Pages
# Transparent Huge Pages(THP)- DBでは無効化を推奨
# ブートパラメータで設定
# GRUB_CMDLINE_LINUXに追加:
# transparent_hugepage=never
# ランタイムでの確認・変更
cat /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# Static Huge Pages(Oracle DB、DPDKなど)
# /etc/sysctl.d/20-memory.conf
vm.nr_hugepages = 1024 # 2MB * 1024 = 2GB
# 確認
grep -i huge /proc/meminfo
5. ファイルシステム・I/Oチューニング
# /etc/sysctl.d/30-fs.conf
# 最大オープンファイル数(システム全体)
fs.file-max = 2097152
# inotify監視制限(IDE、ファイル監視サービス)
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 8192
# AIO(非同期I/O)最大リクエスト数
fs.aio-max-nr = 1048576
ulimit連携
# /etc/security/limits.d/99-app.conf
# sysctlのfs.file-maxと合わせて設定する必要がある
* soft nofile 1048576
* hard nofile 1048576
* soft nproc 65535
* hard nproc 65535
* soft memlock unlimited
* hard memlock unlimited
I/Oスケジューラ設定
# 現在のスケジューラを確認
cat /sys/block/sda/queue/scheduler
# SSD: noneまたはmq-deadline推奨
echo mq-deadline > /sys/block/sda/queue/scheduler
# 永続設定(udevルール)
# /etc/udev/rules.d/60-scheduler.rules
# ACTION=="add|change", KERNEL=="sd*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
# ACTION=="add|change", KERNEL=="sd*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
| スケジューラ | ディスクタイプ | 特徴 |
|---|---|---|
none (noop) | NVMe SSD | オーバーヘッド最小 |
mq-deadline | SATA SSD | レイテンシ保証 |
bfq | HDD | 公平な帯域幅分配 |
kyber | 高速SSD | 読み書きレイテンシ制御 |
6. セキュリティ関連パラメータ
# /etc/sysctl.d/40-security.conf
# ASLR(Address Space Layout Randomization)
kernel.randomize_va_space = 2 # 0=オフ、1=部分的、2=完全
# SysRq制限(緊急復旧用のみ許可)
kernel.sysrq = 176 # ビットマスク: sync + remount-ro + reboot
# コアダンプ制限
kernel.core_pattern = |/bin/false
fs.suid_dumpable = 0
# dmesgアクセス制限
kernel.dmesg_restrict = 1
# カーネルポインタの非表示
kernel.kptr_restrict = 2
# BPF制限(非特権ユーザー)
kernel.unprivileged_bpf_disabled = 1
# ネットワークセキュリティ
net.ipv4.conf.all.rp_filter = 1 # Reverse Path Filtering
net.ipv4.conf.all.accept_redirects = 0 # ICMPリダイレクト拒否
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0 # ソースルーティング拒否
net.ipv4.conf.all.log_martians = 1 # 不審パケットのログ記録
net.ipv4.icmp_echo_ignore_broadcasts = 1 # Smurf攻撃防御
# IPフォワーディング(ルーター/コンテナホストでなければ無効化)
net.ipv4.ip_forward = 0
# コンテナホストの場合:
# net.ipv4.ip_forward = 1
セキュリティパラメータチェックリスト
| パラメータ | セキュリティ推奨値 | CIS Benchmark | 備考 |
|---|---|---|---|
kernel.randomize_va_space | 2 | 必須 | ASLR完全有効化 |
kernel.dmesg_restrict | 1 | 推奨 | 一般ユーザーのdmesgアクセス制限 |
kernel.kptr_restrict | 2 | 推奨 | カーネルアドレス漏洩防止 |
net.ipv4.conf.all.rp_filter | 1 | 必須 | IPスプーフィング防止 |
net.ipv4.conf.all.accept_redirects | 0 | 必須 | MITM攻撃防止 |
net.ipv4.conf.all.log_martians | 1 | 推奨 | 異常パケット監査 |
fs.suid_dumpable | 0 | 必須 | SUIDコアダンプ防止 |
7. ブートパラメータ(Kernel Command Line)
7.1 設定方法
# 現在のブートパラメータを確認
cat /proc/cmdline
# RHEL / Rocky
vi /etc/default/grub
# GRUB_CMDLINE_LINUX="... 追加するパラメータ"
grub2-mkconfig -o /boot/grub2/grub.cfg
# Ubuntu
vi /etc/default/grub
# GRUB_CMDLINE_LINUX_DEFAULT="... 追加するパラメータ"
update-grub
7.2 主要ブートパラメータ
| パラメータ | 値 | 用途 |
|---|---|---|
transparent_hugepage=never | never / always / madvise | DBサーバーのTHP無効化 |
mitigations=auto | off / auto / auto,nosmt | CPU脆弱性緩和制御 |
numa_balancing=disable | disable / enable | NUMA自動バランシング |
isolcpus=2-7 | CPUリスト | 特定CPUをスケジューラから隔離 |
nohz_full=2-7 | CPUリスト | Tick-lessモード(リアルタイムワークロード) |
intel_iommu=on | on / off | IOMMU有効化(SR-IOV、VFIO) |
iommu=pt | pt / off | IOMMU pass-through |
default_hugepagesz=1G | 2M / 1G | デフォルトHuge Pageサイズ |
hugepagesz=1G hugepages=16 | サイズ + 個数 | 1GB Huge Pageの割り当て |
crashkernel=256M | サイズ | kdumpメモリ予約 |
audit=1 | 0 / 1 | カーネル監査ログ |
7.3 CPU脆弱性緩和 vs パフォーマンス
# 現在適用されている緩和策の一覧を確認
grep -r . /sys/devices/system/cpu/vulnerabilities/ 2>/dev/null
# 緩和策の無効化(ベンチマーク・隔離環境でのみ!)
# GRUB_CMDLINE_LINUXに追加:
# mitigations=off
# パフォーマンスへの影響(ワークロードにより異なる)
# mitigations=auto: システムコール集約ワークロードで5~30%のオーバーヘッド
# mitigations=off: セキュリティリスク - プロダクション非推奨
注意:
mitigations=offはSpectre/Meltdown/MDSなどのセキュリティ緩和をすべて無効化する。隔離されたベンチマーク環境でのみ使用し、プロダクションでは絶対に使用しないこと。
8. ワークロード別チューニングプロファイル
8.1 Webサーバー / APIサーバー
# /etc/sysctl.d/99-web-server.conf
# ネットワーク
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# ファイル
fs.file-max = 2097152
# メモリ
vm.swappiness = 10
8.2 データベースサーバー
# /etc/sysctl.d/99-database.conf
# メモリ
vm.swappiness = 1
vm.dirty_ratio = 40
vm.dirty_background_ratio = 10
vm.overcommit_memory = 0
vm.max_map_count = 262144
# ファイル
fs.file-max = 2097152
fs.aio-max-nr = 1048576
# ネットワーク(内部通信中心)
net.core.somaxconn = 65535
net.ipv4.tcp_keepalive_time = 60
# Huge Pages(PostgreSQL、Oracleなど)
# vm.nr_hugepagesの計算: shared_buffers / 2MB + 若干の余裕
# 例: shared_buffers=8GB → vm.nr_hugepages = 4200
vm.nr_hugepages = 4200
ブートパラメータ:
transparent_hugepage=never
8.3 コンテナホスト(Docker/K8s)
# /etc/sysctl.d/99-container-host.conf
# IPフォワーディング必須
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# ネットワーク
net.core.somaxconn = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.netfilter.nf_conntrack_max = 1048576
# inotify(多数のPod実行時)
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 8192
# PID制限
kernel.pid_max = 4194304
# ファイル
fs.file-max = 2097152
9. 自動化と検証
Ansibleによるsysctl管理
# roles/sysctl/tasks/main.yml
- name: Apply sysctl parameters
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
sysctl_file: /etc/sysctl.d/99-tuning.conf
reload: true
state: present
loop: "{{ sysctl_params | dict2items }}"
# roles/sysctl/defaults/main.yml
sysctl_params:
net.core.somaxconn: 65535
net.ipv4.tcp_max_syn_backlog: 65535
vm.swappiness: 10
fs.file-max: 2097152
適用後の検証スクリプト
#!/usr/bin/env bash
# verify-tuning.sh - チューニング値の検証
declare -A EXPECTED=(
["net.core.somaxconn"]="65535"
["net.ipv4.tcp_congestion_control"]="bbr"
["vm.swappiness"]="10"
["fs.file-max"]="2097152"
)
FAILED=0
for param in "${!EXPECTED[@]}"; do
actual=$(sysctl -n "$param" 2>/dev/null)
expected="${EXPECTED[$param]}"
if [[ "$actual" != "$expected" ]]; then
echo "FAIL: $param = $actual (expected: $expected)"
(( FAILED++ ))
else
echo "OK: $param = $actual"
fi
done
echo "---"
if (( FAILED > 0 )); then
echo "検証失敗: ${FAILED}件"
exit 1
else
echo "すべてのパラメータ検証に合格"
fi
10. トラブルシューティング
| 症状 | 確認コマンド | 関連パラメータ |
|---|---|---|
| "Too many open files" | ulimit -n, sysctl fs.file-max | fs.file-max, limits.conf |
| "Connection refused"(バックログ超過) | ss -lnt, netstat -s | grep overflow | net.core.somaxconn |
| TIME_WAIT急増 | ss -s | tcp_tw_reuse, tcp_fin_timeout |
| OOM Kill頻発 | dmesg | grep -i oom, /proc/meminfo | vm.swappiness, vm.overcommit_memory |
| I/O wait高騰 | iostat -x 1, vmstat 1 | vm.dirty_ratio, I/Oスケジューラ |
| "Cannot allocate memory"(mmap) | sysctl vm.max_map_count | vm.max_map_count |
| nf_conntrackテーブル飽和 | dmesg | grep conntrack, sysctl net.netfilter.nf_conntrack_count | nf_conntrack_max |
まとめ
カーネルパラメータチューニングの核心原則を整理する。
- 計測が先、チューニングは後: ボトルネックが確認されていない状態で値を変更しないこと。
- 一度に一つずつ: 複数のパラメータを同時に変更すると、効果を分離できない。
- 必ずバックアップ: 変更前に現在の値を記録すること。ロールバック経路のない変更は行わないこと。
- カナリア適用: 全サーバーに一斉適用せず、1〜2台で先に検証すること。
- ドキュメント化: なぜこの値に変更したのか、どのような効果が確認されたのかを記録すること。
適切なチューニングはサーバーパフォーマンスを劇的に改善できるが、不適切なチューニングは障害の直接的な原因となる。常に安全に、段階的に、測定可能な方法でアプローチしよう。