RHEL8でvm.swappinessを1にする際の落とし穴(cgroup継承問題)

インフラ
RHEL 8.6環境において、スワップ使用を極力控えるために vm.swappiness1 に設定する要件があった。RHEL 7時代と同様の手順で設定したところ、想定通りの挙動にならず、調査に時間を要したため記録を残す。

環境

  • OS: Red Hat Enterprise Linux 8.6
  • 目的: 物理メモリ枯渇寸前までスワップを使用しない設定(swappiness=1)の恒久化

直面した問題

当初、/etc/sysctl.d/vm.swappiness = 1 を記述して適用した。sysctl -a で確認すると値は変更されているように見える。

[root@【ホスト名】 ~]# sysctl vm.swappiness
vm.swappiness = 1

しかし、稼働中のプロセス(systemd管理下のサービス)のメモリ設定を確認すると、デフォルト値である 60 が適用されたままとなっていた。

原因:cgroup v1の仕様変更

Red Hatのナレッジ(Solution 6785021)によると、RHEL 8のcgroup v1環境では、グローバルの vm.swappiness を変更しても、systemdなどが作成する各cgroup(コントロールグループ)には設定が継承されない仕様となっている。

このため、カーネルパラメータ側で「強制的に継承させる」ための追加フラグが必要となる。

解決策

以下の2つの対策を実施することで、全プロセスに対して設定を適用できる。

  1. vm.force_cgroup_v2_swappiness = 1 の追加
  2. Tunedによる上書きの無効化

1. sysctl設定ファイルの作成

vm.swappiness に加え、vm.force_cgroup_v2_swappiness を設定する。このパラメータは名前こそ “v2” が付いているが、cgroup v1環境での継承動作を制御するために使用される。

[root@【ホスト名】 ~]# cat < /etc/sysctl.d/99-vm-swappiness.conf
vm.swappiness = 1
vm.force_cgroup_v2_swappiness = 1
EOF

[root@【ホスト名】 ~]# sysctl --system

2. Tuned設定の確認

RHEL 8では tuned サービスがカーネルパラメータを動的に制御している。sysctlで設定しても、tunedのプロファイル適用時や再起動時に値が上書きされる可能性がある。

/etc/tuned/tuned-main.conf を編集し、tunedによるsysctl設定の再適用(上書き)を禁止する。

[root@【ホスト名】 ~]# vi /etc/tuned/tuned-main.conf

# 以下の行を変更(1 -> 0)
reapply_sysctl=0

※補足:特定のtunedプロファイルを使用している場合は、カスタムプロファイルを作成してパラメータを明記する方が行儀が良いが、今回はインフラ要件として一律適用するため、main設定で制御した。

反映確認

設定反映後、任意のプロセスのcgroup設定値を確認する。ここでは systemd-journald を例とする。

[root@【ホスト名】 ~]# pidof systemd-journald
1234
[root@【ホスト名】 ~]# cat /proc/1234/root/sys/fs/cgroup/memory/memory.swappiness
1

上記の値が 1 になっていれば成功である。以前のように 60 のままの場合は、force_cgroup_v2_swappiness が効いていないか、設定読み込みが行われていない。

まとめ

RHEL 8系でスワップ抑制を行う際は、単なるパラメータ変更だけでなく、cgroupへの継承オプションとtunedの干渉を考慮する必要がある。OSのメジャーバージョンアップ時は、枯れたパラメータであっても仕様確認が必須であると再認識した。

コメント

タイトルとURLをコピーしました