OpenBao靠CNPG達成RPO=0,憑證輪替藏斷線陷阱
CNCF Blog · 2026-09-16
OpenBao 的 PostgreSQL 儲存後端有個容易被忽略的行為:連線池只在程序啟動時建立一次,之後不會重新讀取磁碟上的憑證檔案。這代表憑證到期前該有的自動輪替,反而可能是讓自架 secrets 引擎無預警斷線的元兇。EnterpriseDB 與 ControlPlane 的工程師在 CNCF 部落格發布的文章中,示範了用 CloudNativePG(CNPG)幫 OpenBao 建置零資料遺失的儲存層,也把這個地雷攤開來講清楚。
原本的問題:自架 Secrets 引擎的儲存層與憑證管理
OpenBao 是從 HashiCorp Vault 分岔出來的開源專案,本身沒有內建的資料儲存層,得外掛 Consul、Integrated Storage(Raft)或關聯式資料庫等後端才能存放加密後的 secrets。用 PostgreSQL 當後端,最先要解決的是資料庫本身的高可用與零遺失問題,OpenBao 才有資格自稱是「可靠」的 secrets 引擎。只要牽涉到資料庫連線,就免不了認證方式的選擇:帳號密碼,或是 mTLS 用戶端憑證。
憑證比密碼安全,但憑證會過期、需要定期輪替,這正是文章點名的第二個難題。文章明講:OpenBao 的 postgresql 儲存外掛在啟動時建好連線池後,就不會再重新讀取憑證檔案,這點與它的前身 Vault 一模一樣。憑證輪替因此從一項單純的安全性提升,變成一個必須主動排程處理的維運風險。
採用的方法:CloudNativePG 同步複寫加憑證式雙向驗證
文章實測的架構是 OpenBao 2.6.1 搭配 CloudNativePG 1.30.0 管理的三節點 PostgreSQL 18.6 叢集。複寫方面採用 synchronous: method: any, number: 1 的 quorum 設定,並讓 dataDurability 維持預設值 required,也就是至少一個 standby 完成寫入才回應成功。這樣達成的是 RPO=0(零資料遺失),代價是萬一暫時找不到可用的 standby,寫入會被整批阻塞,而不是悄悄遺失。
認證則完全交給 CNPG 的 DatabaseRole CRD,打開 clientCertificate.enabled: true 後,CNPG 會自動幫 openbao、openbao-rw 兩個角色簽發用戶端憑證,OpenBao 端在連線字串加上 sslmode=verify-full 與對應的 sslcert/sslkey/sslrootcert 路徑。pg_hba 規則進一步把非憑證連線整組擋掉:hostssl 規則要求 cert 驗證,hostnossl 一律 reject。等於密碼登入這條路徑在資料庫端就被完全關閉。
OpenBao 端的儲存設定則長這樣:
storage "postgresql" {
ha_table = "openbao_ha_locks"
ha_enabled = "true"
skip_create_table = "true"
}skip_create_table 設成 true 是必要的,因為 openbao-rw 這個角色刻意不被授予 CREATE 權限,資料表得由管理流程事先建好,OpenBao 執行期只能讀寫既有的表。這樣即使憑證外洩,攻擊者能造成的破壞範圍也被限制在既有資料表的讀寫,動不了 schema。
實際效果與地雷:83 天憑證輪替視窗
CNPG 簽發的用戶端憑證效期是 90 天,並會在到期前約 7 天自動核發新憑證,換算下來憑證上線後大約第 83 天,Secret 裡就已經換上新內容。問題是 OpenBao 的行程完全不知道 Secret 換了新憑證,因為它的連線池只在啟動當下讀取一次憑證檔案,之後就算檔案內容被 CNPG 覆寫,也不會主動 reload,這是它至今還沒解決的已知限制。
如果維運團隊沒有另外排程,OpenBao 會繼續拿著舊憑證撐到第 90 天真正過期為止,屆時只要連線池嘗試重新握手,PostgreSQL 就會因憑證失效直接拒絕連線。OpenBao 等於瞬間失去自己的儲存後端,所有 secrets 讀寫全面中斷,而且這不是 CNPG 的錯,是 OpenBao 這個儲存外掛本身的設計限制。
因此,凡是採用這套 OpenBao 加 CNPG 憑證式驗證架構的人,都得把「憑證每 90 天輪替、CNPG 提前 7 天核發新證」這張時間表,換算成自己的維運行事曆:在第 83 天新憑證核發之後、第 90 天舊憑證真正過期之前,安排一次 OpenBao pod 的 rolling restart,讓每個 pod 重新啟動、重新載入新憑證檔案。少了這一步,憑證輪替不會讓系統更安全,只會讓它在沒人注意的時候突然斷線。
原始來源:CNCF Blog - Running OpenBao on Kubernetes with a CloudNativePG PostgreSQL backend