以 Cloudflare 作為入口的
多租戶 PaaS 設計

支撐 KamuiDash 多租戶 PaaS 的邊緣架構。Cloudflare 負責網域解析、動態請求中繼與來源保護,並由 Worker、KV 與 Tunnel 分工處理。

KamuiDash 透過同一個 Cloudflare 邊緣接收各租戶的應用程式與自訂網域。
本文依序追蹤請求從公開入口到租戶應用程式回應的路徑。

從公開邊緣到租戶應用程式

所有 HTTP 請求先到 Cloudflare Worker。Worker 從 Host 解析目標應用程式;需要執行的動態請求才會經由 Cloudflare Tunnel,送到叢集內的內部路由器與租戶應用程式。

Worker 在入口集中處理網域解析與路徑選擇,只有需要應用程式執行的請求才會進入叢集。

從邊緣到目的地
使用者瀏覽器 / API 用戶端
HTTPS
CLOUDFLARE EDGE
Workers網域解析與路徑選擇
邊緣回應部分內容在此完成
Tunnel已建立的私有路徑
動態請求
PRIVATE ORIGIN
內部路由器轉送到目標租戶
租戶應用程式回傳動態內容
只有動態請求會透過 Tunnel 進入私有來源。

1. 在 Worker 解析 Host

Worker 會正規化收到的 Host,然後查詢 KV 中網域與內部應用程式的對應。自訂網域與平台子網域都會回答同一個問題:這個請求代表哪個應用程式?未知的外部網域會在 Worker 回傳 404,不會進入叢集。

確認應用程式後,Worker 會檢查服務模式;若回應不在邊緣完成,便讀取動態應用程式的目的地並經由 Tunnel 轉送。KV 資料依用途分開。

Worker 讀取的路由資訊
網域對應          Host            → 內部應用程式
目的地登錄表      內部應用程式    → 動態應用程式目的地

網域對應與動態目的地的變更頻率及可接受的傳播時間不同,因此不放在同一筆記錄。

請求分流
  1. 01解析 Host將自訂網域對應至內部應用程式
  2. 02確認服務模式只有動態請求會進入叢集
  3. 03解析目的地從應用程式配置選擇 Tunnel 路徑
  4. 04在邊緣正規化失敗統一逾時、上游錯誤與追蹤
Host 識別應用程式;只有動態請求會交給 Tunnel。

2. 動態請求經由 Tunnel 與內部路由器

若回應不在邊緣完成,Worker 會讀取應用程式與目的地的對應並選擇 Tunnel 路徑。它以解析出的應用程式識別與路由脈絡建立上游請求,並覆寫用戶端傳來的同用途資訊。

每次轉送時,Worker 會依收到的標頭建立新的上游請求,並以解析結果明確設定 Host 與路由脈絡,同時附上請求 ID。因此租戶選擇不會交由用戶端可任意傳送的值決定。

Tunnel 連接器從叢集向外連至 Cloudflare,因此叢集沒有可從網際網路到達的接收端點。Tunnel 另一端的內部路由器取得解析後的脈絡,再轉送到目標租戶應用程式。

上游 fetch 以 AbortController 限制時間。連線失敗、逾時與上游錯誤會在入口轉為 Gateway 錯誤;回應中的內部路由資訊會被移除,未提供 Cache-Control 的動態回應會使用不共享快取的預設值,WebSocket 升級則獨立中繼。

動態請求的信任邊界
PUBLIC用戶端Host / Path / Request headers
接收
EDGEWorker正規化 Host、查詢 KV、重建上游請求
解析後脈絡
PRIVATE PATHTunnel已建立的外向連線
僅連接器
CLUSTER內部路由器轉送至目標租戶
不直接使用用戶端輸入進行路由;Worker 將解析後的脈絡透過 Tunnel 傳給內部路由器。

3. 在 Tunnel 後也限制入口

內部路由器使用 Worker 提供的路由資訊,因此只接受經由 Tunnel 到達的請求。KamuiDash 以 NetworkPolicy 將內部路由器的 Ingress 限制為 Tunnel 連接器 Pod。

此政策只允許 Tunnel 連接器作為來源,關閉同一叢集中其他工作負載直接到達路由器並偽造 Worker 應解析脈絡的路徑。

4. 網域註冊與部署時的變化

新增自訂網域時,KamuiDash 先透過 Cloudflare 的自訂網域功能完成所有權驗證與憑證發行,接著登錄網域與內部應用程式的對應;刪除時則依序解除對應與網域端狀態。移動動態應用程式時會更新目的地登錄表,網域對應與目的地的更新頻率不同,因此使用不同快取時間。

KV 的寫入不會立即清除所有邊緣快取,未登錄的結果也可能短暫存在。註冊與移動會一路追蹤 DNS、憑證與 KV 傳播;Worker 以結構化日誌記錄請求 ID 和邊緣追蹤資訊,排除憑證與 Cookie,並可一路追到 Tunnel、內部路由器與租戶應用程式。

設定變更抵達請求路徑的過程
新增自訂網域
所有權與憑證更新網域對應KV 快取傳播Worker 解析新 Host
移動動態應用程式
準備目的地更新目的地登錄表KV 快取傳播Worker 選擇新路徑
註冊與移動的完成條件,是邊緣可解析新對應,而不只是 KV 已寫入。

Cloudflare 在此路徑處理的工作

Cloudflare 處理自訂網域的所有權驗證以及憑證的發行與更新。Worker 是所有公開請求的共同執行點,集中 Host 解析、上游請求建立、錯誤正規化與請求 ID。Tunnel 讓叢集內的連接器建立外向連線,因此租戶應用程式與內部路由器不必持有公開接收端點。

總結

KamuiDash 在 Cloudflare 入口集中三件事。

將 Cloudflare 放在入口,讓 KamuiDash 不需為每個租戶另建公開路徑,同時保留 Worker、Tunnel 與內部路由器各自的責任。

關於 KamuiDash 的設計理念與從 GitHub 部署的基本流程,請參閱為什麼使用 KamuiDash