# 平台工程(Platform engineering)的重要性,Day 2 才是真正的工作 > 本文成果承蒙陽明交大「高等教育深耕計畫」113 學年度第 2 學期「職涯學習助學金-校外職訓」計畫支持 ## 把平台當產品來開發:來自 Kubernetes 生命週期管理戰壕的教訓 在雲原生領域,建立一個內部開發者平台(IDP)已成為主流。我們夢想著提供「黃金路徑」、光鮮的 Backstage UI,讓開發者能夠一鍵建立新應用。但一個殘酷的現實是:應用的「誕生」(Day 1)只是故事的序章。平台真正、複雜且往往不為人知的工作,發生在日復一日的 **Day 2 維運**中——這是一場關於升級、遷移、安全修補和管理成百上千個服務生命週期的漫長戰役。 本文將深入探討平台維運的真實挑戰,分享來自 Kubernetes 戰壕中經過戰火洗禮的策略,並透過一系列生動的「戰爭故事」,揭示一個核心理念:一個平台的真正價值,取決於它應對 Day 2 挑戰的能力。 ### 第一章:一個「簡單」變更的複雜剖析 平台使用者的期望通常很單純:「我只想修改這個設定檔」。然而,在平台工程師的眼中,這背後隱藏著層層關卡: * **雲端供應商的束縛**:你以為可以隨意更改,但底層的雲端服務商可能並不同意。一個典型的例子是,你無法直接更改一個已建立的 AWS 負載平衡器的類型,這需要重建,意味著如果沒有妥善規劃,就會導致服務中斷。 * **你自己的抽象之敵**:平台團隊為了簡化操作,通常會建立抽象層。但過度的抽象可能反而會隱藏使用者真正需要調整的參數。例如,當資料科學家需要特定型號的 GPU 時,你的平台抽象是否允許他們進行這種細微性的選擇? * **生成式資源的陷阱**:無論是透過 Helm 範本還是 GitOps 工具,平台都會為使用者產生大量 Kubernetes 資源。如果使用者試圖直接手動修改這些被管理的資源,災難就會發生。這些變更要麼會被自動化的協調迴圈(reconciliation loop)無情地覆寫,要麼會直接導致下一次的 Helm 版本更新或 GitOps 同步徹底失敗。 這些挑戰告訴我們,Day 2 的維運工作從一開始就充滿了複雜性。而當這些變更需要擴展到整個組織時,真正的考驗才剛開始。 ### 第二章:戰爭故事 — 在平台級遷移中倖存 當一個變更需要應用於數百個團隊、數千個程式碼倉庫時,這不僅是技術挑戰,更是規模化的組織難題。以下幾個真實案例,生動地展示了平台團隊如何應對這些挑戰。 #### 案例一:CNI 轉換 — Calico 到 Cilium 的線上遷移 * **挑戰**:將叢集的 CNI 從 Calico 全面遷移到 Cilium。Cilium 的網路策略(Network Policy)在某些標準的解讀上與 Calico 存在細微差異,直接切換會導致服務網路中斷。 * **策略:分階段部署**:團隊採取了極為謹慎的多步驟流程。 1. **第一步:部署「過渡版本」**。他們先推出一個平台的中間版本,這個版本僅僅是在叢集中加入了 Cilium 的 CRD,但 CNI 本身仍是 Calico。 2. **第二步:賦能使用者**。這讓所有應用團隊有時間,在不影響現有服務的情況下,預先建立和測試符合 Cilium 規範的新版網路策略。 3. **第三步:執行切換**。直到所有服務都具備了新的 Cilium 網路策略後,平台才推出下一個版本,正式將 CNI 從 Calico 切換到 Cilium。 * **核心教訓**:對於涉及核心網路的線上遷移,一個包含「準備期」的多階段部署流程是保障服務連續性的關鍵。 #### 案例二:廢棄之舞 — 從 PodSecurityPolicy (PSP) 到 PodSecurityStandard (PSS) * **挑戰**:Kubernetes 廢棄了 PodSecurityPolicy (PSP),所有工作負載都需要遷移到新的 PodSecurityStandard (PSS)。 * **策略:審計先行,賦予可見性**:團隊利用了 Kyverno 這類的策略引擎。 1. **審計模式(Audit Mode)**:他們先在叢集中以「審計模式」部署了 PSS 策略。這意味著不合規的 Pod 仍然可以運行,但所有違規行為都會被記錄下來。 2. **提供儀表板**:平台團隊為所有使用者提供了儀表板,讓他們可以清楚地看到自己的應用是否符合新的安全標準。 3. **強制執行**:只有當所有團隊都在儀表板上看到他們的應用呈現「綠色」(即完全合規)時,平台才將策略切換到「強制模式」(Enforce Mode),並安全地移除舊的 PSP。 * **核心教訓**:在推行破壞性安全變更時,先給予使用者「可見性」和「修正時間」,而不是直接強制執行,可以極大地降低推行阻力。 #### 案例三:組織重組的混亂 — 大規模更新所有權 * **挑戰**:公司進行組織重組,團隊名稱和負責人發生變更。這需要更新散佈在數百個 GitHub 倉庫中的 OWNERS 檔案,以及 Kubernetes 資源上的標籤(Labels)。 * **策略:集中化元資料與自動化生成**:手動操作是不可能的。團隊建立了一個**中央元資料儲存庫**,用來存放所有倉庫和元件的資訊(類似於 Backstage 的軟體目錄)。當組織變更發生時,他們只需更新這個中央儲存庫,然後一個自動化工具就會負責產生 PR,將變更推送到所有相關的倉庫中。 * **核心教訓**:面對規模化的、重複性的變更,投資於集中化的元資料管理和自動化生成工具是唯一可行的出路。 #### 案例四:Kubernetes 的量子跳躍 — 解耦控制平面與節點升級 * **挑戰**:客戶的 Kubernetes 版本嚴重落後(例如 1.25),需要升級到 1.28。但他們的應用程式是有狀態的,每次升級節點(Worker Node)都非常痛苦。 * **策略:利用版本傾斜策略(Version Skew Policy)**:Kubernetes 允許控制平面和節點之間存在一定的版本差異。團隊利用這一點,設計了一個對使用者影響最小的升級路徑:他們連續三次只升級控制平面(1.25 -> 1.26 -> 1.27 -> 1.28),而節點始終保持不動。直到最後,才執行一次性的節點升級。 * **核心教訓**:從 Day 0 開始設計你的平台時,就要考慮到操作上的靈活性。如果你的平台產品將控制平面和節點版本死死地綁定在一起,你將無法執行這類優雅的升級策略。 ### 第三章:平台即產品 — 以人為本的策略 應對這些技術挑戰的背後,是一種更深層的理念轉變:**將你的內部平台當作一個真正的產品來運營**。 #### 原則一:你不是你的使用者 平台工程師熱衷於 Kubernetes、YAML 和底層技術,但你的使用者——資料科學家、前端工程師、行動應用開發者——並非如此。他們有自己的業務目標和壓力。意識到這種根本性的差異,是有效溝通的第一步。 #### 原則二:與你的客戶交談 當你看到一個團隊遲遲不肯升級,感到沮喪時,先不要責備。去和他們溝通,你可能會發現他們有著你意想不到的阻礙:一個特殊的程式碼倉庫結構、一套僵化的內部流程,或是某個你不知道的技術債。理解他們的痛苦是解決問題的前提。 #### 原則三:打造一個雙贏局面 幫助使用者解決升級問題,本質上是一種「自私」的行為。作為平台工程師,你也是平台的 on-call 負責人。使用者遇到的每一個問題,都可能在深夜轉化為你的告警。幫助他們,就是幫助你自己減少營運負擔和睡眠中斷。 #### 原則四:建立「可戳破的」、帶有版本的抽象 抽象是必要的,但僵化的抽象是敵人。一個好的策略是使用像 Helm 這樣的工具,並利用 `values.schema.json` 為你的抽象建立一個清晰、帶有版本的 API 介面。這個介面不僅定義了使用者可以調整的範圍,甚至可以用來自動產生 UI 或 CLI。嚴格的版本控制至關重要,它讓你能夠管理龐大叢集中的版本分散,並根據版本資訊調整監控策略(例如,忽略已知舊版本中的無害告警)。 ### 結論:Day 2 才是價值的試金石 一個平台的真正價值,不在於它能多快地建立一個新服務,而在於它能多麼安全、高效地管理成千上萬個服務走過它們完整的生命週期。Day 2 的工作是複雜、困難且往往不被管理層所看見的。 但這正是平台團隊證明自己價值的最佳方式。當下一個 Log4j 等級的重大漏洞(CVE)爆發時,如果你能向你的 CTO 展示,你的平台有能力在數小時內為全公司的服務推送安全修補,而不是耗費數周,那麼平台背後所有這些「看不見」的 Day 2 投入,其價值將變得無比清晰和耀眼。這,才是頂級平台工程的終極體現。