Closed chino closed 4 years ago
@chino Agree, it looks like we're not playing nice with kube-proxy's rules there but I think k8s now has a work-around for the blackhole part of this:
See:
Can you check whether the conntrack entries get cleaned up when you add an endpoint to the service?
My example manifest above has endpoints that appear later but it still wasn't working.
The calico tutorials use v1.7.0
I believe the changes should be in v1.7.1+
I tried with v1.7.4 but still ran into the issue
Which lead me to find that the conntrack
tool that kube-proxy calls isn't available in coreos:
Aug 24 23:51:20 k8s-node-02 kube-proxy[1452]: E0824 23:51:20.362870 1452 conntrack.go:42] conntrack returned error: error looking for path of conntrack: exec: "conntrack": executable file not found in $PATH
I split the vagrant part of this out into https://github.com/projectcalico/calico/issues/1058
I can confirm the issues is fixed in k8s v1.7.4 when endpoints are added. I added notes explaining how to fix up the vagrant tutorials to #1058.
It appears the conversation of sending REJECTs via the FORWARD table is happening over at: https://github.com/kubernetes/kubernetes/issues/48719
I see two options here:
cali-FORWARD
after the KUBE-SERVICES
rule in the filter:FORWARD
table. Excerpt from the table as it is now:
# iptables -n -t filter --line-numbers -L FORWARD
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 cali-FORWARD all -- 0.0.0.0/0 0.0.0.0/0 /* cali:wUHhoiAYhphO9Mso */
2 KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0
...
If the KUBE-SERVICES rule comes first then the standard reject rules for services without endpoints will get hit.
The other option is to not explicitly ACCEPT
in the cali-forward table. So that the rest of the forward rules get processed like normal. Ex: don't put in rule #4 below.
iptables -n -t filter --line-numbers -L cali-FORWARD
Chain cali-FORWARD (1 references)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 /* cali:jxvuJjmmRV135nVu */ mark match 0x1000000/0x1000000 ctstate UNTRACKED
2 cali-from-wl-dispatch all -- 0.0.0.0/0 0.0.0.0/0 /* cali:nu_3aWP3DUkeeFF6 */
3 cali-to-wl-dispatch all -- 0.0.0.0/0 0.0.0.0/0 /* cali:DjrV_uMYqr-g4joA */
4 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 /* cali:Hl34eZwIcbzmic3y */
...
And then the packet will drop back to the FORWARD
table and eventually get rejected in KUBE-SERVICES
if there are no endpoints
I've tested both options by disabling felix and removing/updating the rules manually. Both resulted in the proper rejection when services had no endpoints.
@carsonoid I believe we have a config option to change the ACCEPT to a RETURN, see IptablesAllowAction (FELIX_IPTABLESALLOWACTION)
in https://docs.projectcalico.org/v2.5/reference/felix/configuration
xref k8s PR: https://github.com/kubernetes/kubernetes/issues/60124#issuecomment-369322795
I suggested to use RETURN instead of ACCEPT in that case as well. Relies on kube-proxy accepting the traffic when there are endpoints, which it should do if --cluster-cidr
is set.
Hm, I guess this still hasn't moved forward?
Using Calico 3.0.6 with k8s 1.10.4, I've tried setting FELIX_IPTABLESFILTERALLOWACTION
to RETURN
, FELIX_IPTABLESMANGLEALLOWACTION
to RETURN
and FELIX_DEFAULTENDPOINTTOHOSTACTION
to RETURN
, and it does not make any difference. Services with no endpoints keep hanging instead of refusing.
CALICO_IPV4POOL_CIDR
matches with kube-proxy
's --cluster-cidr
as well.
Reading comments in #1058, and considering I'm using official kube container images (that contain nothing but single go binary), could it be that kube-proxy does not have access to conntrack
?
@tuminoid Yes, that's possible. I'm also not sure that kube-proxy ever got a fix for this.
Quick update. I rebuilt our k8s containers with k8s 1.11.2 and added conntrack
for kube-proxy
, no change in behavior. Connections still hang.
k8s has merged kubernetes/kubernetes#72534 in kube-proxy for upcoming 1.14 release, which should fix this issue.
We started adding e2e tests for network plugins for kubernetes/kops and noticed that this is still an issue. Any plans for a fix? https://testgrid.k8s.io/sig-cluster-lifecycle-kops#kops-aws-cni-calico
@hakman thanks for poking this one. There hasn't been much activity in this area. I think it makes sense to fix, but I don't currently have a timeline / priority for it. Anyone interested in proposing and submitting a patch? Would love to review it :heart:
xposting here since I believe this is the same issue: https://github.com/projectcalico/calico/issues/3548
For posterity: https://github.com/projectcalico/felix/pull/2424
When a client connects/sends to a service
with no endpoints
it appears to incorrectly be forwarded to the default gateway. This creates aconntrack
entry that blackholes the client even after endpoints are later added. TCP will recover from a failed handshake but UDP clients can keep the conntrack entry alive forever if they keep trying to send packets from the same source port.I believe it should normally be REJECTed by the KUBE-SERVICES chain:
However it appears that the
cali-FORWARD
chain handles the packet first (notice the counters):There is some udp conntrack clearing code in kube-proxy but it's only for when
endpoints are removed
and I didn't see anything that would try to reconcile possibly broken conntrack entries that may exist for other reasons:Steps to Reproduce (for bugs)
My kubernetes setup was simply based on calico's vagrant tutorial:
Example k8s manifests:
Conntrack shows the following:
Other info: