適用範圍:騰訊雲容器服務(Tencent Kubernetes Engine ,TKE), 如下簡稱 TKE。nginx
當須要能感知到服務請求來源去知足一些業務需求時,就須要後端服務能準確獲取到請求客戶端的真實源 IP, 好比如下場景:後端
在TKE中默認的外部負載均衡器是 騰訊雲負載均衡器,做爲服務流量的訪問首入口,騰訊雲負載均衡器會將請求流量負載轉發到 Kubernetes 工做節點的 Kubernets Service(默認),此負載均衡過程會保留客戶端真實源 IP(透傳轉發),但在 Kubernetes Service 轉發場景下,不管是使用 iptbales 仍是 ipvs 的負載均衡轉發模式,轉發時都會對數據包作 SNAT,即不會保留客戶端真實源 IP,爲了可以準確的獲取到客戶端的真實源 IP,在 TKE 使用場景下,主要有四種方法獲取客戶端真實源 IP,下面將逐個展開介紹下。api
要啓用保留客戶端 IP 功能,可在 Service 資源中配置字段 Service.spec.externalTrafficPolicy
,此字段表示服務是否但願將外部流量路由到節點本地或集羣範圍的端點。有兩個選項值:Cluster
(默認)和 Local
方式,以下圖所示:安全
Cluster
表示隱藏了客戶端源 IP, LoadBalancer
和 NodePort
類型服務流量可能會被轉發到其餘節點的 Pods; Local
表示保留客戶端源 IP 並避免 LoadBalancer
和 NodePort
類型的服務流量轉發到其餘節點的 Pods,詳情請參考 kubernets設置外部負載均衡器說明。相關 YAML 配置示例以下:服務器
apiVersion: v1 kind: Service metadata: name: example-Service spec: selector: app: example-Service ports: - port: 8765 targetPort: 9376 externalTrafficPolicy: Local type: LoadBalancer
優勢:只須要修改 Kubernets Service 資源配置便可。網絡
缺點:會存在潛在的 Pods(Endpoints)流量負載不均衡風險。app
使用TKE原生支持的 CLB 直通 Pod 的轉發功能(CLB 透傳轉發,並繞過 Kubernetes Service 流量轉發),後端 Pods 收到的請求的源IP便是客戶端真實源IP,此方式不管是在四層仍是七層服務的轉發場景下都適用,轉發原理以下圖:負載均衡
詳細介紹和配置請參考文檔 TKE場景下騰訊雲CLB直通Pod使用場景介紹。ide
優勢:TKE原生支持的功能特性,只需在控制檯按照文檔配置便可。函數
缺點:集羣須要開啓 VPC-CNI 模式網絡,詳情參考文檔 VPC-CNI 模式說明
在七層(HTTP/HTTPS)服務轉發場景下,能夠經過獲取 Http Header 中 X-Forwarded-For
和 X-Real-IP
字段的值來獲取客戶端真實源 IP, TKE 中有兩種場景使用方式,原理介紹以下:
在場景一中,騰訊雲負載均衡器(CLB 七層) 默認會將客戶端真實源IP放到 HTTP Header 的 X-Forwarded-For
和 X-Real-IP
字段,當服務流量在通過 Service 四層轉發後會保留上述字段,後端經過WEB服務器代理配置或應用代碼方式獲取到客戶端真實源IP,詳情參考請文檔 負載均衡如何獲取客戶端真實 IP - 最佳實踐 - 文檔中心 - 騰訊雲;
在場景二中, Nginx Ingress 服務部署須要 Nginx Ingress 能直接感知客戶端真實源 IP,能夠採用保留客戶端源IP的配置方式(詳情參考 kubernets設置外部負載均衡器說明 ),或經過 CLB 直通 Pod 的方式(詳情參考 TKE場景下騰訊雲CLB直通Pod使用場景介紹),當 Nginx Ingress 在轉發請求時會經過 X-Forwarded-For
和 X-Real-IP
字段來記錄客戶端源 IP,後端能夠經過此字段得到客戶端真實源 IP。
下面詳細介紹在 TKE 中兩種場景的配置使用方法:
在TKE控制檯先爲工做負載建立一個主機端口訪問方式的 Service 資源,以下圖:
而後在控制檯爲 Service 新建一個對應的 Ingress 訪問入口,以下圖:
待配置生效後,在後端經過獲取 HTTP Header 中的 X-Forwarded-For
或 X-Real-IP
字段值獲得客戶端真實源 IP。後端抓包測試結果示例以下:
Nginx Ingress 能夠經過 TKE 應用商店、自定義 YAML 配置或使用官方(helm 安裝)方式安裝,原理和部署方法可參考文檔 在 TKE 上部署 Nginx Ingress 中的部署方案一或方案三,若選擇方案一部署,則須要修改 Nginx Ingress Controller Service 的 externalTrafficPolicy
字段值爲 Local
。安裝完成後,會在TKE控制檯自動爲 Nginx Ingress Controller 服務建立一個 CLB(四層)訪問入口,以下圖所示:
爲要轉發的後端服務建立一個 Ingress 資源並配置轉發規則, 能夠使用如下 YAML 建立:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx # ingressClass類爲"nginx" name: example namespace: default spec: rules: # 配置服務轉發規則 - http: paths: - backend: serviceName: nginx servicePort: 80 path: /
待配置生效後,在後端獲取 Http Header 中的 X-Forwarded-For
或 X-Real-IP
字段值獲得客戶端真實源 IP,後端抓包測試結果示例以下:
以上介紹的兩種場景均可以知足獲取客戶端真實源 IP 的需求,且具備如下優勢和缺點:
優勢:在七層(HTTP/HTTPS)流量轉發場景下比較推薦,可經過WEB服務代理的配置或後端應用代碼直接獲取 Http Header 中的字段便可拿到客戶端真實IP,很是簡單高效。
缺點:僅適用於七層(HTTP/HTTPS)流量轉發場景,不適用於四層轉發場景,若是是四層轉發場景,請使用後面介紹的其餘方式。
TOA 內核模塊原理和加載方式參考 全球應用加速 獲取訪問用戶真實 IP - 操做指南 - 文檔中心 - 騰訊雲 文檔。
優勢:對於 TCP 傳輸方式,在內核層面且僅對 TCP 鏈接的首包進行改造,幾乎沒有性能損耗。
缺點:
本文主要介紹了在TKE使用場景下服務端如何獲取客戶端真實源 IP,以知足用戶相關使用場景的需求,用戶可經過對比上述四幾種方式的優勢和缺點,選擇適合實際需求場景的最佳方案。