只能在建立時決定的設定:支援組合在建立之前讀文件確認、兩條登入路徑各自依賴的元件,以及寫死參數的重送把舊判斷帶進新的一次
論述基礎與限制
這張卡來自 2026-10-25 在 Oracle Cloud ap-batam-1 的一次實測:一台 Always Free 的 A1 Ubuntu 主機放在 private subnet、建立時不放 SSH 公鑰,計畫只靠 Bastion 的 managed SSH session 登入。主機在重送腳本送了 16 次之後建成,接著工作階段三次各約 15 分鐘後逾時;官方〈Known Issues for Bastion〉寫明 A1 加非 Oracle Linux 不支援這種工作階段。改用 Run Command 補公鑰時,plugin 確實執行了指令,而執行指令的 ocarun 沒有 sudo;公鑰欄位在主機建立之後不接受修改。這三個成因各自單獨出現時都有補救,同時出現時主機沒有不經過另一台主機或重建的入口。同一天晚上照本卡當時的檢查(作業系統版本這一層還沒寫進來)重建一台:映像檔換成 Oracle Linux、建立時放自己的公鑰。這台 Oracle Linux 10.2 主機上,代理程式回報的 plugin 清單裡沒有 Bastion,managed SSH session 需要的 plugin 不在(從清單推論,沒有在這台上實際建立工作階段)。Known Issues 只寫到 Arm 主機要跑 Oracle Linux,沒有寫版本;依版本查詢可用 plugin 的 oci instance-agent available-plugins get,在映像的作業系統版本欄位值 10 上回傳少了 Bastion 的 8 項清單。這支工具查不到對應時回傳不分版本的全部 15 項(官方 CLI 參考寫明,實測不存在的版本與作業系統名稱都是同一份),而 9、8 回傳的也正好是這一份,所以 9 與 8 有沒有 Bastion 從它分不出來。建立時放的公鑰讓不經過 plugin 的 port forwarding session 登入成功:managed SSH session 的前提不成立時,用自己公鑰的那條路徑接手。卡上的量測只有這兩台、只在 Oracle Cloud;推廣到其他平台的部分,是從 Oracle Cloud、Google Cloud 與 AWS 的官方文件推出的,沒有在 Google Cloud 與 AWS 上重演。
核心原則
只能在建立時決定的設定,判斷要在建立之前做完,因為之後發現選錯,補救要重建整個資源,資源稀缺時還要加上再取得一次。 這一條拆成三件可以在建立之前查的事(支援組合、兩條登入路徑的元件、資源稀缺時的取捨),加上寫死參數的重送這一個會讓判斷過期的結構。
支援組合要讀文件確認,不能從元件狀態推。 一台主機的登入路徑由幾個業者服務串成,每個服務只在一部分機型與作業系統上成立,而這份範圍寫在服務自己的支援清單、Known Issues 與前置條件裡,不寫在建立頁上:建立頁讓任何映像檔配任何相容架構的機型,建立會成功。主機建好之後,元件的狀態顯示 RUNNING,看起來像是支援的證據;狀態描述的是元件啟動了,支援清單描述的是這個組合能不能完成登入,在不支援的組合上,前者成立、後者不成立。用另一個比較容易建的機型演練也一樣驗不出來:演練只驗得到演練與正式環境相同的那些條件,而機型正是要驗的條件。文件的粒度也要對到這次的設定:Known Issues 寫到作業系統為止時,同一個作業系統的不同版本提供的元件仍然可能不同,業者有依版本查詢的工具時,要用映像的作業系統版本欄位的值查(工具接受的格式跟映像名稱裡的版本號不一定相同)。依版本查詢的工具查不到對應時,可能回傳不分版本的全部項目而不是報錯,一個打錯的版本號看起來就跟有支援一樣。所以第一次用這支工具時,先用同一個作業系統名稱、明顯不存在的版本查一次當對照:查到的清單跟對照的項目不同,才算查到這個版本的資料;跟對照相同時分不出是這個版本提供全部,還是工具沒有它的資料,這時要改從別處確認(逐版本列出的文件,或建起來看主機回報的元件清單),結果在確認之前不寫成支援。查到的資料也只回答這個版本有沒有提供那個元件:同一次實測裡 Ubuntu 24.04 查得到有 Bastion plugin,而 A1 加 Ubuntu 是 Known Issues 排除的組合,版本這一層與機型加作業系統那一層都通過才算支援。
登入路徑要有兩條,最沒有把握的那個元件只出現在其中一條上。 只有一條路徑時,那條路徑上任何一個元件失效,資源就沒有入口;兩條路徑共用的元件失效時,兩條一起斷。這個代價在重建昂貴時才成立(資源上有狀態、容量難取得、第一次用這個組合);資源不存狀態、重建便宜時,重建本身就是備用路徑。所以要把兩條各自依賴的元件逐項列出來,而且要把整條路徑走完:Oracle Cloud 的 managed SSH session 名字裡只有 Bastion,plugin 做的是把公鑰臨時放進 authorized_keys,登入照樣經過主機的 sshd,所以它跟用自己公鑰的 port forwarding session 共用 Bastion、22 port 規則與 sshd,這一組擋得住 plugin 與支援範圍出錯,擋不住 sshd 改壞。不經過 sshd 的是序列主控台加設了密碼的救援帳號。兩條都要在停用其他入口之前各自實際登入過。「不放公鑰比較安全」在這裡要算淨值:主機沒有公開 IP 時,網路這一層已經擋住外部的連線,多一把公鑰增加的暴露很小,拿掉的卻正是那條不依賴代理程式的路徑。
資源稀缺時,設定選補救代價低的那一種。 建錯的代價是重建;資源要搶時(免費額度的熱門機型、GPU),重建還要再搶一次。這時最嚴格的設定(不放金鑰、只靠代理程式)裡跟機型無關的部分放到容易重建的資源上驗,跟機型有關的支援範圍仍要讀文件確認;稀缺的那一台選支援完整、有兩條路徑的組合。查不到任何一個確定支援的版本時(這次的 A1 加 Oracle Linux:10 確定沒有,9、8 分不出),條件改成兩條路徑裡至少一條不依賴那個未確認的元件,例如建立時放公鑰、走不經過代理程式的工作階段,建好之後再確認那個元件在不在。
寫死參數的重送,把寫的那一刻的判斷帶進建成的那一刻。 搶資源的重送腳本把建立參數寫在腳本裡,從寫好到建成可能隔了一天。這段時間裡查到的新資訊不會自己進到腳本:這次的實測裡,本站的概念文章在 2026-10-24 晚上就寫著 Run Command 要事先替 ocarun 設 sudo、第一次建主機先放公鑰比較保險,而 2026-10-25 的建立沿用 2026-10-24 寫好的腳本,參數沒有再對一次。判斷只存在於文件裡、沒有進到執行的那一刻時,對建出來的資源沒有作用。
反模式
- 把只能建立時決定的設定當成之後可以調的設定,沒有逐項寫出選錯時怎麼補救。
- 看到元件狀態是
RUNNING、ACTIVE,就把它當成這個組合有支援。 - 文件只寫到作業系統名稱,就取那個作業系統的最新版,沒有查那個版本有沒有提供要用的元件。
- 依版本查詢的工具回傳了要找的項目,就當成有支援,沒有拿不存在的值查一次對照,確認它查不到時不是回傳同一份全部清單。
- 在容易建的機型上演練成功,就當成稀缺機型也會成功。
- 為了最小暴露拿掉唯一不依賴代理程式的入口,而網路層已經擋住了那份暴露。
- 重送腳本跑了一整天,中間查到的新資訊只寫進文件,沒有回頭改腳本的參數。
- 原本規劃的路徑失敗之後,先猜成因各試一次,最後才讀 Known Issues。
修法
- 建立之前列出只能建立時決定的設定:讀修改資源的 API 或 CLI 說明,或看 IaC 的 plan 把哪些屬性標成 forces replacement;逐項寫出選錯時的補救與代價。
- 對路徑上每一個服務讀三種文件:支援的作業系統與映像檔清單、Known Issues、前置條件(服務以哪個使用者執行、要什麼權限),對照這次的機型加作業系統。文件只寫到作業系統、業者又有依版本查詢的工具時,用映像的作業系統版本欄位的值再查一次,第一次用時另外拿同一個作業系統名稱、明顯不存在的版本查一次當對照:結果跟對照不同才採用為這個版本有沒有提供那個元件,再跟 Known Issues 一起判斷支援;相同時從逐版本的文件或建起來的主機回報的元件清單確認,確認之前不當成支援,並讓兩條路徑裡至少一條不依賴它。決策記錄寫出查詢的指令、對照的項目數、實際結果的項目數與判定(確定有、確定沒有、分不出)。
- 兩條路徑逐項列出依賴的元件:最沒有把握的元件(代理程式、支援範圍)只出現在一條上,例如代理程式的工作階段加上用自己公鑰的 SSH;兩條仍然共用的元件(sshd、22 port 規則)寫出來,要擋住它們時另備序列主控台與救援帳號;停用其他入口之前兩條都登入過。
- 稀缺資源選補救代價低的組合:最嚴格的設定裡跟機型無關的部分放到容易重建的資源上驗,跟機型有關的部分讀文件確認。
- 重送腳本的參數在兩個時間點對一次:每次重新啟動之前,以及腳本還在跑時查到會改變建立參數的新資訊時(先停掉腳本再改);拿只能建立時決定的設定、三種文件與兩條路徑的元件,對腳本裡寫死的設定。
- 第一次失敗之後先讀文件:讀 Known Issues 與疑難排解,再決定要改哪個條件重試。
判讀徵兆
| 徵兆 | 判讀 |
|---|---|
| 資源建好、元件狀態正常,而它的功能逾時或失敗 | 組合可能不在支援範圍,成因多半已經寫在 Known Issues |
| 補救的做法需要先登入資源才做得到(加 sudoers、改設定檔) | 這條補救路徑跟原本的路徑共用了「登得進去」這個前提,不算另一條 |
| 演練用的機型或作業系統跟正式的不同 | 演練驗不到那一項不同的條件 |
| 文件或筆記裡寫著某個前置條件,而執行用的腳本早於那一筆寫成 | 那一筆判斷沒有進到腳本,建出來的資源照舊判斷設定 |
| 說明裡寫著某欄位「建立後不能改」,而建立時那一欄選的是最嚴格值 | 選錯的補救是重建;資源稀缺時重建還要再搶一次 |
| 主機的代理程式設定裡元件是啟用,而它回報的元件清單裡沒有這一項 | 代理程式回報完、版本也是最新時,以主機回報的清單為準:這個映像版本不提供它,跟「啟用了卻失敗」是不同的成因 |
| 依版本查詢的工具,查到的清單跟填不存在的值時完全相同 | 分不出這個版本是提供全部還是工具沒有它的資料,這次的結果不能當成有支援的證據 |
跟其他抽象層原則的關係
- 平常不動作的防護機制的部署驗證:本卡最接近的既有卡。那張卡的「元件顯示正常」是成功訊號提早出現的位置之一,處理的是部署之後怎麼驗;本卡把同一個訊號放到建立之前:狀態正常描述的是元件啟動了,而這個組合能不能完成登入,要在建立之前從支援清單與 Known Issues 查,建好之後才發現時,補救要重建整個資源。
- 承重論點先對抗驗證、再建下游:那張卡說最被依賴的論點最先驗;本卡的「這個組合有支援」就是這次的承重論點,主機、Bastion 與網路都依賴這個前提,而它在建立之前讀一條 Known Issue 就驗得到。
- 可重現性只有乾淨機器重跑才驗得出:那張卡說工作機上不在 repo 裡的狀態讓缺口隱形;本卡的演練限制也是兩個環境之間的差異造成的:演練環境與正式環境不同的那一項條件,演練永遠驗不到。
- 驗證方法的選擇時機:那張卡說推理失敗兩次就換驗證工具;本卡把「讀官方的 Known Issues」排在第一次失敗之後、第二次嘗試之前,因為三次各 15 分鐘的等待驗的都是文件上已經寫明的結果。