Skip to content
Published on

Linuxカーネルパラメータチューニングガイド:sysctl + Boot Params、安全な変更とロールバック

Authors
  • Name
    Twitter

はじめに

カーネルパラメータチューニングは、サーバーのパフォーマンスと安定性に直接影響を与える作業である。誤った値一つが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 -pgrub2-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.somaxconn409665535listen()バックログ最大値
net.ipv4.tcp_max_syn_backlog102465535SYNキュー最大サイズ
net.core.rmem_max21299216MB受信ソケットバッファ最大値
net.core.wmem_max21299216MB送信ソケットバッファ最大値
net.ipv4.tcp_congestion_controlcubicbbr輻輳制御アルゴリズム
net.ipv4.tcp_tw_reuse0(2)1TIME_WAITソケットの再利用
net.ipv4.tcp_fin_timeout6015FIN-WAIT-2タイムアウト
net.ipv4.tcp_keepalive_time720060Keepalive開始時間(秒)
net.ipv4.ip_local_port_range32768-609991024-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.swappiness1~510~301
vm.dirty_ratio402040
vm.dirty_background_ratio10510
vm.overcommit_memory001
vm.max_map_count26214465530262144

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-deadlineSATA SSDレイテンシ保証
bfqHDD公平な帯域幅分配
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_space2必須ASLR完全有効化
kernel.dmesg_restrict1推奨一般ユーザーのdmesgアクセス制限
kernel.kptr_restrict2推奨カーネルアドレス漏洩防止
net.ipv4.conf.all.rp_filter1必須IPスプーフィング防止
net.ipv4.conf.all.accept_redirects0必須MITM攻撃防止
net.ipv4.conf.all.log_martians1推奨異常パケット監査
fs.suid_dumpable0必須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=nevernever / always / madviseDBサーバーのTHP無効化
mitigations=autooff / auto / auto,nosmtCPU脆弱性緩和制御
numa_balancing=disabledisable / enableNUMA自動バランシング
isolcpus=2-7CPUリスト特定CPUをスケジューラから隔離
nohz_full=2-7CPUリストTick-lessモード(リアルタイムワークロード)
intel_iommu=onon / offIOMMU有効化(SR-IOV、VFIO)
iommu=ptpt / offIOMMU pass-through
default_hugepagesz=1G2M / 1GデフォルトHuge Pageサイズ
hugepagesz=1G hugepages=16サイズ + 個数1GB Huge Pageの割り当て
crashkernel=256Mサイズkdumpメモリ予約
audit=10 / 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-maxfs.file-max, limits.conf
"Connection refused"(バックログ超過)ss -lnt, netstat -s | grep overflownet.core.somaxconn
TIME_WAIT急増ss -stcp_tw_reuse, tcp_fin_timeout
OOM Kill頻発dmesg | grep -i oom, /proc/meminfovm.swappiness, vm.overcommit_memory
I/O wait高騰iostat -x 1, vmstat 1vm.dirty_ratio, I/Oスケジューラ
"Cannot allocate memory"(mmap)sysctl vm.max_map_countvm.max_map_count
nf_conntrackテーブル飽和dmesg | grep conntrack, sysctl net.netfilter.nf_conntrack_countnf_conntrack_max

まとめ

カーネルパラメータチューニングの核心原則を整理する。

  1. 計測が先、チューニングは後: ボトルネックが確認されていない状態で値を変更しないこと。
  2. 一度に一つずつ: 複数のパラメータを同時に変更すると、効果を分離できない。
  3. 必ずバックアップ: 変更前に現在の値を記録すること。ロールバック経路のない変更は行わないこと。
  4. カナリア適用: 全サーバーに一斉適用せず、1〜2台で先に検証すること。
  5. ドキュメント化: なぜこの値に変更したのか、どのような効果が確認されたのかを記録すること。

適切なチューニングはサーバーパフォーマンスを劇的に改善できるが、不適切なチューニングは障害の直接的な原因となる。常に安全に、段階的に、測定可能な方法でアプローチしよう。