具有 externalTrafficPolicy=local 的 k8s 負載均衡器服務通過 IPv4 上的客戶端 IP,在 IPv6 上隱藏它
我無法讓 kubernetes IPv6
SingleStack
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 訪問日誌會在以下位置列印正確的客戶端 IP192.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" "-"
該地址來自集群的
serviceSubnet
,fd5a:1111:1111::/112
並且恰好是clusterIP
IPv6 服務的地址。似乎有些東西實際上在這裡做了一些 TCP 代理(ipvs?),但目前尚不清楚它為什麼會這樣。externalTrafficPolicy
如果是的話,我會期待Cluster
- 事實上,如果我將服務從 更改Local
為Cluster
,我將獲得在 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
規則並查看MASQUERADE
由ip-masq-agent
.從集群中刪除此部署並重新啟動節點以刪除
ip6tables
規則解決了該問題。