はじめに
先日、Linuxサーバーで稼働している BIND(named) が突然応答しなくなる事象が発生しました。
サーバー自体は停止していませんでしたが、DNS問い合わせがタイムアウトし、一時的に名前解決ができない状態になっていました。
調査を進めた結果、BINDそのものに問題があったのではなく、OS側で実行されていた dnfのキャッシュ更新処理(dnf-makecache) が原因で、ディスクI/Oが枯渇していたことが判明しました。
今回は、その調査内容と対処方法を備忘録としてまとめます。
この記事で分かること
- BINDが突然応答しなくなった原因
systemd-journaldの Watchdog Timeout の意味dnf-makecacheがディスクI/Oに与える影響CPUSchedulingPolicy=idleとIOSchedulingClass=idleを使った再発防止方法
動作環境
- OS:AlmaLinux 8(RHEL8系)
- DNSサーバー:BIND(named)
- ログ管理:systemd-journald / rsyslog
- パッケージ管理:dnf
発生した事象
ある日、DNS問い合わせがタイムアウトし、BINDが応答しない状態になりました。
サーバー自体は稼働していましたが、数分後には自動的に復旧しました。
サービスが停止したわけではないため、BINDではなくOS側で何らかのリソース不足が発生している可能性を疑い、ログの調査を行いました。
ログを確認する
/var/log/messages を確認
まずは /var/log/messages を確認します。
less /var/log/messages
該当箇所を見ると、次のようなログが記録されていました。
systemd-journald.service: Watchdog timeout (limit 3min)!
systemd-journald.service: Killing process ... with signal SIGABRT.
Journal stopped
Journal started
dnf: Metadata cache refreshed recently.
server reload successful
ここで注目したポイントは次の3点です。
systemd-journaldが Watchdog Timeout を検知しているsystemd-journaldが SIGABRT により強制終了されている- dnfのキャッシュ更新完了直後にBINDがリロードされている
これだけでは原因は断定できないため、続いて journalctl でも確認します。
journalctl を確認
journalctl --since "2026-07-19 02:00:00"
時系列を見ると、次のような流れになっていました。
02:22 logrotate started
02:24
systemd-journald.service: Watchdog timeout
03:03
dnf: Metadata cache refreshed recently.
Journal started
server reload successful
03:03
logrotate finished
このことから、
- logrotate実行
- dnfによるキャッシュ更新
- systemd-journald停止
- systemd-journald再起動
- BINDリロード
という流れが確認できました。
原因
今回の原因は、
dnf(パッケージ管理)のキャッシュ更新処理によってディスクI/Oが飽和したこと
でした。
RHEL8系(AlmaLinux、Rocky Linuxなど)では、
dnf-makecache.timer
が定期的に実行されます。
この処理ではリポジトリのメタデータを更新するため、大量の小さなファイルを読み書きします。
ストレージ性能に余裕がない環境では、一時的にディスクI/Oが飽和し、他のプロセスがディスクアクセス待ちとなってしまいます。
発生した現象の流れ
今回の障害は、以下のような流れで発生したと考えられます。
① dnf-makecache が起動
定期実行される dnf-makecache.timer によってキャッシュ更新が開始されます。
② ディスクI/Oが急増
大量のメタデータ更新により、ディスクI/Oが急激に増加します。
③ systemd-journald が停止
ログを書き込めなくなり、
Watchdog timeout (limit 3min)
が発生します。
その結果、
SIGABRT
によって systemd-journald が強制終了されます。
④ BINDが応答不能
OS全体がディスクI/O待ちとなるため、BINDも正常に処理できず、DNS問い合わせがタイムアウトします。
⑤ dnf処理終了
Metadata cache refreshed recently.
が出力され、キャッシュ更新が完了します。
⑥ 自動復旧
その後、
- systemd-journald 再起動
- ログ出力再開
- BINDリロード
が実行され、
server reload successful
となり正常状態へ復帰しました。
対処方法
今回実施した対策は、dnf-makecacheの優先度を下げることです。
dnf-makecache の優先度を変更する
まずは Override ファイルを作成します。
sudo systemctl edit dnf-makecache.service
以下を追記します。
[Service]
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
この設定により、
- CPUは空いているときのみ使用
- ディスクI/Oもアイドル時のみ使用
となり、通常業務への影響を抑えることができます。
設定を反映する
sudo systemctl daemon-reload
sudo systemctl restart dnf-makecache.timer
設定が反映されたか確認する
systemctl show dnf-makecache.service | grep -E "CPUSchedulingPolicy|IOSchedulingClass"
期待される結果は以下のとおりです。
IOSchedulingClass=3
CPUSchedulingPolicy=5
IOSchedulingClass=3
Linux内部では 3 = idle を表します。
ディスクI/Oの優先度が最低となり、他のサービスを優先するようになります。
CPUSchedulingPolicy=5
AlmaLinux 8(Kernel 4.18系)では、
5 = SCHED_IDLE
を意味します。
CPU使用率に余裕がある場合のみ実行されるため、サーバー全体への影響を最小限に抑えることができます。
まとめ
今回の障害は、BINDそのものではなく、OS全体のディスクI/O枯渇が原因でした。
ポイントを整理すると次のとおりです。
- BINDの障害ではなくOS全体のリソース不足
dnf-makecache.timerが大量のディスクI/Oを発生systemd-journaldが Watchdog Timeout により強制終了- BINDも巻き込まれて一時的に応答停止
CPUSchedulingPolicy=idleとIOSchedulingClass=idleの設定により、再発防止が期待できる
BINDが突然停止したように見えても、原因はDNSサーバーではなくOS側のリソース競合であるケースもあります。
同様の事象が発生した場合は、BINDのログだけでなく、/var/log/messages や journalctl、ディスクI/Oの状況まで確認することをおすすめします。
今回はここまでです。最後までお読みいただきありがとうございました。