Open jaxklag opened 5 days ago
@jaxklag
When "externalTrafficPolicy: Cluster" set on service, source IP is preserved and not replaced with those of k8s node. Customer can reach external IP of the service from outside the k8s cluster.
That is not a bug, that is a feature! That make writing policies much simpler for you!
with "externalTrafficPolicy: Cluster" set on service, source IP must be SNAT with ip of k8s node.
Nope, there is no such requirement. It is just that kube-proxy in iptables mode does not have much options to do it better and thus does it this way. And thus they had to come up the the externalTrafficPolicy
mode to fix this issue and it also only select local pod so it saves the extra hop. If yo set it in ebpf dp, we also save the extra hop.
Hello @tomastigera
Thansk for your answer. I agree with you.
What about the fact that setting "Local" for externalTrafficPolicy cause the service to be unreachable ? Is it epexcted behaviour ?
I understand that this config parameter is useless with calico + ebpf dataplane but what about customers which can still use the externalTrafficPolicy parameter and as a consequence cause the service to be unreachble ?
Couldn't be ignored by Calico when ebpf is activated ?
Regards,
With Local
you may get service unreachable if your connections land on a node which does not have the backing pod. That would happen if your LB does not take this into account.
Seems like the kube-vip might the problem. I am not expert on that. What does it do exactly? All I know is that it may not play exacly well with ebpf dataplanes. https://github.com/kube-vip/kube-vip/issues/594
@jaxklag this may also be relevant https://github.com/projectcalico/calico/issues/9141
@tomastigera Thanks for your replies. I will study that Monday and come back to you with some information.
Does sysctl parameters still apply/ have incidence on network traffic handle by ebpf ?
I remember that i must set some specific sysctl config with DSR on standard linux traffic without k8s.
Actually, i didn't configured any sysctl for DSR on ens192 interface.
Regards,
@tomastigera
With
Local
you may get service unreachable if your connections land on a node which does not have the backing pod. That would happen if your LB does not take this into account.
Scaling replica to have a pod on k8s node named "k8sw1" (which has the LoadBalancer IP), make it works with externalTrafficPolicy set to "Local"
You were right.
On my side there is a misunderstanding on the use case of the "Local" parameter rather than "Cluster" with ebpf dataplane.
With ebpfs, as you explained previously, "Cluster" does the job preserving IP source and load-balancaing accros all the pod replica even when there is no pod on the node with the LoadBalancer IP.
"Local" prevents load-balancing on all the replicas of the pod since only the replica present on the node carrying the IP of the LoadBlancer service will receive traffic. Is Calico-node responsible of that decision ? Why this choice with ebpf backend ?
Regards,
Seems like the kube-vip might the problem. I am not expert on that. What does it do exactly? All I know is that it may not play exacly well with ebpf dataplanes. kube-vip/kube-vip#594
- I'd turn off the DSR mode to start with not to introduce more variables into this.
- It would be good to se a tcpdump of traffic within the host that has the pod.
- In one of the tcpdump you provided it seems like you are making a connection from a pod. Note that externalTrafficPolicy does not apply to local traffic. There is internalTrafficPolicy option as well.
- It would be good to see routing tables within that node
- Eventually we may want to see debug logs from ebpf (BPFLogLevel=Debug)
I don't think so because even without kube-vip i had the same results. Cf. my previous answer which spots that the problem was that there was no pod replica running on the worker node with the LoadBalancer IP.
Regards
"Local" prevents load-balancing on all the replicas of the pod since only the replica present on the node carrying the IP of the LoadBlancer service will receive traffic. Is Calico-node responsible of that decision ? Why this choice with ebpf backend ?
That is how it is specified by k8s and its kube-proxy. We just follow the same behaviour.
Hello,
I'm facing a strange problem on a fresh install of calico with ebpf dataplane.
Maybe i've missed something in the configuration of ebpf dataplane ...
I give you all the info i have and i'm available to give you more trace if needed.
Thansks for your help !
Expected Behavior
with "externalTrafficPolicy: Cluster" set on service, source IP must be SNAT with ip of k8s node.with "externalTrafficPolicy: Local" set on service, source IP must be preserved and most of all, service must be reachable from outside the cluster.
Current Behavior
~~When "externalTrafficPolicy: Cluster" set on service, source IP is preserved and not replaced with those of k8s node. Customer can reach external IP of the service from outside the k8s cluster.~~
When "externalTrafficPolicy: Local" set on service, source IP. Customer can't reach external IP of the service. The customer network traffc ends on k8s node which have the external IP.
Steps to Reproduce (for bugs)
Go on k8s node named "k8sw1" with external IP configured on int ens192 (10.128.41.230)
We don't see dnat done in any tcpdump output done on all worker nodes !!
NAT rule from calico-node on "k8sw1" node. Pod IP are correct into nat rules. Don't know if the rule has the expected output.
I've got here a first problem. When externalTrafficPolicy is set to Local, it's impossible to reach the service via its external IP.
If i just replace externalTrafficPolicy from "Local" to "Cluster", service is reachable. See debug below.
Got answer from curl.
Go on k8s node named "k8sw1" with external IP configured on int ens192 (10.128.41.230)
We observed http traffic.
We do not see response packet because of DSR
I follow the HTTP traffic on k8s node named "k8sw3" with one of the nginx pod We observe the response is sent directly thanks to DSR.
The problem here is that the source IP is not replaced with the IP of k8sw1 node despite the Cluster mode of the service. Normal ?
NAT rule from calico-node on "k8sw1" & "k8sw3" nodes. Pod IP are correct into nat rules. Don't know if the rules have the expected output.
It works but there is no SNAT done on client source IP despite the Cluster setting for externalTrafficPolicy on the service.
Context
Quite simple.
Just want to have the choice to preserve or not the client IP source with ebpf dataplace and DSR activated. Just honor the value of the externalTrafficPolicy configured into the service.
Your Environment
Setup of calico using Kubespray v2.26.0 with traditionnal Linux dataplane.
Following Calico docs, activation of ebpf dataplane manually without using kubespray.
k8s cluster is not production. OS : Rocky Linux 9 with supported kernel
k8s version : 1.29.6
kube-proxy is disabled as suggested into calico documentation
calico version : 3.28.1 and then upgraded to 3.28.2. Same problem in both versions
Calico Bpf External Service Mode : "DSR" ==> Same problem with "Tunnel". Note that both mode are working as expected regarding the network path used for response packets
Kube-vip is used to allocate external IP for service type LoadBalancer and configure IP on worker node.
Note thant even without kube-vip the problem happens.