PR

BINDが突然応答しなくなった原因を調査|dnf-makecacheによるディスクI/O枯渇が原因だった

スポンサーリンク

はじめに

先日、Linuxサーバーで稼働している BIND(named) が突然応答しなくなる事象が発生しました。

サーバー自体は停止していませんでしたが、DNS問い合わせがタイムアウトし、一時的に名前解決ができない状態になっていました。

調査を進めた結果、BINDそのものに問題があったのではなく、OS側で実行されていた dnfのキャッシュ更新処理(dnf-makecache) が原因で、ディスクI/Oが枯渇していたことが判明しました。

今回は、その調査内容と対処方法を備忘録としてまとめます。

この記事で分かること

  • BINDが突然応答しなくなった原因
  • systemd-journald の Watchdog Timeout の意味
  • dnf-makecache がディスクI/Oに与える影響
  • CPUSchedulingPolicy=idleIOSchedulingClass=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=idleIOSchedulingClass=idle の設定により、再発防止が期待できる

BINDが突然停止したように見えても、原因はDNSサーバーではなくOS側のリソース競合であるケースもあります。

同様の事象が発生した場合は、BINDのログだけでなく、/var/log/messagesjournalctl、ディスクI/Oの状況まで確認することをおすすめします。

今回はここまでです。最後までお読みいただきありがとうございました。