題目與適用場景
你負責一個裸機 Kubernetes 叢集,團隊用 Service.spec.externalIPs 讓外部地址直接路由到 Service。叢集升級到 v1.36 後出現棄用警告,安全團隊擔心租戶可以宣告任意地址並攔截流量。請設計遷移:先發現真實依賴,再按業務選擇 LoadBalancer 控制器或 Gateway API,最後阻斷新增使用並驗證回滾。
Kubernetes 官方說明指出,externalIPs 不由 Kubernetes 分配或驗證所有權;v1.36 將其標記為 deprecated,未來版本會先停止 kube-proxy 支援,再完全移除。因此答案要區分目前相容視窗與長期目標,不能把棄用誤述為立即刪除。
背景與邊界
本題聚焦 Service 網路入口、RBAC、准入策略、遷移順序和可觀測性。雲端負載平衡器、裸機網路設備和 DNS 由平台團隊提供,候選人應說明介面契約、地址所有權證明、雙寫視窗和故障回退條件。
面試官考察點
- 能否解釋
externalIPs是 Service spec 欄位,與 Node 的ExternalIP地址或 LoadBalancer 顯示欄位不同。 - 能否從審計、流量、權限、控制器和 DNS 追蹤遷移閉環。
- 能否用
DenyServiceExternalIPs阻斷新增寫入,同時不誤刪既有業務。 - 能否比較 LoadBalancer、MetalLB 類控制器和 Gateway API 的所有權與回滾邊界。
- 能否用指標和分階段切換證明沒有流量黑洞或 IP 搶占。
30 秒回答框架
「我先掃描 Service spec、審計日誌、DNS、節點路由和真實流量,建立 externalIP 到租戶、埠和後端的對映。遷移前開啟 DenyServiceExternalIPs 只阻斷新增值,不修改既有物件;對每個入口選擇管理員控制的 LoadBalancer 控制器或 Gateway API,先並行驗證健康檢查、來源地址和連線排空,再切 DNS/上游。確認舊流量為零後刪除 externalIPs,保留回滾視窗,並用審計、5xx、連線失敗和地址衝突指標控制放量。」
分步驟深入解答
- 建立資產清單。 列出所有使用
externalIPs的 Service、地址、埠、命名空間、擁有者、DNS TTL、入口協定、EndpointSlice、externalTrafficPolicy 和最近流量。區分外部地址欄位與 Node.status.addresses的ExternalIP,避免誤報。
- 識別安全風險。
externalIPs由使用者寫入 spec,而 Kubernetes 不負責分配地址或保證唯一性。低信任租戶可以宣告別人的地址,造成流量攔截或中間人風險。審計建立、更新、刪除和 kube-proxy 規則,按地址和租戶關聯異常。
- 先擋新增、後遷移存量。 啟用
DenyServiceExternalIPs,它拒絕新建或新增 externalIPs,但允許刪除既有值。先在審計模式或低風險叢集驗證誤傷,再切到強制模式;存量物件由遷移控制器或人工審批處理。
- 選擇替代入口。 雲環境優先使用管理員控制的
type: LoadBalancer;裸機可用具備地址池和衝突檢查的負載平衡控制器。需要角色分離、共享入口或路由規則時使用 Gateway API,讓平台管理員持有 Gateway,應用團隊僅管理 HTTPRoute 等受限物件。
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
spec:
gatewayClassName: platform-public
addresses:
- type: IPAddress
value: 192.0.2.4這段只表達管理員持有地址的示意;實際 GatewayClass、控制器能力、憑證和 IP 池必須按部署實作驗證。
- 設計雙入口驗證。 新入口先用獨立 hostname 或低 TTL DNS 灰度,比較連線成功率、TLS、來源地址、長連線、健康檢查和 EndpointSlice 收斂。若必須重用舊 IP,先確認新控制器完成地址所有權登記,再切換上游,避免兩個實作同時宣告同一地址。
- 排空與刪除。 觀察舊入口無新連線並等待最大連線壽命後,移除 externalIPs,保留審計記錄和回滾快照。刪除順序應讓 DNS、負載平衡、Service 和後端之間始終至少有一條可驗證路徑。
- 版本與回滾。 v1.36 先產生警告;官方時間表預計最早 v1.40 在 kube-proxy 禁用行為,最早 v1.43 完全移除。回滾只恢復經過地址所有權驗證的舊入口,不重新開放任意租戶寫 externalIPs;若新入口失敗,暫時回退 DNS 或控制器設定並持續阻斷新增風險。
高品質示範回答
我先把每個 externalIP 當作待遷移資產,而不是直接批量替換欄位。透過 API 清單、審計、DNS、節點規則和流量日誌確認地址、租戶、埠、連線壽命和所有權。externalIPs 是使用者可寫的 Service spec 欄位,Kubernetes 不負責分配或衝突檢查,這正是 CVE-2020-8554 類流量攔截風險的根源。
在遷移期間啟用 DenyServiceExternalIPs,只拒絕新增或追加地址,保留刪除存量的能力。替代方案由入口需求決定:雲環境使用管理員控制的 LoadBalancer;裸機使用有地址池和衝突檢測的控制器;需要角色分離和共享路由則使用 Gateway API。新入口透過獨立 hostname 或低 TTL 灰度,比較連線、TLS、來源地址和健康檢查,確認舊連線排空後再刪除 externalIPs。
我會把 v1.36 的棄用警告、最早 v1.40 的 kube-proxy 行為變化和最早 v1.43 的完全移除寫入遷移計畫。回滾只恢復已驗證的管理員入口,不恢復任意租戶寫入;指標包括地址衝突、5xx、連線失敗、DNS 生效延遲和殘留 Service 數量。
常見錯誤
- 錯誤表現: 把棄用理解成升級後立即刪除 → 失敗原因: 誤判相容視窗,導致無計畫停機 → 修正方法: 按 v1.36 警告、後續行為禁用和最終移除分階段安排。
- 錯誤表現: 直接把
externalIPs改成loadBalancerIP→ 失敗原因: 仍可能繞過地址池和衝突檢查 → 修正方法: 讓管理員控制的 LoadBalancer 控制器分配並寫入 status。 - 錯誤表現: 開啟准入控制後批量刪除所有舊欄位 → 失敗原因: 沒有流量和連線排空證據 → 修正方法: 先擋新增、灰度新入口、等待連線壽命,再按資產刪除。
- 錯誤表現: 只檢查 Service,不檢查 DNS、節點規則和真實流量 → 失敗原因: 可能留下隱性入口或黑洞 → 修正方法: 建立端到端遷移清單和觀測視窗。
- 錯誤表現: 讓租戶繼續管理 Gateway 地址 → 失敗原因: 替代入口重現相同權限問題 → 修正方法: Gateway 由平台持有,應用只管理受限路由。
追問及應對
DenyServiceExternalIPs 會影響已有 Service 嗎?
官方行為是拒絕新建 Service 使用該欄位,以及向已有 Service 追加新值;刪除既有值仍可進行。上線前應核對目前版本實作並觀察拒絕事件,不能把它當作自動遷移器。
裸機叢集為什麼不直接手工填 LoadBalancer IP?
手工填寫仍缺少地址池、衝突檢查、健康狀態和審計。使用具備管理員地址池的控制器,可以讓分配、回收和唯一性成為平台責任;特殊固定 IP 也應經過明確審批。
Gateway API 如何保持應用團隊自助?
平台團隊建立 Gateway 和 GatewayClass,限制 addresses、監聽器和跨命名空間引用;應用團隊提交 HTTPRoute,並透過引用策略、策略物件和審計控制可達範圍。
如何處理長連線和 WebSocket?
在 DNS 或入口切換前測量連線壽命,使用連線排空和雙入口重試策略。舊入口只停止新連線,保留足夠時間讓現有連線完成;指標要區分新連線失敗和舊連線自然結束。
什麼時候可以關閉回滾開關?
當舊入口流量為零、所有 Service 已移除欄位、地址衝突檢查通過、DNS TTL 視窗結束且新入口連續觀察達標後,再刪除快照並保留審計證據。時間表不能取代資料證據。
參考資料
- Kubernetes v1.36 Service ExternalIPs 棄用公告(Kubernetes Blog)
- Service 文件(Kubernetes Documentation)
- Admission Control 文件(Kubernetes Documentation)
- Gateway API 文件(Kubernetes Documentation)
面試作答要點
先區分欄位語義和安全風險,再給出盤點、阻斷新增、替代入口、雙入口驗證、排空、刪除與回滾的順序。
一句話總結
遷移 externalIPs 的關鍵是把任意使用者可寫入口改成管理員擁有、可審計、可驗證的地址分配鏈路。
繼續練習
如果叢集同時使用 Gateway API、MetalLB 和雲 LoadBalancer,請設計統一入口目錄、地址所有權模型和跨環境回滾協定。