周五的時候我的伺服器突然核心報錯,連不上 ssh 也 無法重啟。經過了迂迴的各種搶救方案,終於救回了一千多張圖床的的圖片,心有餘悸,記錄一下救援過程,順便折騰了一套新的圖床方案。
▍伺服器救援
這台伺服器大約已經穩定運行了一年半,運行了我許多重要服務,還有我博客圖床的一千多張無備份的圖片通過 Docker Volume 持久化在主機上。
伺服器宕機
其實我至今仍不知道出了什麼問題,早上剛好需要更新伺服器上的我運行的 RSSHub 實例的鏡像版本,於是想著乾脆把所有服務都更新到最新吧,於是一通 docker pull 和 docker-compose 重啟操作,前面的都沒什麼問題,直到最後一個服務突然啟動容器失敗,報了一個類似 not enough space 的錯誤,我心想著可能是下載的鏡像太多了導致磁盤滿了,於是又一通 docker image prune --all、docker volume prune 和 docker system prune 操作,釋放出了接近 10G 的空間,重試,依然不行。
作為一個有且僅有一點伺服器運維經驗的開發來說,我第一反應想到的就是重啟,未曾想,這才是一天噩夢的開始。

沒想到重啟後我的 Uptime Kuma 提醒我所有服務都下線了,也無法再通過 ssh 連上機子了。

於是趕緊登錄到伺服器的線上控制台,發現核心報錯,無法啟動,強制重啟也依然不生效,並且趕緊求援我的 DevOps 朋友們。
拯救數據
STRRL 說應該 rootfs 出現了問題,不過鑑於我的伺服器雲廠商並沒有提供什麼高級啟動等額外的功能,這條路堵住了。但想到我有一年半毫無備份的圖床數據在上面,依然不甘心,於是開始想辦法搶救數據。

研究了一下伺服器的控制台,發現它提供一個大約每周一次的備份,並且可以一鍵將備份轉為快照,最近的一次在 6 月 22 日,還好。我首先想到的是直接通過快照恢復機器,如果是我今天的操作導致了什麼配置問題,那理應一周前的快照是能正常啟動的,於是滿懷信心地等待了十幾分鐘的快照恢復,結果報了同樣的錯誤。依然不死心,把 6 月 15 的備份也恢復了一下,還是不行。
這下意識到了事情的嚴重性,甚至做好了數據全部丟失的最壞打算,同時開始檢索類似情況,最後發現伺服器的快照鏡像是可以下載的。
於是先下載了快照鏡像,得到了一個 .disk 文件,這個文件應該是一個專屬格式,可以通過 Virtual Box 的命令行工具 vboxmanage convertfromraw 來進行格式轉換,但官網下載後發現並不支持 M 晶片的 Mac,於是又在之前的老 19 款 Intel Mac 上安裝並且執行轉換,得到了一個 .vmdk 文件。
轉換完成後將這個 .vmdk 作為一個磁盤掛載到 Virtual Box CentOS 虛擬機上,發現依然報同樣的錯誤。

於是另闢蹊徑,發現 7-Zip 軟體支持常見虛擬機格式的解壓,但客戶端只有 Windows 版本。

雖然按理說可以在 macOS 上使用命令行版本 p7zip 來執行,但我解壓時會報錯,所以又堵住了一條路,想了個曲線救國的方式,通過虛擬機下載了一個 Win11,下載了 7-Zip 軟體直接解壓成功了。
問題又來了,解壓得到的是 1.img、2.img 這樣格式的 Linux 磁盤鏡像文件,macOS 上無法加載,又用 fuse 折騰了一下,還是無法加載。

期間倒也是有好消息,在全網搜羅的時候發現了一個數據恢復軟體 UFS Explorer,嘗試了一下可以正常加載,只是超過 768k 的文件則需要付費,當然沒打算,看到文件確實是可以識讀之後心裡就安心了許多,至少數據還在,剩下都是技術問題了。
STRRL 告訴我 OrbStack 可以啟動一個 Linux Machine,然後可以把這個 img 作為一個 Linux 磁盤掛載上去。
sudo losetup -fP 1.img
mkdir /mnt/bwg
sudo mount /dev/loop0 /mnt/bwg
通過以上命令成功把我的 img 磁盤鏡像掛載到了 OrbStack 的 Ununtu 機器上。

當我看到我的圖片出現在命令行輸出結果時,感動得都快流淚了 。
tar -czvf cheverto_chevereto_images.tar.gz cheverto_chevereto_images/
rsync -acvP ./cheverto_chevereto_images.tar.gz pseudoyu@[yu-mac-studio]:~/Downloads/

緊接著趕緊打個 tar 包,然後通過 rsync 傳到了我本地的 Mac 上,本機解壓後,終於看到了我所有的圖片。
遷移圖床系統至 r2
但由於這一次的遭遇,不再信任伺服器單機部署的圖床穩定性了,花了半天折騰了一套新的免費圖床系統 —— 「從零開始搭建你的免費圖床系統 (Cloudflare R2 WebP Cloud PicGo)」。

至於現有的數據傳到 r2,我則是使用了 rclone 來進行上傳,徹底完成遷移,大功告成!
▍總結
經過這麼一次,我也開始重新考慮了服務部署、數據安全等問題,準備還是將一些重要的數據上雲而不再依賴單機,也繼續把一些服務遷移到 fly.io 、Zeabur 等 serverless 平台。