起因是公司在一個新專案做系統 Benchmark 時遇到的一個 Unknown Known:一個所有資深 SRE 都知道怎麼解,卻沒人意識到它正在發生的問題。
一筆抵過幾個工程師年薪的帳單
我們在 Cloud Kubernetes 上建構一套大型分散式資料系統,做 Benchmark 的時候,因為 persistent disk(PD)的 IOPS 不足,會不斷地重建整個分散式資料庫系統。但 Kubernetes 的 PD 有個特性:資料庫被刪除,PD 不會跟著被刪除,因為系統不知道上面有沒有重要資料。
一輪一輪的測試下來,累積了大量高 IOPS 的 PD。這些 PD 費用高昂,直到幾週後才被發現 — 整個月的帳單,可以抵過幾個工程師的年薪。
只要是做過幾年 Kubernetes 維運的 SRE,都會立刻知道這是什麼問題,也知道怎麼解:一個簡單的腳本,查詢哪些 PD 沒有被 attach 到任何 instance 上就夠了。但真正值得追問的不是「為什麼沒人寫這個腳本」,而是這件事暴露出監控系統的分散與薄弱。
兩種基礎設施治理模式
一般企業的基礎設施管理,大致會落在兩種模式之間。
中央集權型:公司 IT 維護所有開發系統,制定統一的管理標準,用最少的維護人力覆蓋所有系統。副作用是權限閉鎖 — 所有開發部署都要經過統一的維護團隊,一旦情況緊急或部門分散,會帶來極大阻礙。另一個問題是技術閉環:即使多雲,每個平台的維運方式都差異極大,像 GCP Kubernetes 和 AWS ECS,人力有限的維護團隊通常會盡量收斂到單一系統上,然後把力氣花在強化那套系統的維護與管理 — 但這對某些特化型服務未必是最佳解。舉例來說,內部請假系統其實用 AWS Lambda + API Gateway + DynamoDB 就能做到個位數美金的低費用,硬要塞進 Kubernetes 反而會有幾十到上百美金的低消。這種做法的好處,是公司只需要制定單一規章制度、所有人共用,可以盡量降低稽核、權限控管與系統穩定性的風險 — 因為服務系統一致,監控也可以持續復用。
分散開發型:各團隊自行創建 AWS Account 或 GCP Project 來管理專案,對帳戶有最高掌握度,初期能急速推進,也不受限於單一技術,彈性很高,像一個個小型新創團隊。但問題同樣明顯:每個團隊都需要專業的系統維護人力,每個專案技術不同,監控、管理、稽核經常無法互相復用,等同於每個專案都要打掉重來。
為什麼這種事只會發生在分散開發型
前面描述的帳單事故,正是發生在分散開發型的案例裡。即使維護團隊在問題發生的當下立刻就知道問題所在,但監控建構的速度趕不上資源創建的速度,問題就會發生。再加上工程師離職率高、專案團隊動態成立,有些成員是從 Backend RD/QA 轉換角色進來的,對新技術會有一份憧憬,想用新的技術棧來搭建管理系統 — 這些都讓監控覆蓋更難跟上。
站在管理數十個團隊的管理層角度來看,同樣類型的事件會不斷重演:一年十幾次 P0,很多都基本到不行 — 憑證忘記換、Auto Scaling 不運作、Rate Limit 或 Cache 實作錯誤、資源沒做好監控直到用完系統才炸開。公司永遠會有新團隊想用新技術,這件事本身不是問題;問題是同樣的事件在不同團隊之間反覆發生。
解法不是補 RCA,是讓監控隨資源自動出現
我的見解是,這裡真正該做的不是把 RCA 做得更仔細、或是表面地補上一個 Monitor,而是強制套用一種管理方式:只要 resource 一創建出來,監控就直接產生。
在 Kubernetes 上,這已經有現成的機制可以參考 — 像 Prometheus 的 resource discovery,新的 Pod/Service 出現,監控自然就跟著出現。但 GCP、AWS 上非 Kubernetes 的資源,像 RDS、Cache Server、Queue 這些,就需要撰寫自動化腳本來偵測。這不需要很即時:從資源創建到真正上線,通常至少有 24 小時的落差,所以只要排程每天掃描一次資源,自動在監控系統上補上新增的監控項目就足夠。DNS 也是同樣的邏輯 — 只要有新的 HTTPS endpoint 掛上 DNS,就自動創建憑證過期監控與 health check。
不酷炫,但是很實際
這類系統沒有那麼酷炫,卻很實際:只要使用這套系統的一個團隊踩過一次 P0 incident,補上一個通用的 Monitor,以後所有其他團隊都能受益。這件事有個前提 — 補上去的每個 Monitor,都要考量到其他團隊的相容性。
但只要開始變成各專案各做各的,這個做法就會分崩離析,各自特化的監控系統就會重新冒出來。管理技術的重點,從來不是要把大家綁死在某一個技術棧上,而是新開發的管理系統,能不能顧及所有專案、考量其他團隊的適配,以及過去所有辛苦建立起來的 Monitor,是不是都還被包含在裡面。