跳到主要內容
節省工具箱Jason Tools
經驗分享

殘留 CephFS 掛載造成 snmpd 無回應

Jason Cheng 發布
殘留 CephFS 掛載造成 snmpd 無回應
本文目錄
  1. 症狀
  2. 追查過程
  3. 處理方式
  4. 正確的 CephFS 刪除步驟
  5. 預防與監控
  6. 結論
  7. 參考資料

某天 LibreNMS 告警,一台 Proxmox VE 節點的 SNMP 沒有回應。登入一看,snmpd 服務還在、網路也通,但 snmpwalk 怎麼打都逾時,重新啟動 snmpd 也卡住不動。

追到最後,原因出乎意料:一個早就刪掉的 CephFS,掛載點還留在節點上。這篇記錄追查過程,以及刪除 CephFS 時的正確步驟。

症狀

  • LibreNMS 顯示該節點 SNMP 無回應,輪詢失敗
  • systemctl status snmpd 顯示服務還在執行
  • snmpwalk -v2c -c your-community 10.10.10.13 逾時
  • systemctl restart snmpd 卡住很久,kill 也殺不掉
  • 同一台節點上 df -h 也會卡住

追查過程

看 snmpd 卡在哪裡

ps -o pid,stat,wchan:32,cmd -C snmpd

STAT 欄位是 D(不可中斷的睡眠),代表程式正在等某個核心操作完成,這種狀態下連 kill -9 都沒有用。

再看它的核心呼叫堆疊:

cat /proc/$(pidof snmpd)/stack
[<0>] wait_generic_request+0x1e/0x140 [libceph]
[<0>] ceph_monc_do_statfs+0xfc/0x130 [libceph]
[<0>] ceph_statfs+0x8c/0x1f0 [ceph]
[<0>] statfs_by_dentry+0x6a/0xb0
[<0>] user_statfs+0x6a/0xe0
[<0>] __do_sys_statfs+0x3d/0x80
[<0>] __x64_sys_statfs+0x16/0x20
[<0>] do_syscall_64+0x7e/0x170
[<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e

由下往上看:

呼叫意義
__x64_sys_statfs、user_statfssnmpd 呼叫了 statfs(),要查某個檔案系統的容量
ceph_statfs這個檔案系統是 CephFS
ceph_monc_do_statfsCeph 核心用戶端向 MON 查詢容量
wait_generic_request一直在等 MON 回應

這就是鐵證:snmpd 沒有掛掉、也不是網路問題,而是被卡在核心的 statfs() 裡。

snmpd 為什麼會去查 CephFS

snmpd 回應 HOST-RESOURCES-MIB 的 hrStorageTable(LibreNMS 用來畫磁碟使用量的資料)時,會對每一個掛載點呼叫 statfs() 取得容量。只要其中一個卡住,而 snmpd 是單一執行緒處理請求,後面所有 SNMP 請求都會被堵住。

df 會卡住也是同樣的原因。

找出有問題的掛載點

findmnt -t ceph
TARGET            SOURCE                                    FSTYPE OPTIONS
/mnt/pve/cephfs1  10.10.10.11,10.10.10.12,10.10.10.13:/      ceph   rw,relatime,name=admin,secret=<hidden>,acl,mds_namespace=cephfs1
/mnt/pve/cephfs2  10.10.10.11,10.10.10.12,10.10.10.13:/      ceph   rw,relatime,name=admin,secret=<hidden>,acl,mds_namespace=cephfs2

cephfs2 是之前測試用、已經刪除的 CephFS,但掛載點還在。對它做 statfs(),Ceph 用戶端會一直等一個不存在的檔案系統回應,永遠等不到。

可以用 timeout 確認,不怕把自己的 Shell 也卡住:

timeout 5 stat -f /mnt/pve/cephfs1 && echo OK
timeout 5 stat -f /mnt/pve/cephfs2 || echo "卡住或失敗"

處理方式

移除儲存設定

先到「資料中心 → 儲存」確認 cephfs2 的儲存項目是否還在,還在的話先移除,否則 PVE 會再自動掛回來:

grep -A6 'cephfs: cephfs2' /etc/pve/storage.cfg
pvesm remove cephfs2

卸載殘留的掛載點

正常的 umount 也會卡住,用 lazy unmount:

umount -l /mnt/pve/cephfs2

-l 會先把掛載點從目錄樹上拆掉,等沒有人在使用時再真正釋放。叢集裡每個節點都要檢查,同樣的掛載點可能每台都有。

重新啟動 snmpd

killall -9 snmpd
systemctl start snmpd

# 確認恢復
snmpwalk -v2c -c your-community localhost hrStorageDescr

卸載之後,卡住的 statfs() 通常會結束,snmpd 就殺得掉了。如果還是一直停在 D 狀態,就只能安排時間重新開機。

正確的 CephFS 刪除步驟

這次的根本原因,是刪除 CephFS 時沒有把 PVE 的儲存設定與掛載點清乾淨。依 Proxmox VE 官方文件,完整的步驟是:

  1. 卸載所有非 PVE 的用戶端,例如 VM 裡掛載的 CephFS
  2. 停用 PVE 裡相關的 CephFS 儲存,避免被自動掛回去
  3. 移除 VM、CT 正在使用的資源,例如放在這個 CephFS 上的 ISO
  4. 在每個節點手動卸載:umount /mnt/pve/<儲存名稱>
  5. 停止或銷毀這個 CephFS 的 MDS,先停 standby 的,避免 standby 被升級為 active
  6. 刪除 CephFS,同時移除儲存設定與底層的儲存集區

第 5、6 步的指令:

# 停止或銷毀 MDS
pveceph stop --service mds.<名稱>
pveceph mds destroy <名稱>

# 刪除 CephFS、儲存設定與儲存集區
pveceph fs destroy <名稱> --remove-storages --remove-pools

pveceph fs destroy 在還有啟用中的儲存項目參照這個 CephFS 時會拒絕執行,這也是一道保護。這次的 cephfs2 應該是在舊版或手動用 ceph fs rm 刪除,才會留下沒清乾淨的掛載。

預防與監控

  • 刪除 CephFS、外部 NFS、iSCSI 這類網路儲存後,到每個節點用 findmnt 確認沒有殘留
  • PVE 節點上的 pvestatd 也會定期查詢所有儲存的容量,殘留的掛載點同樣可能讓它卡住,網頁介面上的儲存圖示會變成灰色問號
  • LibreNMS 對節點的 SNMP 監控,其實也間接幫你監控了「有沒有卡住的掛載點」:SNMP 突然逾時、而網路正常時,可以優先往這個方向查

結論

這次的經驗是:程式卡住時,看 /proc/<pid>/stack 最快。它直接告訴你卡在核心的哪個呼叫,不用一直猜是網路、權限還是程式本身的問題。

另外,任何網路檔案系統的掛載點,只要後端不見了,都可能讓所有對它呼叫 statfs() 的程式一起卡住。刪除儲存時照官方步驟一步一步來,才不會留下這種不定時炸彈。

參考資料

Jason Cheng

Jason Cheng

企業開源技術顧問,專注架構規劃與實務導入

關於作者 →

延伸閱讀