手当たり次第に書くんだ

飽きっぽいのは本能

Ubuntu 26.04 の Cephadm 環境で ceph-common と cephadm の logrotate 定義が競合した事例

Ubuntu 26.04 上に Cephadm で構築した Ceph クラスターで、logrotate.service が終了コード 1 になっていました。原因は、ホスト側の ceph-commoncephadm が、同じ /var/log/ceph/cephadm.log をそれぞれローテーション対象として定義していたことです。

今回発生していたのは、ログローテーション機能そのものの停止ではありません。cephadm.log のローテーションは成功していた一方で、設定競合が残っていたため、logrotate プロセス全体が失敗判定になっていました。個別処理の結果とジョブ全体の終了状態が一致しない事例です。

対象確認結果
cephadm.log のローテーション成功
ceph-common の定義重複エラー
logrotate.service終了コード 1
Ceph クラスターHEALTH_OK

確認した環境

項目内容
OSUbuntu 26.04
Ceph クラスターCeph 20.2.1 Tentacle
ホスト側 ceph-common20.2.0-0ubuntu2
構築方式cephadm
ログ管理systemd-journald、Grafana Alloy、Loki、Grafana
構成管理Ansible

Cephadm 環境では、Ceph daemon はコンテナとして動作します。一方、ホスト OS には Ceph CLI やクライアント機能を利用するための ceph-common がインストールされていました。

そのため、コンテナ内の Ceph とホスト側の ceph-common でバージョン表示が異なる場合があります。今回もクラスター側は Ceph 20.2.1、ホスト側は 20.2.0 でしたが、このバージョン差を競合の直接原因と確定したわけではありません。本記事では、この環境で実際に確認した設定ファイルの組み合わせと挙動を扱います。

ログ集中管理から logrotate の異常を発見した

異常は Ceph のヘルスチェックではなく、ホスト OS のログから発見しました。ログは次の経路で集約しています。

systemd-journald
  -> Grafana Alloy
  -> Loki
  -> Grafana

logrotate.timer から起動された logrotate.service には、次のエラーが記録されていました。

error: ceph-common:1 duplicate log entry for /var/log/ceph/cephadm.log
error: found error in file ceph-common, skipping

systemd 上の状態も失敗となっていました。

Active: failed (Result: exit-code)
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf
status=1/FAILURE

状態確認、該当時間帯のログ、設定解析を順に確認します。

sudo systemctl status logrotate.service --no-pager -l
sudo journalctl -u logrotate.service --since "3 hours ago" --no-pager
sudo logrotate --debug /etc/logrotate.conf

systemctl status でサービス全体の失敗を確認し、journalctllogrotate --debug で原因を cephadm.log の重複定義まで絞り込みました。

原因はワイルドカードと個別パスの重複だった

Cephadm サーバーには、2 つの logrotate 定義が存在していました。

ceph-common 側の定義

/etc/logrotate.d/ceph-common
/var/log/ceph/*.log {
  rotate 7
  daily
  compress
  sharedscripts
  missingok
  notifempty
  su root ceph
}

cephadm 側の定義

/etc/logrotate.d/cephadm
/var/log/ceph/cephadm.log {
  rotate 7
  daily
  compress
  missingok
  notifempty
  su root root
}

対象パスの関係は次のとおりです。

/etc/logrotate.d/ceph-common
  -> /var/log/ceph/*.log
  -> /var/log/ceph/cephadm.log
/etc/logrotate.d/cephadm
  -> /var/log/ceph/cephadm.log

ceph-common のワイルドカードと cephadm の個別指定が、同じ実ファイルへ展開されていました。

エラーメッセージから確定できる範囲

エラーは、重複を検出した設定ファイルとして ceph-common を示しています。この実行結果から確定できるのは次の点です。

  • ceph-common の定義を処理した時点で cephadm.log が重複対象として検出された
  • ceph-common の設定ファイルが正常に処理されなかった
  • 設定エラーが存在したため logrotate 全体が終了コード 1 になった

一方、今回の調査では、/etc/logrotate.d/ 配下の厳密な読み込みログ、サービス実行時の LANGLC_COLLATE、対象バージョンのソート実装を記録していません。そのため、なぜ ceph-common 側で重複が検出されたのかを、ファイル名の並び順やロケールから推測しません。

同様の事象を再調査する場合は、設定変更前に次の出力を保存します。

sudo logrotate --debug /etc/logrotate.conf 2>&1 | grep 'reading config file'
systemctl show logrotate.service -p Environment -p EnvironmentFiles
sudo systemctl cat logrotate.service
sudo systemctl show-environment

ceph-common のワイルドカードが管理する実ファイルを確認した

/etc/logrotate.d/ceph-common を削除する前に、そのワイルドカードが cephadm.log 以外のログを管理していないか確認しました。

sudo find /var/log/ceph -maxdepth 1 -type f -name '*.log' -printf '%f|%s bytes\n' | sort

確認時点で一致したのは次の 1 ファイルだけでした。

cephadm.log|228908 bytes

次のファイルは /var/log/ceph/*.log に一致しません。

/var/log/ceph/cephadm.log.1.gz
/var/log/ceph/cephadm.log.2.gz
/var/log/ceph/<FSID>/ceph-osd.0.log
/var/log/ceph/<FSID>/ceph-volume.log
  • *.log は末尾が .log.1.gz.log.2.gz のファイルに一致しない
  • glob はサブディレクトリを再帰的に検索しない
  • FSID 配下のログはクラスター固有の別定義が管理している
ログ管理する定義
/var/log/ceph/cephadm.log/etc/logrotate.d/cephadm
/var/log/ceph/<FSID>/*.log/etc/logrotate.d/ceph-<FSID>

Ceph 20 Tentacle の公式ドキュメントでは、Cephadm 自身のログがデフォルトで /var/log/ceph/cephadm.log に記録され、ファイル出力を有効にした Ceph daemon のログが /var/log/ceph/<cluster-fsid> に配置されると説明されています。

公式ドキュメントに記載されたクラスタ固有の logrotate 定義は /etc/logrotate.d/ceph.<cluster-fsid> ですが、今回のホストで確認したファイル名は /etc/logrotate.d/ceph-<FSID> でした。区切り文字が異なるため、ファイル名を決め打ちせず、実際の配置を確認します。

sudo grep -RIn '/var/log/ceph' /etc/logrotate.conf /etc/logrotate.d

失敗期間中も cephadm.log はローテーションされていた

logrotate.service が失敗しているという事実だけでは、個々のログが処理されたかどうかは判断できません。状態データベース、ローテーション済みファイル、新旧ログのタイムスタンプを確認しました。

logrotate の状態データベースには次の値が記録されていました。

"/var/log/ceph/cephadm.log" 2026-7-11-0:24:41

時刻を比較しやすい形式へ直すと 2026-07-11 00:24:41 です。ローテーション後には /var/log/ceph/cephadm.log.1.gz が生成されていました。

確認対象
旧ログの最初2026-07-10 00:49:30
旧ログの最後2026-07-11 00:24:30
旧ログの行数18,977 行
状態データベースの処理時刻2026-07-11 00:24:41
新ログの最初2026-07-11 00:25:32

旧ログが cephadm.log.1.gz へ移され、その後、新しい cephadm.log への記録が再開したことを確認できました。

ceph-common definition
  -> duplicate detected
  -> definition skipped
cephadm definition
  -> cephadm.log rotated
logrotate process
  -> exit code 1 because a configuration error remained

実際の影響は日次ジョブの失敗状態だった

Ceph クラスターの状態は正常でした。

sudo ceph health
HEALTH_OK

今回確認した影響は次の範囲です。

  • logrotate.service が毎日 failed になる
  • systemd 上に失敗状態が残る
  • 同じ設定エラーが継続的に通知される
  • ceph-common 側の定義が正常に処理されない
  • 別の logrotate 障害が発生した場合に既知の失敗状態と区別しにくい

一方、Ceph のデータパス停止、クラスターのヘルス異常、cephadm.log のローテーション停止、ログの継続的な肥大化、ログデータの消失は確認されませんでした。緊急復旧ではなく、設定競合を解消し、日次ジョブの終了判定を実際の運用状態へ合わせるための修正です。

採用した対応は競合する定義だけを削除すること

ceph-common パッケージは残し、Cephadm サーバーにある競合定義だけを削除しました。

/etc/logrotate.d/ceph-common

Ansible では次のように期待状態を定義できます。

- name: Remove conflicting ceph-common logrotate definition
  become: true
  ansible.builtin.file:
    path: /etc/logrotate.d/ceph-common
    state: absent

Cephadm サーバーと Ceph クライアントでは配置される定義が異なるため、この処理は Cephadm サーバーへ限定します。

ホストceph-common 定義cephadm 定義競合
Cephadm サーバーありありあり
Ceph クライアントありなしなし

ceph-common パッケージを削除しなかった理由

ceph-common には Ceph CLI とクライアント機能が含まれます。Cephadm サーバーでも次の管理コマンドを使用するため、パッケージそのものは必要です。

ceph health
ceph status
ceph orch host ls
ceph orch ps

不要だったのは、cephadm 専用定義と対象が重複していた logrotate 定義です。修正単位をパッケージ全体から設定ファイルへ絞り、さらにその設定ファイルが管理する実ログを確認しました。

package
  -> configuration file
  -> actual log files matched by the configuration

設定ファイル単位まで絞っても、ワイルドカードがほかの実ログを担当していないか確認しなければ、変更範囲を適切に限定したとは判断できません。

conffile の削除状態を Ansible で管理する

/etc/logrotate.d/ceph-common は dpkg が管理する conffile です。dpkg は、前回のパッケージに含まれた内容、ホスト上の現在の内容、新しいパッケージに含まれる内容を比較し、MD5 ダイジェストを使って変更状態を判定します。

管理者が conffile を削除した場合、その欠落自体がローカル変更として扱われ、通常のアップグレードでは自動的に復元されません。ただし、ホスト再構築、OS イメージからの再展開、purge 後の再インストール、--force-confmiss、手動復元、パッケージ側の管理方式変更では再配置される可能性があります。

Ansible で state: absent を宣言する目的は、通常のパッケージ更新だけへの対策ではありません。ホスト再構築を含めたライフサイクル全体で、Cephadm サーバーの期待状態を再現するためです。

修正後の検証

logrotate の設定解析

sudo logrotate --debug /etc/logrotate.conf
rc=0
duplicate log entry: none

systemd 上の実行結果

sudo systemctl reset-failed logrotate.service
sudo systemctl start logrotate.service
sudo systemctl show logrotate.service -p ActiveState -p SubState -p Result -p ExecMainStatus
ActiveState=inactive
SubState=dead
Result=success
ExecMainStatus=0

logrotate.service は処理後に常駐しないため、成功後の inactive/dead は正常です。成功判定には Result=successExecMainStatus=0 を使用します。

対象ログと定義の網羅性

sudo find /var/log/ceph -type f -name '*.log' -printf '%p\n' | sort
sudo grep -RIn '/var/log/ceph' /etc/logrotate.conf /etc/logrotate.d
ログ修正後の管理定義
/var/log/ceph/cephadm.log/etc/logrotate.d/cephadm
/var/log/ceph/<FSID>/*.log/etc/logrotate.d/ceph-<FSID>

ceph-common の定義を削除した後も、確認対象となった Ceph ログには、それぞれ有効な管理定義が残っていました。

Ceph と Ansible の状態

sudo ceph health
HEALTH_OK

Ansible を 2 回実行し、2 回目が changed=0failed=0 になることも確認しました。

検証対象結果
logrotate の設定解析成功
systemd の実行結果成功
対象ログの網羅性未管理ログなし
Ceph クラスターHEALTH_OK
Ansible の冪等性changed=0

ほかの環境へ適用する時の判断基準

今回のパッケージ構成やファイル名を、すべての Cephadm 環境へそのまま適用することはできません。Ceph リリース、ディストリビューション、パッケージ提供元によって、logrotate 定義やファイル名が異なる可能性があります。

一方、次の調査方法はほかの環境にも適用できます。

  • systemd の終了結果と個別ログの処理結果を分けて確認する
  • ワイルドカードを実ファイルへ展開して対象を確定する
  • 重複定義を削除する前に、ほかのログを管理していないか確認する
  • 修正後にもログと管理定義の対応関係を再確認する
  • パッケージ全体ではなく、競合している設定と責務まで修正単位を絞る
  • 未取得の読み込み順や内部実装をファイル名だけから推測しない

logrotate の調査では、設定ファイルの解析結果、個別ログの処理結果、プロセス全体の終了結果を分けて考えます。これらは常に同じ結果になるとは限りません。

参考情報

まとめ

今回の問題は、ceph-commoncephadm が同じ cephadm.log を管理していたことによる設定競合でした。cephadm.log 自体はローテーションされていましたが、重複エラーが残ったため、logrotate プロセス全体は終了コード 1 になっていました。

対応では、汎用定義が管理する実ログを確認したうえで、ceph-common パッケージを残し、競合する logrotate 定義だけを Cephadm サーバーから削除しました。修正後には、同じログが複数の定義から管理されていないことと、必要なログが未管理になっていないことを両方確認しています。

設定競合の解消では、エラーメッセージを消すだけでは不十分です。二重管理を取り除くことと、管理対象の網羅性を維持することを、変更後の実状態から確認する必要があります。

関連する記事
Ubuntu 26.04 の Cephadm 環境で ceph-common と cephadm の logrotate 定義が競合した事例

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る