Skip to content

Ceph — Monitor (MON) 詳解

核心定位

Ceph Monitor(MON)不是資料平面,而是整個叢集的控制平面與一致性中樞。它負責維護叢集地圖、仲裁成員、處理 CephX 身分驗證,並透過 Paxos 確保多個 Monitor 對關鍵狀態有一致觀點。

相關章節

MON 的角色:叢集狀態管理與 Paxos 一致性

src/mon/Monitor.h 可以看到 Monitor 本身是訊息分派核心:

cpp
// 檔案: ceph/src/mon/Monitor.h
class Monitor : public Dispatcher,
                public AuthClient,
                public AuthServer,
                public md_config_obs_t {

這個繼承結構很直接地反映 MON 的三個責任:

  1. Dispatcher:接收與分派各類 monitor 訊息。
  2. AuthClient / AuthServer:同時參與叢集內部與外部客戶端的驗證流程。
  3. 組態觀察者:能根據執行期設定變動調整行為。

MON 並不保存使用者物件資料,而是保存「誰應該擁有資料、叢集目前健康狀態如何、哪些服務可被信任」這類高價值控制資訊。任何 OSD、MDS、MGR 或 client 想要正確行動,都必須先相信 MON 公布的狀態。

MON 具體保存哪些資料

Ceph 的 Monitor 子系統會維護多種 map 或權限資訊,常見的包括:

名稱用途
MonMap記錄 Monitor 成員、位址、仲裁基礎資訊
OSDMap記錄 OSD 拓撲、up/in 狀態、pool 設定、CRUSH 關聯
CRUSHMap描述資料放置拓撲與故障領域
MDSMap記錄 CephFS 的 MDS rank 與狀態
PGMap彙整 Placement Group 與容量、健康、IO 統計
AuthMap儲存 CephX 實體、金鑰、capabilities

這些結構分散在不同 monitor service 中維護。例如:

  • src/mon/OSDMonitor.h 管理 OSDMap
  • src/mon/MDSMonitor.h 管理 MDSMap
  • src/mon/PGMap.h 定義 PGMap
  • src/mon/AuthMonitor.h 管理驗證與授權狀態
cpp
// 檔案: ceph/src/mon/OSDMonitor.h
class OSDMonitor : public PaxosService,
                   public md_config_obs_t {
  OSDMap osdmap;
  OSDMap::Incremental pending_inc;

這代表 MON 不是一個單一巨大狀態機,而是由多個 PaxosService 各自管理不同類型的叢集真相,再由 Monitor 作為統一入口協調。

Paxos 在 Ceph Monitor 裡的實作方式

src/mon/Paxos.h 中的 Paxos 類別是 MON 一致性機制的核心:

cpp
// 檔案: ceph/src/mon/Paxos.h
class Paxos {
public:
  enum {
    STATE_RECOVERING,
    STATE_ACTIVE,
    STATE_UPDATING,
    STATE_UPDATING_PREVIOUS,
    STATE_WRITING,
    STATE_WRITING_PREVIOUS,
    STATE_REFRESH,
    STATE_SHUTDOWN
  };

Ceph 的 Paxos 實作重點不是教科書式地暴露 prepare / accept 名詞,而是把 Monitor 需要的流程包成可操作的狀態機:

  • Recovering:重新加入 quorum 後先把本地狀態追到最新。
  • Active:目前可服務、可讀取已提交狀態。
  • Updating / Writing:Leader 準備提案、落盤、等待多數確認。
  • Refresh:提交後重新整理本地快取與外部可見狀態。

可以把它簡化成下面的流程:

text
// 檔案: docs-site/ceph/monitor.md
Client / Daemon 更新請求
          |
          v
     Leader MON 收到提案
          |
          v
  對應 PaxosService 產生新版本
          |
          v
 多數 MON 接受並持久化到 MonitorDBStore
          |
          v
      提交 commit 版本
          |
          v
  對外發布新的 map / auth 狀態

觀念釐清

MON 的 Paxos 保護的是控制平面狀態,不是每一筆 object 寫入資料。實際物件資料複寫與恢復主要由 OSD 與 PG 狀態機負責。

選舉邏輯:誰成為新的 Leader

src/mon/Elector.hElector 類別負責處理選舉訊息與本地選舉狀態:

cpp
// 檔案: ceph/src/mon/Elector.h
class Elector : public ElectionOwner, RankProvider {

檔案中的註解已經清楚說明其職責:它維護 ElectionLogic,接收 proposal、ack、victory 等訊息,並決定本節點最後成為:

  • Leader:主導 Paxos 提案與新狀態提交。
  • Peon:追隨 Leader,接受已提交狀態。

handle_proposehandle_ackhandle_victory 這些方法名稱可看出 Ceph 將選舉拆成明確訊息階段。實務上還會搭配:

  • peer feature 檢查
  • quorum feature 相容性驗證
  • ping / timeout 機制
  • 連線品質追蹤(ConnectionTracker

因此選舉不是單純比 rank,而是要同時考慮能否形成合法 quorum節點是否仍可信賴

MonitorDBStore:Monitor 的持久化儲存層

MON 的一致性不能只停在記憶體。src/mon/MonitorDBStore.h 定義了持久化儲存抽象:

cpp
// 檔案: ceph/src/mon/MonitorDBStore.h
class MonitorDBStore
{
  std::string path;
  boost::scoped_ptr<KeyValueDB> db;

這裡的 KeyValueDB 在實際部署中通常由 RocksDB 提供後端,因此可以把 MonitorDBStore 理解成:

  • 上層:Monitor / PaxosService 以 transaction 方式寫入版本狀態
  • 下層:RocksDB 負責 key-value 持久化

同一個檔案裡也能看到 Transactionputeraseerase_range 等操作,表示 MON 會把 map、auth、增量版本等內容以鍵值形式存進本地資料庫。這使得 Monitor 在重啟後能重新載入最後已提交的叢集狀態,而不是從零開始推導。

CephX:客戶端與叢集服務的驗證入口

MON 也是 CephX 驗證的重要控制點。src/auth/cephx/CephxKeyServer.h 可以看到金鑰伺服結構:

cpp
// 檔案: ceph/src/auth/cephx/CephxKeyServer.h
struct KeyServerData {
  version_t version{0};
  std::map<EntityName, EntityAuth> secrets;
  std::map<uint32_t, RotatingSecrets> rotating_secrets;

這裡保存的是:

  • 實體名稱(例如 client、osd、mds、mgr)對應的 secret
  • 各服務類型的 rotating secret
  • 對應 capability(caps)資訊

MON 透過 CephX 提供兩層保護:

  1. 身分驗證:你是誰?
  2. 授權控制:你能存取哪些 pool、哪些 monitor command、哪些 filesystem?

也就是說,client 在真正與 OSD 或 MDS 深度互動前,通常會先從 MON 取得可信任的叢集地圖與驗證結果。

MON 與其他 daemon 的協作關係

text
// 檔案: docs-site/ceph/monitor.md
                +----------------------+
                |   Ceph Monitor MON   |
                | Paxos / Maps / Auth  |
                +----------+-----------+
                           |
        +------------------+------------------+
        |                  |                  |
        v                  v                  v
   OSD 取得 OSDMap     MDS 取得 MDSMap    Client 取得 MonMap
   與 CRUSH 規則        與 CephFS 狀態      與 CephX 授權

MON 的工作像是「發布真相」:

  • OSD 根據 OSDMapCRUSHMap 決定資料位置
  • MDS 根據 MDSMap 決定 rank 角色與故障接手
  • client 根據 map 與 auth 資訊選擇正確目標

只要 MON 無法形成 quorum,整個叢集的控制平面就會失去可更新能力。

實作觀察重點

閱讀原始碼時建議的主線

  1. 先看 Monitor.h 了解總控角色。
  2. 再看 Paxos.hPaxosService 理解一致性框架。
  3. 接著看 OSDMonitor.hMDSMonitor.hAuthMonitor.h 如何把不同 map 套進 Paxos。
  4. 最後看 Elector.hMonitorDBStore.h,理解 leader 選舉與持久化如何支撐整體穩定性。

關鍵原始碼索引

  • ceph/src/mon/Monitor.h:113class Monitor : public Dispatcher
  • ceph/src/mon/Paxos.h:176class Paxos
  • ceph/src/mon/OSDMonitor.h — OSD map 管理
  • ceph/src/mon/Elector.h — 選舉邏輯
  • ceph/src/mon/MonitorDBStore.h — 持久化儲存
  • ceph/src/auth/cephx/CephxKeyServer.h — CephX 驗證資料

MON 的部署與安裝

Bootstrap 階段:第一個 MON 如何建立

執行 cephadm bootstrap 時,流程會自動在第一台主機上建立初始 MON:

bash
# 初始化叢集,指定第一個 MON 的 IP 位址
cephadm bootstrap --mon-ip 192.168.1.10

Bootstrap 完成後,叢集只有一個 MON,此時還不具備高可用能力。

擴增 MON:建立三節點 quorum

實務上建議部署 3 個或 5 個 MON 以形成容錯 quorum。可用 ceph orch 指定數量:

bash
# 讓 cephadm 在合適的 host 上自動部署共 3 個 MON
ceph orch apply mon --placement="count:3"

# 或明確指定哪幾台 host 跑 MON
ceph orch apply mon --placement="host1,host2,host3"

也可以用 YAML spec 宣告式描述:

yaml
# mon-spec.yaml
service_type: mon
placement:
  hosts:
    - node1
    - node2
    - node3
bash
ceph orch apply -i mon-spec.yaml

建議使用奇數個 MON

Paxos quorum 需要超過半數成員存活才能繼續運作。3 個 MON 最多容忍 1 台故障;5 個 MON 最多容忍 2 台故障。

加入主機後再加 MON

在加入新主機後,先確認 cephadm 能管理該主機,再套用 spec:

bash
# 加入新主機
ceph orch host add node2 192.168.1.11

# 確認主機列表
ceph orch host ls

# 套用 MON 擴增
ceph orch apply mon --placement="count:3"

驗證 MON 狀態

bash
# 查看 quorum 狀態,確認幾個 MON 在線且形成 quorum
ceph quorum_status

# 查看整體健康狀態(包含 MON 的 health check)
ceph health detail

# 查看 MON daemon 清單
ceph orch ps --daemon-type mon

# 查看 MON map 與成員資訊
ceph mon dump

如果 quorum 遺失

當少於半數 MON 存活時,叢集控制面(cluster maps、認證更新、指令)都無法繼續運作。維運時請確保 MON 分散在不同主機或 failure domain,避免單台機器故障導致 quorum 喪失。

相關章節

延伸閱讀

基於 Apache 2.0 授權