metallb: externalTrafficPolicy does not preserve IP anymore (L2 mode)
- The bug itself, as detailed as you can.
After upgrading some clusters to k8s 1.15.6, target pod cant see source IP anymore. LB service are configured with externalTrafficPolicy: Local
.
Traffic effectively flows only to the local pod, but the ClientIP is the node one.
- Version of MetalLB
0.8.3
- Version of Kubernetes
1.15.6-rancher1-2
- Name and version of network addon (e.g. Calico, Weave…)
Flannel + Calico (Canal)
- Whether you’ve configured kube-proxy for iptables or ipvs mode
iptables mode.
I tracked rules for a LB service (public IP is hidden) :
# iptables-save |grep GS7VUV4NFC2NA6UK
:KUBE-FW-GS7VUV4NFC2NA6UK - [0:0]
:KUBE-SVC-GS7VUV4NFC2NA6UK - [0:0]
:KUBE-XLB-GS7VUV4NFC2NA6UK - [0:0]
-A KUBE-FW-GS7VUV4NFC2NA6UK -m comment --comment "traefik/traefik:webs loadbalancer IP" -j KUBE-XLB-GS7VUV4NFC2NA6UK
-A KUBE-FW-GS7VUV4NFC2NA6UK -m comment --comment "traefik/traefik:webs loadbalancer IP" -j KUBE-MARK-DROP
-A KUBE-NODEPORTS -p tcp -m comment --comment "traefik/traefik:webs" -m tcp --dport 31163 -j KUBE-XLB-GS7VUV4NFC2NA6UK
-A KUBE-SERVICES -d 10.43.238.216/32 -p tcp -m comment --comment "traefik/traefik:webs cluster IP" -m tcp --dport 443 -j KUBE-SVC-GS7VUV4NFC2NA6UK
-A KUBE-SERVICES -d xxx.xxx.xxx.xxx/32 -p tcp -m comment --comment "traefik/traefik:webs loadbalancer IP" -m tcp --dport 443 -j KUBE-FW-GS7VUV4NFC2NA6UK
-A KUBE-SVC-GS7VUV4NFC2NA6UK -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-7COCHRO3VKLLNBYW
-A KUBE-SVC-GS7VUV4NFC2NA6UK -j KUBE-SEP-YVVGR5GWIKLB47FM
-A KUBE-XLB-GS7VUV4NFC2NA6UK -m comment --comment "masquerade LOCAL traffic for traefik/traefik:webs LB IP" -m addrtype --src-type LOCAL -j KUBE-MARK-MASQ
-A KUBE-XLB-GS7VUV4NFC2NA6UK -m comment --comment "route LOCAL traffic for traefik/traefik:webs LB IP to service chain" -m addrtype --src-type LOCAL -j KUBE-SVC-GS7VUV4NFC2NA6UK
-A KUBE-XLB-GS7VUV4NFC2NA6UK -s 10.42.0.0/16 -m comment --comment "Redirect pods trying to reach external loadbalancer VIP to clusterIP" -j KUBE-SVC-GS7VUV4NFC2NA6UK
-A KUBE-XLB-GS7VUV4NFC2NA6UK -m comment --comment "Balancing rule 0 for traefik/traefik:webs" -j KUBE-SEP-YVVGR5GWIKLB47FM
# iptables-save |grep YVVGR5GWIKLB47FM
:KUBE-SEP-YVVGR5GWIKLB47FM - [0:0]
-A KUBE-SEP-YVVGR5GWIKLB47FM -s 10.42.2.98/32 -j KUBE-MARK-MASQ
-A KUBE-SEP-YVVGR5GWIKLB47FM -p tcp -m tcp -j DNAT --to-destination 10.42.2.98:443
-A KUBE-SVC-GS7VUV4NFC2NA6UK -j KUBE-SEP-YVVGR5GWIKLB47FM
-A KUBE-XLB-GS7VUV4NFC2NA6UK -m comment --comment "Balancing rule 0 for traefik/traefik:webs" -j KUBE-SEP-YVVGR5GWIKLB47FM
I’m not fluent with kube-proxy/iptables, but couldn’t masquerade rule be the cause ?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 16 (7 by maintainers)
We got it working 😉 In our Service-Spec we had both loadBalancerIP AND externalIPs set to the loadbalanced-ip. The latter one was a remainder of TungstenFabric-SDN.
So it looked like this
According to https://kubernetes.io/blog/2018/07/09/ipvs-based-in-cluster-load-balancing-deep-dive/ as soon as you have “Service External IP + port” it masqurades. But with loadbalancerIP PLUS externalTrafficPolicy=local traffic is just accepted.
So we removed the externalIPs-configuration from the service-manifest, and immediately the real-client IP shows up.
@remche check if you also have a similar-configuration