這是一次 Ceph OSD 無法啟動的處理經驗。一早看到 Ceph 叢集變成 HEALTH_WARN、有一顆 OSD 掉了,直覺以為是硬碟壞了,結果直接讀磁碟完全正常,真正的問題是 SAS 連線瞬斷後,LVM 還抓著舊的裝置編號。
這種問題的麻煩在於錯誤訊息層層包裝:Ceph 說讀不到 label、LVM 說 I/O error、磁碟本身卻沒事。這篇把整個追查過程記錄下來,用外接 SAS JBOD 的朋友可以參考。
環境
| 項目 | 內容 |
|---|---|
| 平台 | Proxmox VE 內建的 Ceph,版本 19.2.3(Squid) |
| 節點 | pve5 |
| 受影響 OSD | osd.12 |
| 磁碟 | SK Hynix 3.84 TB 企業級 SSD |
| 儲存架構 | Dell MD1420 SAS JBOD,透過 HBA 接到節點 |
症狀
ceph -s顯示HEALTH_WARN,1 osds downceph osd tree看到osd.12(host=pve5)是downsystemctl status ceph-osd@12顯示服務反覆重新啟動,最後因Start request repeated too quickly進入failed
追查過程
看 OSD 的記錄
journalctl -u ceph-osd@12 --no-pager -n 100
BlueStore 在多個位置(0x0、0x40000000、0x280000000…)讀取 label 全部回傳 Input/output error,最後報 No valid bdev label found。看起來很像磁碟壞了。
確認底層裝置
ceph-volume lvm list 12
確認 osd.12 的資料放在 LVM 的 LV 上,底層實體裝置是 /dev/sdv。Ceph 用 ceph-volume 建立的 OSD 都是這種架構:實體磁碟 → LVM PV → VG → LV → BlueStore。
直接讀實體磁碟
dd if=/dev/sdv of=/dev/null bs=1M count=1000 iflag=direct
smartctl -a /dev/sdv
直接讀 /dev/sdv 完全正常(約 177 MB/s),SMART 也沒有異常,磁碟本身沒壞。問題在磁碟和 Ceph 之間的某一層。
看 dmesg
dmesg -T | grep -i -E 'sdv|DID_NO_CONNECT|reset' | tail -50
找到關鍵:
sd 8:0:23:0: [sdv] tag#5838 FAILED Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK
I/O error, dev sdv, sector 0 op 0x0:(READ) flags 0x0 phys_seg 32 prio class 2
DID_NO_CONNECT 代表 HBA 送出 SCSI 指令後,SAS 傳輸層回報連不到目標裝置。這不是磁碟回報的錯誤,而是通道層級的連線中斷。
往下看,連線中斷觸發了 bus reset,MD1420 的 SAS expander 重新列舉所有磁碟,sdv 的 SCSI 位址從 8:0:23:0 變成 8:0:24:0,再變成 8:0:25:0。名稱還是 sdv,但裝置編號(major:minor)從 65:48 變成了 65:80。
比對 Device Mapper
LVM 的 LV 是透過 Device Mapper(DM)對應到實體裝置,而 DM 記住的是啟用 VG 當下的 major:minor:
dmsetup table | grep ceph
ls -l /dev/sdv
dmsetup table:0 7501471744 linear 65:48 2048
/dev/sdv :brw-rw---- 1 root disk 65, 80 ...
DM 還指向舊的 65:48,但那個裝置已經不存在了。所以透過 LV 路徑的所有讀寫都是 I/O error,Ceph 當然讀不到 BlueStore label。用 LV 路徑跑 dd 驗證,果然一樣是 I/O error。
根因整理
| 層級 | 發生什麼事 |
|---|---|
| SAS 傳輸層 | 連線瞬斷(DID_NO_CONNECT),觸發 bus reset |
| SCSI | expander 重新列舉,裝置的 major:minor 改變 |
| LVM / DM | DM 對應還指向舊的 major:minor,LV 讀寫全部失敗 |
| Ceph | BlueStore 讀不到 label,OSD 起不來,systemd 重試到上限 |
修復步驟
設定 noout
修復期間先告訴 Ceph 不要因為這顆 OSD 離線就開始搬資料:
ceph osd set noout
重新啟用 VG,更新 DM 對應
# 找出 osd.12 所屬的 VG
ceph-volume lvm list 12 | grep -E 'block device|vg name'
# 停用再啟用 VG,讓 DM 重新抓目前的裝置
vgchange -an ceph-<vg-uuid>
vgchange -ay ceph-<vg-uuid>
# 確認 DM 已經指向新的 major:minor
dmsetup table | grep ceph
dmsetup table 變成 65:80,再用 LV 路徑跑 dd,讀取正常(約 201 MB/s)。
注意:vgchange -an 之前要確認這個 VG 只給這顆 OSD 使用,而且 OSD 已經停止。ceph-volume 建立的 OSD 是一顆 OSD 一個 VG,但如果有把 DB/WAL 放在共用的 VG 上,停用那個 VG 會影響到其他 OSD。
處理裝置權限
這時候啟動 OSD,錯誤從 I/O error 變成了 Permission denied。原因是重新啟用 VG 時新建立的 /dev/dm-11 權限是 root:disk,而 ceph-osd 是以 ceph 使用者執行的。
建議用 ceph-volume 重新啟用 OSD,它會處理權限與連結:
ceph-volume lvm activate 12 <osd-fsid>
<osd-fsid> 可以從 ceph-volume lvm list 12 的 osd fsid 欄位查到。當下我是直接手動改權限:
chown ceph:ceph /dev/dm-11
udevadm trigger /dev/dm-11
手動 chown 只是暫時的,重新開機或下次 VG 重新啟用時就會恢復成 root:disk;ceph-volume lvm activate 才是正規做法。
啟動 OSD
systemctl reset-failed ceph-osd@12
systemctl start ceph-osd@12
# 確認狀態
ceph osd tree | grep osd.12
ceph -s
# 恢復正常後取消 noout
ceph osd unset noout
reset-failed 是必要的,systemd 因為重試太多次把服務鎖住了,不先重設會直接拒絕啟動。
事件時間軸
| 時間 | 事件 |
|---|---|
| 08:33 前 | SAS 連線瞬斷,sdv 出現 DID_NO_CONNECT,觸發 bus reset,SCSI 位址漂移 |
| 08:33:36 | ceph-osd@12 第一次嘗試啟動,讀取 BlueStore label 全部 I/O error |
| 08:33:57 | 第三次嘗試仍失敗 |
| 08:34:08 | systemd 停止重試,服務進入 failed |
| 08:40 | vgchange -an/-ay 更新 DM 對應 |
| 08:41:46 | 重新啟動 OSD,因 Permission denied 失敗 |
| 08:43:04 | 修正裝置權限,osd.12 啟動成功 |
影響範圍
osd.12離線約 10 分鐘,期間叢集是HEALTH_WARN- 相關的 PG 進入 degraded,由其他 OSD 上的副本繼續提供服務
- 其他 OSD 與節點上的 VM/CT 都不受影響,沒有資料遺失
這就是 Ceph 三副本的價值,一顆 OSD 掉了服務照常,可以從容處理。
可能的實體原因與後續
SAS 瞬斷的可能原因,需要到現場檢查:
- HBA 與 MD1420 之間的 SAS 線材鬆動或接觸不良
- MD1420 特定插槽的連接器老化
- SAS expander 或 EMM 模組暫時異常
- HBA 韌體問題造成偶發逾時
- 電源不穩
後續建議:
- 短期
檢查 SAS 線材兩端是否接牢、該插槽有沒有異狀;持續注意 dmesg 是否再出現DID_NO_CONNECT - 中期
用 Wazuh、Graylog 或 LibreNMS 監控 kernel 記錄裡的 SAS/SCSI 錯誤關鍵字,有就告警 - 中期
評估多路徑(multipath):MD1420 有兩個 EMM 模組,兩條 SAS 線都接上並啟用multipathd,一條路徑斷了可以自動切到另一條。注意只有雙埠的 SAS 磁碟才能走多路徑,SATA 磁碟只有單一路徑 - 長期
評估更換線材、更新 HBA 與 MD1420 韌體
結論
這次最大的收穫是:OSD 起不來不一定是磁碟壞了。直接讀實體磁碟是最快的分界點,實體磁碟正常,就往 LVM/DM、權限這些中間層去查。
處理步驟也記一下:noout → vgchange -an/-ay → ceph-volume lvm activate → reset-failed 再啟動 → unset noout。下次再遇到,十分鐘內就能處理完。
參考資料
- Ceph 文件:ceph-volume lvm
https://docs.ceph.com/en/squid/ceph-volume/lvm/ - Ceph 文件:Troubleshooting OSDs
https://docs.ceph.com/en/squid/rados/troubleshooting/troubleshooting-osd/ - Proxmox VE 文件:Deploy Hyper-Converged Ceph Cluster
https://pve.proxmox.com/pve-docs/chapter-pveceph.html - Linux man page:dmsetup(8)
https://man7.org/linux/man-pages/man8/dmsetup.8.html



