前幾天要調整主機上的核心 (kernel) 一個不小心把 /boot 下的各種檔案 (如: initrd.img, system.map…ect) 刪除,導致重新開機後無法進入系統。
簡易的自我檢測方式可至 EC2 後台點選執行個體 (instances) 內,選擇想要的個體中的狀態檢查 (status check) 標籤頁,通常無法進入系統時,可達性 (reachability) 會出現紅字錯誤,可見官方文件 (現在終於有繁中版本了)。
官方文件內有諸多除錯方式,但有個比較快速的方式是獲得主機目前的截圖,即在想要的 EC2 執行個體上按右鍵,點選 Instance Settings 後選 Get Instance Screenshot,即可獲得主機目前執行狀況的截圖。誠如前述,我是因為手賤不小心刪掉目前核心所需要的檔案,所以會出現類似電腦安裝多個作業系統,要你選擇執行哪個的畫面。
於是,參考 Jarrod 去年發表的文章,得知可透過「建立一個與原本相同部署 (deployment) 的執行個體,並用原本系統碟磁區 (volume) 的快照 (snapshot) 來產生另一個系統碟,讓新的個體修復新產生的磁區,以掛回原本的執行個體」的方式來修復。
因為他原本文章就圖文並茂,因此就簡略翻譯各步驟的重點,不附圖。
1. 將 EC2 執行個體關機
在執行個體上按右鍵,選 Instance State -> Stop
2. 建立磁區快照
點選左邊的 ELASTIC BLOCK STORE 樹狀選單下的 Volumes,選擇該執行個體掛載 (mount) 的磁區,原則上如果只有一個執行個體,只會有一個磁區。在該磁區上按右鍵後,點選 Create Snapshot。建立完後,建議可賦予原本的磁區一個名稱,如舊的 old 或損毀的 crashed,避免之後搞混。
3. 由快照建立新的磁區
同樣,在左邊 ELASTIC BLOCK STORE 樹狀選單下,有 Snapshot 選單,點進去後可以看到剛剛建立的快照,在該快照上點右鍵選擇建立磁區 Create Volume,新的磁區會依循原本的磁區建立,無需額外設定,點選 Create 即可。磁區建立會花點時間,同理,也可賦予新的磁區名稱,如新的 new 或修復的 repaired,以避免搞混。
4. 建立新的執行個體
在左邊 INSTANCES 樹狀選單下的 Instances 下,點選 launch Instance,可建立新的執行個體。建議可參考原本執行個體下描述 (description) 標籤頁下的亞馬遜機器鏡像檔 ID (AMI ID) 欄位中的執行個體,這個欄位所示的即是原本 EC2 的系統配置。請注意,當新的執行個體建立完畢後,必須先將它停止,即按右鍵點選 Instance State -> Stop。
5. 把新的磁區附加到新的執行個體
至左邊 ELASTIC BLOCK STORE 樹狀選單內的 Volumes 內,找到新建的磁區按右鍵,點選 Attach Volume 後,在跳出的視窗內的 Instance 中,選擇要掛載的目的執行個體。在此即新建的執行個體,千萬別和舊的搞混了。而裝置 (Device) 欄位顯示的應為 /dev/sdf,這在系統執行後會顯示為 /dev/xvdf,是正常的。
6. 在作業系統中掛載新的磁區
透過 SSH 進入新的執行個體後,輸入
fdisk -l
指令,可以看到剛剛透由舊磁區建立的新磁區,以 /dev/xvdf 的方式掛載到新的執行個體,大小也會是一樣的。
確定無誤後,執行以下指令,在根目錄下建立名為 mount 的資料夾,並把損毀磁區掛載到那個資料夾。
mkdir /mount
mount /dev/xvdf1 /mount
在此可透過 df -h 指令查看原本磁區是否確定掛載,也就是在 Mounted on 欄位中,是否顯示 /mount,若有,則成功。在這個階段,您可以透過更換目錄 cd 指令,前往 /mount 下,看看這個目錄內是不是與您原本的磁區相符。
7. 用 chroot 損毀磁區當成暫時的根目錄
首先把新開的 EC2 執行個體中的 /dev, /dev/shm, /proc 與 /sys 幾個資料夾,掛載到損毀磁區的相對位置
mount -o bind /dev /mount/dev
mount -o bind /dev/shm /mount/dev/shm
mount -o bind /proc /mount/proc
mount -o bind /sys /mount/sys
最後用以下指令,把損毀磁區當成根目錄
chroot /mount
8. 偵錯
再來就要看自己的問題出在哪邊了,使用的指令依照 Linux 系統差異也有所不同。原文作者使用 CentOS,所以他這個階段用了 yum 指令去查看安裝的核心版本,但 ubuntu 與 debian 則要用 dpkg -l | grep linux-image-.*-generic
這個指令去調閱已安裝的核心版本。
我個人的狀況誠如前述,不小心刪掉了 /boot 幾個檔案,便參考這篇文章使用 sudo apt-get install --reinstall linux-image-4.X.Y-ZZ-generic
指令強制重裝所需版本的核心。
等確定沒問題後,就把這個執行個體關機後卸載修復的磁區後,與原本執行個體的損毀磁區交換即可,詳見原文的 9-13步驟。