ある日、外部からサーバーにSSH接続しようとしたところ、なぜか繋がらない現象が発生しました。
「何も操作していないのになぜ?」と思い、サーバー起動後にログを調べてみたところ、不在の時間帯に勝手にシステムがアップデートされ、再起動がかかっていたことが判明しました。
1. 発生した現象と実際のログ
サーバーのシステムログ(/var/log/messages や journalctl 等)を確認したところ、以下のようなログが記録されていました。
Aug 6 08:48:34 hogehoge systemd[1]: Starting dnf-makecache.service - dnf makecache...
Aug 6 08:48:35 hogehoge dnf[252288]: AlmaLinux 10 - AppStream 6.2 kB/s | 3.8 kB 00:00
Aug 6 08:48:44 hogehoge dnf[252288]: メタデータキャッシュを作成しました。
Aug 6 09:03:35 hogehoge dracut[278695]: Executing: /usr/bin/dracut -f --kernel-image /lib/modules/6.12.0-211.40.1.el10_2.x86_64/vmlinuz --kver 6.12.0-211.40.1.el10_2.x86_64 /boot/initramfs-6.12.0-211.40.1.el10_2.x86_64.img
Aug 6 09:04:03 hogehoge systemd[1]: Stopping sshd.service - OpenSSH server daemon...
Aug 6 09:04:03 hogehoge systemd[1]: Started sshd.service - OpenSSH server daemon.
Aug 6 09:04:09 hogehoge systemd[1]: Starting packagekit.service - PackageKit Daemon...
Aug 6 09:04:09 hogehoge systemd[1]: Started packagekit.service - PackageKit Daemon.
Aug 6 09:05:44 hogehoge systemd-logind[1265]: The system will reboot now!
ログの流れとポイントの解説
上記のログの流れを時系列で解説すると、以下のようになります。
- 08:48 頃:dnf-makecache が作動リポジトリキャッシュの更新が行われ、バックグラウンドでパッケージのアップデート処理が開始されています。
- 09:03 頃:dracut による initramfs の再生成カーネルの更新に伴い、新しい initramfs(initramfs-6.12.0-211.40.1.el10_2.x86_64.img)が生成されています。
- 09:04 頃:PackageKit の起動とサービスの再起動sshd などの主要サービスが一瞬再起動し、直後に PackageKit Daemon が立ち上がっています。
- 09:05 頃:systemd-logind によるリブート命令The system will reboot now! が出力され、OS全体に再起動が命じられています。
一切手動で操作していないにもかかわらず、バックグラウンドでカーネル更新からリブートまでが全自動で完結していました。
2. 勝手に再起動した原因
原因は Cockpit(Web管理画面)と PackageKit による自動更新機能 です。
AlmaLinux や RHEL 系統では、標準で Cockpit や PackageKit がバックグラウンドで動いている場合があります。
これらが有効になっていると、不在時であってもセキュリティアップデート等を自動適用し、「カーネルが更新されたため再起動が必要」 と判断された段階で自動的にシステムをリブートしてしまいます。
3. 対処法:勝手な自動再起動を止める
手動でタイミングを制御したい場合、バックグラウンドでの自動更新・自動再起動を無効化します。
PackageKit の自動更新を無効化する(推奨)
ターミナルから以下のコマンドを実行し、PackageKit サービスを停止・マスク化(完全無効化)します。
systemctl stop packagekit
systemctl mask packagekit
これで、Cockpit などを経由した勝手なバックグラウンド更新や自動リブートを確実に防ぐことができます。(手動での dnf update は問題なく実行可能です)
4. 今後のために:再起動してもログを残す「ログ永続化」設定
今回、再起動時に何が起きていたか詳細を journalctl で追おうとしたところ、以下のエラーが出ました。
Specifying boot ID or boot offset has no effect, no persistent journal was found.
デフォルトでは systemd-journald のログがメモリ上にしか保存されないため、再起動すると過去のログが消えてしまう状態になっていました。
次回以降、障害や予期せぬ再起動が起きた際にもログを追えるよう、ログをディスクに永続保存する設定を行っておきます。
ログ永続化の手順
設定用ディレクトリを作成し、専用の設定ファイルを配置します。
mkdir -p /etc/systemd/journald.conf.d
echo -e "[Journal]\nStorage=persistent" > /etc/systemd/journald.conf.d/persistent.conf
mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
systemctl restart systemd-journald
設定確認
以下のコマンドで /var/log/journal ディレクトリが生成されていれば設定完了です。
ls -ld /var/log/journal
この設定を行っておくことで、次回からはサーバー再起動後も以下のコマンドで前回のログを遡って解析できるようになります。
- journalctl -b -1 (前回の起動時のログを表示)
- journalctl –list-boots (保存されている起動履歴一覧)
まとめ
- 勝手に再起動させたくない場合は
systemctl mask packagekitで停止する - 再起動後の原因追及のために journald のログ永続化(Storage=persistent) をセットでおこなっておく
意図しないタイミングでのサーバーダウンを防ぐためにも、初期構築時にあわせて設定しておくのがおすすめです。