題幹與適用場景
請設計一個共用 Kubernetes Gateway。平台團隊負責 Gateway 與負載平衡基礎設施,應用團隊在各自命名空間維護入口 hostname、連接埠、HTTPRoute 與憑證。目標規模約 20 個團隊、每隊 50 個 listener,也就是約 1000 個網域;單一 Gateway 的基礎 listener 上限按 64 估算。
回答要解釋如何把 listener 從巨大的 Gateway 物件拆到多個 ListenerSet,如何授權跨命名空間附加,如何在衝突時保持流量穩定,以及控制器如何透過 status 讓團隊知道設定是否 Accepted、Programmed 或 Conflicted。
面試官考察點
資源邊界與委派
高品質回答會把共用基礎設施、租戶設定與路由繫結分開,說明為什麼應用團隊不能直接編輯平台 Gateway。
衝突與安全預設值
候選人應說清楚預設拒絕 ListenerSet、允許的命名空間來源、相同 hostname 的確定性優先級與憑證參照邊界。
控制器一致性
要涵蓋 watch、合併、驗證、狀態條件與重試,不能只寫一份 YAML 就假設資料面立即生效。
可擴展性與遷移
需要比較一個 Gateway、每租戶一個 Gateway、Ingress 註解等替代方案,並解釋何時 ListenerSet 的複雜度值得承擔。
回答前需要釐清的問題
- 1000 個網域是否共用一個負載平衡位址,還是每個團隊需要獨立入口?
- 應用團隊能否管理自己的 TLS Secret,平台是否保留憑證審批權?
- 跨命名空間附加是允許全部命名空間、標籤選擇,還是只允許同命名空間?
- 發生衝突時要求舊設定繼續服務,還是允許新設定搶占?
- 控制器需要多快反映設定,是否要求跨叢集複製?
- HTTPRoute、TLSRoute 與其他 Route 類型的授權邊界是否相同?
30 秒回答框架
「我讓平台團隊建立 Gateway,並預設禁止 ListenerSet;透過 allowedListeners 明確允許的命名空間範圍。每個應用團隊在自己的命名空間提交 ListenerSet 與 Route,控制器先驗證 ParentRef、hostname、連接埠、協定、憑證參照與 AllowedRoutes,再按 Gateway 優先、建立時間較早、namespace/name 字典序的規則合併。衝突物件標記 Accepted=False、Conflicted=True,不能取代已生效的 listener。資料面只由控制器從合併後的期望狀態編程,狀態條件與指標讓租戶能區分拒絕、衝突、未編程與已生效。」
分步驟深入解答
第一步:估算規模並選擇資源模型
20 個團隊乘以每隊 50 個 listener 約為 1000 個入口。把 1000 條設定塞進一個 Gateway 會造成單物件寫入競爭、權限過寬與控制器重算;ListenerSet 把每隊設定拆成獨立資源,Gateway 只保留平台級位址、類別與允許附加的策略。
第二步:建立授權握手
Gateway 的 allowedListeners 是安全門。預設 None 表示不接受任何 ListenerSet;平台可以選擇 Same、標籤 Selector 或 All。ListenerSet 用 parentRef 指向 Gateway,控制器只有在兩端授權、參照有效且物件被允許時才進入合併集合。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: shared-gateway
spec:
allowedListeners:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: shared
---
apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
name: team-a-listeners
namespace: team-a
spec:
parentRef:
name: shared-gateway
namespace: platform
listeners:
- name: app-a
hostname: app-a.example.com
protocol: HTTPS
port: 443第三步:定義合併與衝突規則
先把 Gateway 自帶 listeners 與獲授權的 ListenerSet 拼成候選集合,再按連接埠、協定與適用 hostname 判斷是否為同一 listener。衝突優先級固定為:父 Gateway 優先;然後 ListenerSet 建立時間較早者優先;仍相同則按 namespace/name 字典序。失敗者寫入 Conflicted,不能靜默覆蓋現有流量。
第四步:隔離路由與憑證
ListenerSet 的 allowedRoutes 限制哪些命名空間可以綁定 Route;Route 透過 parentRefs 指向 ListenerSet 的特定 section。TLS Secret 由平台策略限制參照範圍,憑證審批與應用發布權限分開。應用團隊只能修改自己的 ListenerSet 與 Secret,不能借 ParentRef 讀取其他租戶資源。
第五步:讓控制器可收斂
控制器 watch Gateway、ListenerSet、Route、Namespace 標籤與 Secret,產生按 Gateway 分組的期望模型。每次事件做去重與短暫防抖,驗證通過後再編程負載平衡。status 回傳 Accepted、Programmed、ResolvedRefs 與 Conflicted 條件;重試必須冪等,舊期望狀態保留到新設定成功編程。
第六步:比較替代方案與故障路徑
每租戶一個 Gateway 能簡化權限,卻增加位址、負載平衡與憑證成本;單 Gateway 加註解便宜,但缺少統一 schema、衝突語意與跨實作互通性。ListenerSet 控制面不可用時保留最後一次 Programmed 設定,拒絕未知新 listener;平台 Gateway 刪除或 ParentRef 失效時把子資源標記為未接受,恢復後重新收斂。
高品質示範回答
「我會把 Gateway 當作平台擁有的共用邊界,把 ListenerSet 當作租戶擁有的宣告。平台先設定 GatewayClass、位址與 allowedListeners,預設不允許任何附加;只有帶有 gateway-access=shared 標籤的命名空間可以引用它。每隊提交自己的 ListenerSet、HTTPRoute 與憑證參照。
控制器收到事件後,先驗證 ParentRef、命名空間授權、連接埠/協定/hostname、AllowedRoutes 與 Secret 參照,再把 listener 合併。父 Gateway 優先,之後按 ListenerSet 建立時間與 namespace/name 解決衝突;輸家標記 Accepted=False、Conflicted=True,不奪走已運行的設定。合併成功後才更新負載平衡,Programmed 狀態表示資料面已生效。
按 20 隊乘 50 條約 1000 個 listener,拆分資源可避免單物件寫入競爭與權限集中。控制器不可用時繼續服務最後的穩定快照,新的衝突設定不進入資料面。若租戶需要完全獨立的位址、合規域或故障域,我會改用多個 Gateway,接受較高基礎設施成本。」
常見錯誤
- 讓所有團隊直接編輯 Gateway → 設定互相覆蓋且權限過大 → Gateway 歸平台,ListenerSet 按命名空間委派。
- 預設允許全部命名空間 → 任意租戶可申請共用入口 → 預設 None,再用 Same 或 Selector 收窄範圍。
- 讓新 listener 最後寫入即生效 → 新設定可能劫持舊網域 → 使用確定性優先級並將輸家標記衝突。
- 只檢查 hostname 不檢查連接埠與協定 → 不同協定仍可能撞在同一入口 → 以連接埠、協定與適用 hostname 共同判定。
- 直接把 Secret 名稱交給資料面 → 跨命名空間越權或憑證洩露 → 通過參照授權和控制器驗證後再編程。
- 收到事件就立即改負載平衡 → 短暫非法狀態造成抖動 → 防抖、冪等合併、成功後切換並保留舊快照。
- status 只寫 Ready → 租戶無法區分拒絕、衝突與未編程 → 使用 Accepted、Programmed、ResolvedRefs、Conflicted 條件。
- 把 ListenerSet 當作無限擴展 → 控制器和負載平衡仍有容量瓶頸 → 按 Gateway 分片、限制每租戶配額並監測收斂延遲。
追問及應對
追問一:兩個團隊提交相同 hostname 和連接埠,誰贏?
父 Gateway 優先;兩個 ListenerSet 衝突時建立時間較早者優先,仍相同按 namespace/name 字典序。輸家保持可見但標記 Conflicted,不能用重試時間改變結果。
追問二:平台想暫時凍結一個租戶,怎麼做?
移除其命名空間標籤或縮小 allowedListeners 選擇器,控制器會讓該 ListenerSet 變為未接受並保留最後快照。凍結動作寫入稽核記錄,恢復時重新驗證而不是直接信任舊物件。
追問三:一個 ListenerSet 有 64 條 listener,還能繼續擴展嗎?
單個 ListenerSet 自身仍要遵守實作限制,不能把總量當成無限。把租戶拆成多個 ListenerSet、按 Gateway 分片,並為每個分片設定配額;如果位址或憑證隔離更重要,則改用多個 Gateway。
追問四:憑證 Secret 更新時如何避免中斷?
監聽 Secret 版本並先驗證憑證鏈、hostname 與有效期;在資料面確認新憑證已編程後再更新 Programmed。舊憑證在寬限視窗內保留,失敗則繼續使用已知良好版本並告警。
追問五:控制器重啟期間新 Route 會不會覆蓋舊流量?
不會。控制器持久化或重建期望狀態,資料面繼續使用最後成功快照;重啟後先完整重算、驗證衝突與參照,再以一次可觀察的版本切換。
來源一:Gateway API ListenerSet 使用指南
使用指南定義 ListenerSet 的多租戶委派用途、64 條 listener 限制、allowedListeners、parentRef 與衝突優先級。本文的資源模型、授權握手、衝突處理與狀態設計據此展開。
來源二:GEP-1713
GEP-1713 說明 ListenerSet 解決共用 Gateway 的資源爭用、跨命名空間管理與大規模網域場景,並給出父 Gateway、建立時間與字典序的合併規則。本文的容量估算與替代方案比較以此為約束。
來源三:Kubernetes Gateway API v1.5 發布說明
發布說明記錄 ListenerSet 進入 Standard,並說明它針對多租戶、委派 listener 與超過 64 條 listener 的場景。本文把這些公開變更轉化為面試中的遷移與治理問題。
來源四:系統設計面試公開指南
公開面試指南強調先釐清需求、討論擴展和故障、解釋取捨。本文的釐清問題、估算、衝突追問與替代方案用於訓練這些可觀察的答題訊號。