「エンジニア日記」シリーズ。個人の経験に基づくポエムです。
自宅サーバーが、死んだ。
壊れた。
それも、誰かに壊されたわけじゃなく、OSが自分自身を殺す形で。
先に断っておくと、これは本番環境向けのプロのチューニング手法の話ではない。個人で自宅サーバーを運用していて実際にハマった話と、その対策の記録だ。すでに詳しい人からすると「そんなの常識」な内容かもしれないが、知らずにデフォルト設定のまま運用している人は多分自分以外にもいると思う。
何が起きたか
強制停止をかけると、たまに起動しなくなる。
最初は「まあSDカードだしな」くらいに思っていた。でも症状を追っていくと、単純な物理故障とは違う挙動をしていた。安全なシャットダウンシーケンスを踏まずに電源が落ちると、ファイルシステムが壊れた状態のまま次回起動を迎える。そしてOS側の後始末が間に合わず、結果的に自分で自分を壊す形になる。
正直、最初は原因がわからなくて「運が悪かった」くらいの認識だった。何度壊れたかはもう正確には覚えていない。数えるのをやめたくらいには壊れた。
なぜこうなるのか
原因はメモリ管理、特にswapまわりの設定にあった。
デフォルトのままだと、物理メモリがいっぱいになった時の「粘り」が一切ない。メモリが枯渇すると、Linuxカーネルは生き残るためにOOM Killerを発動し、メモリを食っているプロセスを強制的に殺しにいく。運が悪いと、それが原因で書き込み中だったファイルシステムの整合性が崩れる。そこで強制的に電源を落とすと、さらに壊れる。
実際にうちで起きていたのも、これだった。OOM Killerがプロセスを殺した末に、そのままファイルシステムが壊れて起動しなくなる。「OSが自分自身を殺す」というのは比喩でもなんでもなく、文字通りの意味だった。
swapは、この「メモリがいっぱいになった瞬間」の緩衝材になる。防波堤だと思えばいい。波(メモリ消費のスパイク)が来た時に、防波堤が何もなければ町(OS)は直接波を受けて壊れる。防波堤があれば、多少のスパイクは吸収してくれる。
ちなみにswapを使いすぎるとSDカードやSSDの寿命を削るので、そこはvm.swappinessで調整する。物理メモリを優先的に使いつつ、限界が近い時だけswapに逃がす、というバランスの取り方になる。
実際にやった設定
| 設定項目 | 現状 | 推奨値 | 理由 |
|---|---|---|---|
| Swap容量 | 0 | 8GB | 物理メモリと同等量を確保。急激なメモリ消費スパイクを吸収する防波堤になる |
| vm.swappiness | 10 | 10 | 物理メモリを優先使用しつつ、限界が近い時だけswapを使う設定。SD/SSDの寿命を守る |
| vm.vfs_cache_pressure | 50 | 50 | キャッシュをメモリ上に長く保持させ、ディスクI/Oの発生頻度を下げて安定させる |
| vm.overcommit_memory | 0 | 0 | swapがあることが前提の設定。SBC(シングルボードコンピュータ)のような用途ではこれでいいと思う |
| kernel.panic | 0 | 10 | システムがハングした際、10秒後に自動再起動させる設定。遠隔復旧に必須 |
実際に叩いたコマンド
スワップファイルの作成
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 再起動後も有効にするため fstab に追記
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
カーネルパラメータの設定
sudo bash -c "cat <<EOF >> /etc/sysctl.conf
# メモリ管理の最適化
vm.swappiness = 10
vm.vfs_cache_pressure = 50
# フリーズ発生から10秒後に自動再起動
kernel.panic = 10
kernel.panic_on_oops = 1
EOF"
sudo sysctl -p
今どうなってるか
この設定にしてから、今のところ同じ形での自壊は起きていない。今もこの設定のまま運用を続けている。
ただ、これで「絶対壊れない」と言うつもりはない。地味に不安が残っているのは事実で、根本的にはSDカード運用自体がリスクを抱えているという話もある。そのあたりは今回のスコープ外ということにしておく。
余談だが、この一件があってから、自宅の電源タップにだけは変に神経質になった。壊れたのは明らかにソフトウェア側の話なのに、なぜか「電源を触る前に一呼吸置く」という謎の儀式が身についてしまった。因果関係としては多分正しくない。
パリピかよ。
まとめ的なもの
swap 0のままサーバーを運用するのは、防波堤なしで海沿いに住むようなものだと思う。壊れてから気づくタイプの設定なので、他にも似たようなことで自宅サーバーを壊した経験がある人がいたら、それはあなただけではないと思う。
他にも見直すべき設定はあると思うが、今回はこのあたりで。
「エンジニア日記」シリーズでは、こういう個人開発・自宅運用でぶつかった実体験を今後も言語化していきます。もしよければストック・フォローお願いします🙇
一部間違っている可能性があります。優しくコメントしてくれると嬉しいです。
もし良い記事と思ったら、いいね、ストック、フォローお願いします🙇
