Networking

具有 externalTrafficPolicy=local 的 k8s 負載均衡器服務通過 IPv4 上的客戶端 IP,在 IPv6 上隱藏它

  • June 18, 2021

我無法讓 kubernetes IPv6SingleStack LoadBalancer服務通過正確的源 IP 地址傳遞到 pod。SingleStack LoadBalancer它在將流量傳遞到相同 pod的姊妹 IPv4 上執行良好。

該集群是一個裸機 v1.21.1 雙棧集群kubeadm,使用 Calico v3.18 作為 cni 和 MetalLB 來為配置了type: LoadBalancer. 然後將 Calico 配置為通過 BGP 向本地路由器宣布負載均衡器 IP。以具有兩個服務(一個用於 IPv4,一個用於 IPv6)的單個nginx部署為例,如果我通過 IPv4 地址捲曲 IP,則 nginx 訪問日誌會在以下位置列印正確的客戶端 IP 192.168.2.0/24

192.168.2.128 - - [01/Jun/2021:19:32:37 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"

但是將來自同一客戶端的 IPv6 地址捲曲在 中2001:8b0:c8f:e8b0::/64,nginx 顯示的客戶端 IP 地址為fd5a:1111:1111::f31f

fd5a:1111:1111::f31f - - [01/Jun/2021:19:34:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"

該地址來自集群的serviceSubnetfd5a:1111:1111::/112並且恰好是clusterIPIPv6 服務的地址。似乎有些東西實際上在這裡做了一些 TCP 代理(ipvs?),但目前尚不清楚它為什麼會這樣。externalTrafficPolicy如果是的話,我會期待Cluster- 事實上,如果我將服務從 更改LocalCluster,我將獲得在 IPv4 上轉發請求的集群節點的本地 IP 地址(如預期的那樣),以及在 IPv6 上相同的 clusterIP 地址。externalTrafficPolicy在 IPv6 的情況下似乎沒有效果。

我是否遺漏了一些明顯的東西,或者這些服務的行為方式是否應該相同?

測試清單:

---
apiVersion: v1
kind: Service
metadata:
 name: test-service-source-ip-v4
 namespace: default
 labels:
   k8s-app: test-service-source-ip
spec:
 selector:
   k8s-app: test-service-source-ip
 type: LoadBalancer
 ipFamilies:
   - IPv4
 ipFamilyPolicy: SingleStack
 loadBalancerIP: 192.168.254.11
 externalTrafficPolicy: "Local"
 ports:
   - name: http-tcp
     protocol: TCP
     port: 80
---
apiVersion: v1
kind: Service
metadata:
 name: test-service-source-ip-v6
 namespace: default
 labels:
   k8s-app: test-service-source-ip
spec:
 selector:
   k8s-app: test-service-source-ip
 type: LoadBalancer
 ipFamilies:
   - IPv6
 ipFamilyPolicy: SingleStack
 loadBalancerIP: 2001:8b0:c8f:e8b1:beef:f00d::11
 externalTrafficPolicy: "Local"
 ports:
   - name: http-tcp
     protocol: TCP
     port: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
 namespace: default
 name: test-service-source-ip
 labels:
   k8s-app: test-service-source-ip
spec:
 replicas: 1
 selector:
   matchLabels:
     k8s-app: test-service-source-ip
 template:
   metadata:
     labels:
       k8s-app: test-service-source-ip
   spec:
     containers:
       - name: test-service-source-ip
         image: nginx:1
         ports:
           - containerPort: 80
             protocol: TCP

事實證明,我有一個舊的ip-masq-agent執行安裝,它被配置為錯誤地對進出集群的 IPv6 流量進行 natting。我通過查看ip6tables規則並查看MASQUERADEip-masq-agent.

從集群中刪除此部署並重新啟動節點以刪除ip6tables規則解決了該問題。

引用自:https://serverfault.com/questions/1065356