在常見的生產架構中:
外部負載均衡器(Ng/ELB/ALB/NLB等)終止來自客戶端的 HTTPS 連接。
它將解密后的明文 HTTP 請求轉發給后端的 Kubernetes Ingress Controller Pods。
Ingress Controller 處理 HTTP 請求,并將 HTTP 響應返回給負載均衡器。
負載均衡器重新加密這個 HTTP 響應為 HTTPS,并最終返回給原始客戶端。
總結:對于客戶端來說,他始終認為自己在進行端到端的 HTTPS 通信,完全不知道后端發生了 TLS 終止和再加密的過程。
為什么選擇在外部負載均衡器終止 TLS?(SSL Termination)
這種做法被稱為 SSL Termination 或 TLS Termination,主要有以下幾個優勢:性能開銷降低:TLS 加密解密是 CPU 密集型操作。將這項工作卸載到專門優化的、通常具有硬件加速功能的外部負載均衡器上,可以顯著減輕集群內 Ingress Controller 和 Worker 節點的計算壓力,讓它們更專注于處理業務邏輯。負載均衡器可以集中高效地處理大量 TLS 握手和加密操作。簡化證書管理:你只需要在負載均衡器上配置和管理 SSL/TLS 證書(例如,從 AWS Certificate Manager, Let‘s Encrypt 等獲取和自動續簽)。集群內部的 Ingress Controller 和所有后端服務完全不需要關心證書問題,簡化了配置和安全管理。你不再需要將證書作為 Secret 掛載到 Ingress Controller Pod 中。增強可觀測性和靈活性:負載均衡器可以提供豐富的、與應用層解耦的 TLS 相關指標(如 TLS 版本、密碼套件、握手錯誤等)。你可以在負載均衡器層靈活地設置安全策略(如強制 TLS 1.2+,使用特定的密碼套件),而無需修改后端應用。支持基于內容的路由:一些高級負載均衡器(如 AWS ALB)需要能看到 HTTP 請求的明文內容(如 Host 頭、URL 路徑)才能做出更智能的路由決策。如果全程加密,它們就無法做到這一點。
詳解如下:
詳細過程分解:從 HTTPS 入口到 HTTP 內部
讓我們詳細跟蹤一個請求 https://my-app.com 的旅程,特別是 外部負載均衡器 → Ingress Controller Pod 這一段。步驟 1: 客戶端發起 HTTPS 請求
客戶端(瀏覽器)向 https://my-app.com 發起請求,完成 DNS 解析,找到外部負載均衡器的 IP 地址。客戶端與負載均衡器開始 TLS 握手。負載均衡器出示其配置的 SSL 證書。客戶端驗證證書(有效性、是否由可信CA簽發、域名是否匹配等)。握手成功后,建立了一條安全的、加密的 HTTPS 連接。步驟 2: 負載均衡器終止 TLS 并解密請求
負載均衡器使用自己的私鑰解密接收到的加密請求數據包。此時,負載均衡器得到了一個完整的、明文的 HTTP 請求(包括 HTTP 方法、URL、Headers、Body 等)。步驟 3: 負載均衡器轉發 HTTP 請求到 Ingress Controller
負載均衡器根據其配置的健康檢查目標和路由規則,從健康的 Ingress Controller Pod 池中選擇一個后端。負載均衡器創建一個新的、內部的 TCP 連接到選中的那個 Ingress Controller Pod(例如,通過 NodePort 或直接到 Pod IP,如果使用云提供商的集成模式)。負載均衡器通過這個新的、未加密的 TCP 連接,將步驟 2 中得到的明文 HTTP 請求原樣發送出去。重要:負載均衡器通常會在轉發時添加或修改一些 HTTP 頭,以傳遞原始客戶端的信息,最常見的是:X-Forwarded-For: 記錄原始客戶端的真實 IP 地址。X-Forwarded-Proto: 告知后端原始請求使用的協議(這里是 https)。X-Forwarded-Port: 告知后端原始請求的端口。步驟 4: Ingress Controller 接收并處理 HTTP 請求
Ingress Controller Pod(如 Nginx)接收到這個明文的 HTTP 請求。它查看 Host 頭和 Path,并根據集群中定義的 Ingress 資源規則,決定將這個請求路由到哪個后端 Service 和 Pod。它將請求轉發給目標 Service(通過 ClusterIP,再由 kube-proxy 的 iptables/IPVS 規則導向最終 Pod)。步驟 5: 生成響應并沿原路返回
應用 Pod 處理請求,生成一個 HTTP 響應。該 HTTP 響應先返回給 Ingress Controller。Ingress Controller 將其作為 HTTP 響應 返回給外部負載均衡器。負載均衡器接收到這個明文的 HTTP 響應。負載均衡器重新加密這個 HTTP 響應。它使用在步驟 1 中與客戶端建立的 TLS 會話密鑰,將響應數據加密。負載均衡器將加密后的 HTTPS 響應數據包發送回給原始客戶端。安全性考慮:內部通信安全嗎?
你可能會問:“集群內部的 HTTP 通信安全嗎?”在可信的網絡邊界內(例如,云服務商的同一個 VPC 內、數據中心的內網中),這種架構被認為是安全的。攻擊者很難進入到這個內部網絡來竊聽明文流量。如果需要對內部流量進行加密(多租戶集群、嚴格的安全合規要求),可以采用服務網格(Service Mesh)(如 Istio, Linkerd),它們會在 Pod 之間自動進行 mTLS 加密。這樣,從 Ingress Controller 到后端服務的鏈路也是加密的。另一種方案是使用 SSL Passthrough,即負載均衡器不終止 TLS,而是將加密的流量直接透傳給 Ingress Controller。但這會失去上述所有優點(性能開銷、高級路由等),并將證書管理的負擔轉移回集群內部,因此不常用。