カーネルパラメータをデフォルトのまま運用するか調整するかは、ワークロードの種類と規模によって判断が変わります。汎用的な用途ではデフォルト値で問題が出ないケースが多い一方、高トラフィックWebサービスやデータベース集約型の環境では、調整しないこと自体がボトルネックの原因になります。本記事では、どのワークロードでどのパラメータを変えるべきか、変えると何がどう変わるかを設計判断の観点から整理します。
カーネルデフォルト値で問題が出るワークロードの特徴と見極め方
デフォルト値が「汎用的な妥協点」である理由
Linuxカーネルのデフォルト値は、特定のワークロードに最適化されたものではなく、幅広い用途で「まず動く」ことを優先した設定です。接続数が少なく、メモリも潤沢ではない小規模環境を前提に設計されているため、スループットを最大化したい場合や大量のセッションを同時に捌く必要がある場合には、デフォルト値のままでは能力を発揮できないことがあります。たとえばnet.core.somaxconnのデフォルトは多くのディストリビューションで128〜4096程度に設定されており、同時接続数が数千規模になるアプリケーションではキューが溢れる要因になります。
問題が出やすいワークロードの特徴
デフォルト値で問題が顕在化しやすいのは、いくつかの特性を持つワークロードです。短命なTCPセッションを大量に生成するAPIサーバーやリバースプロキシは、TIME_WAITが大量に残留してポートが枯渇しやすくなります。1台のサーバーが数万本のファイルディスクリプタを保持するような大規模なログ収集・ファイル同期システムでも、デフォルトの上限に引っかかることがあります。また、DBサーバーでは大容量メモリを積んでいるにもかかわらず、vm.swappinessの設定が不適切であればスワップアウトが発生し、レイテンシが急増するケースも珍しくありません。これらはいずれも「デフォルトが悪い」のではなく、「設計されたユースケースと実際の用途が合っていない」状態として捉えるべきです。
見極めのための計測指標
調整が必要かどうかを判断するには、まず現在の状態を計測することが出発点になります。確認すべき指標は、TCPの接続状態(TIME_WAIT数・CLOSE_WAIT数)、ファイルディスクリプタの使用率、スワップの使用量・発生頻度、そしてカーネルが接続を拒否した回数などです。これらの数値が閾値の70〜80%に達している場合は、調整の検討に入るサインと捉えるのが妥当です。一方、計測もせずに「高トラフィックだから調整すべき」と判断して変更を加えるのはアンチパターンです。実測値を根拠に変更範囲を絞り込む姿勢が、副作用を最小限に抑える前提条件になります。
ネットワーク系・メモリ系・ファイルディスクリプタ系のパラメータ比較
ネットワーク系パラメータの選定基準
ネットワーク系のパラメータは、接続の受け付け数・バッファサイズ・TIME_WAITの制御という3つの軸で整理できます。受け付け数に関係するnet.core.somaxconnとnet.ipv4.tcp_max_syn_backlogは、アプリケーション側のlisten設定と合わせて決める必要があります。どちらか一方だけ増やしても、もう一方が低いままであれば実質的な効果は得られません。バッファサイズはスループットの上限に直結し、高レイテンシWAN越しの大容量転送を行う環境では大きく変わります。TIME_WAITの制御(tcp_tw_reuse)は短命セッションを大量生成する構成で有効ですが、NAT環境下での利用は設計上のリスクを伴うため、適用範囲を慎重に確認する必要があります。
メモリ系パラメータの選定基準
メモリ系パラメータで最も影響が大きいのはvm.swappinessです。デフォルト値は60で、これはスワップをある程度積極的に使うことを意味します。DBサーバーやキャッシュサーバーでは、スワップが発生した時点でレイテンシが跳ね上がるため、10以下に設定するのが一般的な設計判断です。ただし0にすると完全にスワップを使わなくなり、OOMキラーが早期に発動しやすくなるというトレードオフがあります。vm.dirty_ratioとvm.dirty_background_ratioは書き込みキャッシュのフラッシュタイミングを制御します。大量書き込みが発生するログサーバーやバックアップサーバーでは、この設定が書き込みの均等化(スパイクの抑制)に影響し、デフォルト値のまま放置すると突然ディスクI/Oが飽和するフラッシュバーストが起きることがあります。
ファイルディスクリプタ系の見落としがちな境界
ファイルディスクリプタの上限には、カーネル全体のシステム上限(fs.file-max)とプロセス単位の上限(nofile)の2段階があります。システム上限だけを上げてもプロセス上限が変わっていなければ、アプリケーションはエラーを出し続けます。逆もまた同様です。NginxやElasticsearchのような多接続を扱うミドルウェアを運用する環境では、システム上限を数十万単位に設定したうえで、プロセス単位の上限も合わせて引き上げるのが正しい順序です。現場では「システム上限は変えたのになぜかエラーが出続ける」という状況が散見されますが、これは2段階の上限を片方だけ変更したことが原因であることが多いです。手順の詳細は実装セミナーに譲りますが、設計上は「2つの上限は必ずセットで変更する」と整理しておく必要があります。
| カテゴリ | 主なパラメータ | 調整が必要な典型的ワークロード | 変更時の注意点 |
|---|---|---|---|
| ネットワーク接続数 | net.core.somaxconn net.ipv4.tcp_max_syn_backlog |
高トラフィックWebサーバー、APIゲートウェイ | アプリ側のlisten値と合わせて設定する |
| ネットワークバッファ | net.core.rmem_max net.core.wmem_max |
広帯域・高レイテンシWAN転送 | 過大設定はメモリ圧迫につながる |
| TIME_WAIT制御 | net.ipv4.tcp_tw_reuse | 短命TCPセッションを大量生成する環境 | NAT環境では副作用が出る場合がある |
| スワップ制御 | vm.swappiness | DBサーバー、インメモリキャッシュ | 0にするとOOM発動タイミングが早まる |
| 書き込みキャッシュ | vm.dirty_ratio vm.dirty_background_ratio |
ログサーバー、バックアップサーバー | 低くしすぎるとI/O頻度が増加する |
| ファイルディスクリプタ | fs.file-max / nofile | 多接続ミドルウェア(Nginx・Elasticsearch等) | システム上限とプロセス上限の両方を変える |
sysctlの設定方式 — 実行時変更と永続化のどちらをいつ使うか
実行時変更の使いどころと限界
sysctlによる実行時変更は、再起動で元に戻ります。これは欠点ではなく、本番環境でパラメータの効果を検証する際の安全弁として機能します。変更の効果を即座に確認できるため、チューニングの試行錯誤フェーズでは実行時変更から始めるのが一般的な判断です。ただし実行時変更だけで運用を続けると、ノード再起動・OSアップデート・インフラの再デプロイのたびにデフォルト値に戻ってしまいます。特に自動スケールするクラウド環境では、新しく起動したノードには変更が適用されず、同じクラスター内でパラメータが混在する状態になります。検証が終わったら永続化に移行することを前提とした手順設計が必要です。
永続化の設計と設定ファイルの分割
/etc/sysctl.confへの直書きは管理しやすい反面、変更履歴が残りにくく、ディストリビューションや他ツールが書き込む設定と競合するリスクがあります。/etc/sysctl.d/配下に用途別のファイルを分割して置くほうが、変更の見通しが良くなります。「99-network-tuning.conf」「99-vm-tuning.conf」のように分けることで、どの設定がどの用途のために変更されたかが明確になります。ファイルの読み込み順序は数字の昇順で決まるため、ディストリビューション側の設定より後に読み込まれるよう90番台以上のプレフィックスを使うのが一般的な設計判断です。IaCでこのファイルを管理すれば、変更履歴はGitに残ります。
設定の競合と上書きリスクを回避する
実行時変更と永続化設定が食い違う状態は、トラブルの原因として見落とされやすいです。OS再起動後に挙動が変わる、特定のノードだけ動作が違う、という現象の背後に、この不整合が隠れているケースは現場で珍しくありません。コンテナランタイムやセキュリティツールが起動時にカーネルパラメータを上書きするケースもあり、設定の競合が起きていないかを定期的に確認する仕組みが必要です。特に複数のチームが同じサーバーを管理する環境では、誰がどのファイルを管理しているかを明文化しておくことが、この種の問題を防ぐ設計として有効です。
パラメータ変更の検証をどこで行うか — 実測基準の設計
「効果あり」と判断する基準の設計
パラメータ変更の効果があったかどうかを「体感」で判断するのはアンチパターンです。変更前後で比較できる計測基準を設計することが先決になります。確認すべきはレイテンシのパーセンタイル値(P95・P99)、スループット(RPS・接続数)、リソース使用率(CPU・メモリ・ディスクI/O)、そしてカーネルが生成するエラーカウンターです。変更前にこれらを取得し、変更後の同条件での計測値と比較することで、効果と副作用を客観的に判断できます。「改善したように見える」ではなく「P99レイテンシが230msから80msに改善した」という水準で記録することが、チームとしての意思決定の品質を上げます。
負荷テスト環境の設計と本番との乖離
検証はステージング環境で行うのが原則ですが、ステージングが本番と同じ規模・トラフィックパターンを再現できていない場合は、チューニングの効果が正確に見えません。本番で20〜30台が稼働しているWebサーバークラスターを、ステージングで2〜3台で再現しても、接続数やセッション数のオーダーが変わるため、同じパラメータで同じ効果が出るとは限りません。この乖離を埋める手法の1つが、本番の一部ノード(カナリアノード)でパラメータを先行適用して計測する方法です。ただし本番カナリアでの変更は、ロールバック手順と監視アラートを準備してから行うことが前提になります。
パラメータ変更適用前の判断チェックリスト
- 変更前の計測値(P95/P99レイテンシ、接続数、スワップ使用量など)を記録したか
- 変更対象のパラメータが問題の根本原因と対応しているかを確認したか(推測ではなく実測に基づく)
- 変更によって影響を受ける可能性のある他のパラメータ・コンポーネントを洗い出したか
- ステージング環境での変更と効果測定を完了したか
- ロールバック手順(実行時変更で即時戻せる状態)を確認したか
- 変更内容を設定ファイルに反映し、IaCリポジトリへのコミット・レビューの段取りを整えたか
- 本番適用後の監視アラートのしきい値を見直したか
クラウドVM・コンテナ・ベアメタルで調整範囲が変わる理由
クラウドVMの制約と注意点
クラウドVMでは多くのカーネルパラメータは変更可能ですが、インスタンスタイプやゲストカーネルのバージョンによって挙動が変わることがあります。特に、ネットワーク帯域やI/Oスループットはハイパーバイザー層のリソース制限が実効上限になるため、カーネルのバッファを増やしても物理的な制約を超えることはできません。クラウドVMでのチューニングは「ソフトウェア上のボトルネックを取り除く」という観点で行うべきで、ハイパーバイザーの制限を無視した過剰なチューニングは意味をなしません。各クラウドプロバイダーが特定のカーネルパラメータについて推奨設定を公開しているケースもあるため、プロバイダーのドキュメントを設計の起点にするのが合理的です。
コンテナ環境の特殊性
コンテナ(Docker・Kubernetes)では、カーネルはホストと共有されます。コンテナ内から読める/proc/sys/配下の値は多くの場合ホストカーネルの設定であり、コンテナごとに独立したカーネルパラメータを持つわけではありません。これはコンテナでのチューニングが「ホストOS側での変更」を意味することになり、特定のコンテナだけを対象としたsysctl変更は同一ホスト上の全コンテナに影響します。Kubernetesでは一部のパラメータをPodのsecurityContextで設定できますが、特権的な設定変更はセキュリティポリシーによって制限されることが多いです。コンテナ環境でのカーネルチューニングは、ホストOS管理者と連携した設計が前提になります。
ベアメタルで初めて自由になるものと責任
ベアメタルサーバーはハイパーバイザー層がない分、カーネルパラメータの変更が直接ハードウェアに作用します。NICのリングバッファサイズやCPUアフィニティの設定、HugePageの有効化など、クラウドVMでは制限されることが多い領域も、ベアメタルでは設計の選択肢に入ります。一方、その分だけ副作用が大きくなる可能性もあります。HugePageを有効化すると仮想メモリの管理が変わるため、対応していないアプリケーションでメモリ確保が失敗することがあります。ベアメタル環境でのチューニングは「調整できる自由の広さ」と「副作用の影響範囲の大きさ」がセットになっているという認識で設計判断を行う必要があります。
変更を誰が管理し、どこにIaCとして残すかの設計
ドリフト防止のための管理設計
カーネルパラメータの変更が手動作業だけで管理されている環境では、時間の経過とともに設定の実態と記録が乖離するドリフトが発生します。構築を任されたある担当者の話では、本番環境10台のうち3台だけパラメータが異なる状態になっており、特定のノードを経由したリクエストだけレスポンスタイムにばらつきが出るという問題が発生していたとのことです。これはドリフトの典型例で、インフラが大きくなるほど手動管理の限界が露呈します。管理の原則は「コードに書かれていないものは存在しないとみなす」であり、カーネルパラメータもIaCの一部として管理対象に含めることが設計として正しい方向です。
AnsibleとTerraformとcloud-initの使い分け
カーネルパラメータのIaC管理には複数の選択肢があります。Ansibleのsysctlモジュールは実行時変更と永続化の両方を担え、既存環境への適用が容易なため、オンプレミスや既存クラウド環境のデイ2オペレーションに向いています。Terraformはプロビジョニング段階でユーザーデータスクリプトとしてsysctl設定を仕込む方法で使われますが、変更後の再適用には別途Ansibleと組み合わせることが多いです。cloud-init(user-data)はクラウドVMの初回起動時に設定を焼き込む用途で有効で、自動スケールするフリートの全ノードに同じ設定を適用したい場合に向いています。使い分けの判断基準は「新規プロビジョニング時か既存への変更適用か」と「ステートレスな管理かステートフルな追跡が必要か」の2軸で整理できます。
レビューと変更履歴の管理設計
カーネルパラメータの変更は、コードレビューと同じフローで管理することが望ましいです。特に本番環境への影響が大きいパラメータ変更では、変更理由・変更前後の値・検証結果をプルリクエストの説明に含めるルールを設けることで、後から見返したときに判断の根拠が残ります。一方で変更の承認フローが重くなりすぎると、チューニングの試行錯誤を妨げる本末転倒になります。ステージング環境のパラメータは軽いフロー、本番環境のパラメータは厳格なレビューというように、環境ごとに承認の重みを変える設計が現実的です。
落とし穴 — パラメータ変更で副作用が出やすい組み合わせ
swappinessとOOMキラーのトレードオフ
vm.swappinessを低く設定(特に0または1)するとスワップを使わなくなり、メモリが逼迫した際にOOMキラーが早期に発動してプロセスを強制終了します。DBサーバーやJVMアプリケーションでは「スワップよりOOM」を選ぶことが多いですが、OOMキラーがどのプロセスを殺すかはoom_score_adjによって制御できます。この設定が不適切なままswappinessだけ下げると、Webサービスの本体プロセスではなくシステムデーモンが先に終了させられるという意図しない動作が起きることがあります。swappinessの変更はoom_score_adjの設計と合わせて行うことが、副作用を抑えるうえで重要な観点です。
接続数系パラメータの連鎖と見落とし
ネットワーク接続数に関わるパラメータは単独では機能せず、複数が連携して上限を決めます。somaxconnとtcp_max_syn_backlogを増やしたにもかかわらず、nf_conntrackのmax値が低いままであれば、コネクショントラッキングテーブルが溢れて新規接続が拒否されます。また、TIME_WAITソケットが大量に残留している場合はポートレンジの制約が効いてきます。これらのパラメータは相互依存しており、1つを変更したあとに別の上限が新たなボトルネックになる「ボトルネックの移動」が起きやすいです。接続数を増やす変更を行う際は、関連するパラメータ群をセットで確認する設計習慣が必要です。
変更後に観測できる問題のパターンと早期検知
副作用を早期に検知するには、変更後の一定期間(最低でも48〜72時間)、通常時よりも細かい粒度でシステムメトリクスを監視する体制を取ることが有効です。副作用として現れやすいパターンとして、スワップ使用量の急増(swappiness変更後)、接続タイムアウトの増加(バッファサイズ変更後)、ファイルシステムのI/Oパターンの急変(dirty_ratio変更後)などがあります。「変更から数日後に問題が出た」というケースでは、変更とその影響が切り離されて原因追跡が困難になります。変更の日時と内容をインフラのイベントログとして記録し、メトリクスのグラフと照合できる状態を維持しておくことが、原因特定の精度を上げるうえで設計として組み込むべき習慣です。
▶ 手を動かして本番まで到達する
その設計判断を、RHEL10の本番環境で手を動かして固めませんか
ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。
最大6名の少人数で、構築実務者の到達点まで引き上げます。座学で終わらせず、本番相当の環境で判断を検証する2日間です。
カーネルパラメータの調整設計を実装で確かめる上級Linuxハンズオンへ →
Linuxセミナー上級編(RHEL10)|最大6名の少人数ハンズオン