Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClusterwideNetworkPolicy causes intermittent connection problems to k8s API #32698

Open
3 tasks done
baurmatt opened this issue May 24, 2024 · 14 comments
Open
3 tasks done
Labels
info-completed The GH issue has received a reply from the author kind/bug This is a bug in the Cilium logic. kind/community-report This was reported by a user in the Cilium community, eg via Slack. sig/agent Cilium agent related. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies.

Comments

@baurmatt
Copy link

baurmatt commented May 24, 2024

Is there an existing issue for this?

  • I have searched the existing issues

What happened?

We're running Cilium with egress/ingress CiliumClusterwideNetworkPolicy/CiliumNetworkPolicy to ensure all traffic must be explicitly allowed:

apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: deny-all
spec:
  description: Deny all traffic by default.
  endpointSelector: {}
  ingress:
    - {}
  egress:
    - {}
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: deny-all-host
spec:
  description: Deny all traffic by default.
  nodeSelector: {}
  ingress:
...
  egress:
 ...
    - toEntities:
        - kube-apiserver
 ...

This works fine - until it doesn't :)

From time to time, worker nodes are getting NotReady and stay there until manual interaction. Investigating deeper it turned out that the worker nodes aren't able to reach the Kubernetes API and thus kubelet/Cilium isn't functional anymore.

Kubelet Log:

root@fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v:~# journalctl -u kubelet --since '1 hour ago' --lines 2
May 24 06:49:18 fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v kubelet[718]: E0524 06:49:18.561511     718 event.go:289] Unable to write event: '&v1.Event{TypeMeta:v1.TypeMeta{Kind:"", APIVersion:""}, ObjectMeta:v1.ObjectMeta{Name:"node-local-dns-6lprl.17d1e77cc4ae555c", GenerateName:"", Namespace:"kube-system", SelfLink:"", UID:"", ResourceVersion:"", Generation:0, CreationTimestamp:time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), DeletionTimestamp:<nil>, DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string(nil), ManagedFields:[]v1.ManagedFieldsEntry(nil)}, InvolvedObject:v1.ObjectReference{Kind:"Pod", Namespace:"kube-system", Name:"node-local-dns-6lprl", UID:"d8ea403f-dace-478e-b6cc-2ee7dcad3df1", APIVersion:"v1", ResourceVersion:"35076729", FieldPath:""}, Reason:"FailedMount", Message:"MountVolume.SetUp failed for volume \"kube-api-access-wrqkj\" : failed to fetch token: Post \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/api/v1/namespaces/kube-system/serviceaccounts/node-local-dns/token\": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out", Source:v1.EventSource{Component:"kubelet", Host:"fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v"}, FirstTimestamp:time.Date(2024, time.May, 22, 19, 50, 56, 66590044, time.Local), LastTimestamp:time.Date(2024, time.May, 23, 10, 13, 10, 402818080, time.Local), Count:70, Type:"Warning", EventTime:time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), Series:(*v1.EventSeries)(nil), Action:"", Related:(*v1.ObjectReference)(nil), ReportingController:"kubelet", ReportingInstance:"fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v"}': 'Patch "https://27sdd5kjmq.dus2-1.REDACTED.org:30153/api/v1/namespaces/kube-system/events/node-local-dns-6lprl.17d1e77cc4ae555c": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out'(may retry after sleeping)
May 24 06:49:20 fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v kubelet[718]: E0524 06:49:20.993363     718 webhook.go:154] Failed to make webhook authenticator request: Post "https://27sdd5kjmq.dus2-1.REDACTED.org:30153/apis/authentication.k8s.io/v1/tokenreviews": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out

Cilium Agent Log:

root@fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v:~# nerdctl --namespace k8s.io logs $(nerdctl --namespace k8s.io ps -a| grep cilium-agent | tail -n 1 | awk '{print $1}') --tail 10
level=info msg="Establishing connection to apiserver" host="https://27sdd5kjmq.dus2-1.REDACTED.org:30153" subsys=k8s-client
level=info msg="Establishing connection to apiserver" host="https://27sdd5kjmq.dus2-1.REDACTED.org:30153" subsys=k8s-client
level=info msg="Establishing connection to apiserver" host="https://27sdd5kjmq.dus2-1.REDACTED.org:30153" subsys=k8s-client
level=error msg="Unable to contact k8s api-server" error="Get \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/api/v1/namespaces/kube-system\": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out" ipAddr="https://27sdd5kjmq.dus2-1.REDACTED.org:30153" subsys=k8s-client
level=error msg="Start hook failed" error="Get \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/api/v1/namespaces/kube-system\": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out" function="client.(*compositeClientset).onStart" subsys=hive
level=info msg=Stopping subsys=hive
level=info msg="Stop hook executed" duration="482.18µs" function="metrics.NewRegistry.func2 (pkg/metrics/registry.go:96)" subsys=hive
level=info msg="Stopped gops server" address="127.0.0.1:9890" subsys=gops
level=info msg="Stop hook executed" duration="578.108µs" function="gops.registerGopsHooks.func2 (pkg/gops/cell.go:50)" subsys=hive
level=fatal msg="failed to start: Get \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/api/v1/namespaces/kube-system\": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out" subsys=daemon

With the help of nerdctl I was able to manually start the Cilium Agent container:

root@fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v:~# nerdctl --namespace k8s.io start --attach $(nerdctl --namespace k8s.io ps -a| grep cilium-agent | tail -n 1 | awk '{print $1}')
...

This allowed me to interact with Cilium directly, but this wasn't much fruitful because the Cilium (and Monitor/...) socket isn't there yet - probably because the Kubernetes API still can't be reach:

root@fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v:/tmp# nerdctl --namespace k8s.io exec -it $(nerdctl --namespace k8s.io ps --filter name=k8s://kube-system/cilium-mm6hw/cilium-agent --latest -q) cilium identity list
Error: Cannot get identities for given labels []. err: Get "http://localhost/v1/identity": dial unix /var/run/cilium/cilium.sock: connect: no such file or directory

FATA[0000] exec failed with exit code 1

But it gave some insights and showed that there isn't a matching Egress rule anymore for the IP of the Kubernetes API:

root@fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v:/tmp# nerdctl --namespace k8s.io exec -it $(nerdctl --namespace k8s.io ps --filter name=k8s://kube-system/cilium-mm6hw/cilium-agent --latest -q) cilium bpf ipcache list | grep 109.68.xxx.yyy
109.68.xxx.yyy/32     identity=16777325 encryptkey=0 tunnelendpoint=0.0.0.0
root@fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-snt6v:/tmp# nerdctl --namespace k8s.io exec -it $(nerdctl --namespace k8s.io ps --filter name=k8s://kube-system/cilium-mm6hw/cilium-agent --latest -q) cilium bpf policy list | grep 16777325
Was impossible to retrieve label ID 16777325: Get "http://localhost/v1/identity/16777325": dial unix /var/run/cilium/cilium.sock: connect: no such file or directory
Allow    Ingress     16777325                      22/TCP       NONE         disabled    0             0          24

My guess (and I don't have much experience with Cilium/BPF or networking in general 🙈) what happening is: Cilium looses its mapping from kube-apiserver to the IP and isn't able to recover from that.

Temporary workaround for us is:

root@fb75189d-8291-4b73-baeb-6010916aecbd-7855768f7f-j9jbk:~# iptables -D CILIUM_OUTPUT -m comment --comment "cilium: host->any mark as from host" -j MARK --set-xmark 0xc00/0xf00

This deletes the iptables jump to the bpf firewalling (?) and thus allows access to the Kubernetes API again. This allows Cilium to fully restart and bootstrap itself. Afterwards everythings seems to be back to normal.

Cilium Version

1.15.2

Kernel Version

5.15.0-100-generic

Kubernetes Version

1.28.7

Regression

Not sure when it started, but we're seeing it for a couple of months and mostly doing update relatively fast after release.

Sysdump

cilium-bugtool-20240524-131108.522+0000-UTC-3443698366.zip

Relevant log output

2024-05-22 21:36:02.358	level=error msg=k8sError error="github.com/cilium/cilium/pkg/k8s/informer/informer.go:46: Failed to watch *v2.CiliumNode: failed to list *v2.CiliumNode: Get \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/apis/cilium.io/v2/ciliumnodes?resourceVersion=58814000\": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out" subsys=k8s
2024-05-22 21:36:02.358	level=warning msg="github.com/cilium/cilium/pkg/k8s/informer/informer.go:46: failed to list *v2.CiliumNode: Get \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/apis/cilium.io/v2/ciliumnodes?resourceVersion=58814000\": dial tcp 109.68.xxx.yyy:30153: connect: connection timed out" subsys=klog
2024-05-22 21:35:59.313	level=info msg="Envoy: Version 99c1c8f42c8de70fc8f6dd594f4a425cd38b6688/1.27.3/Distribution/RELEASE/BoringSSL" subsys=envoy-manager
2024-05-22 21:35:56.440	level=error msg=k8sError error="github.com/cilium/cilium/pkg/k8s/resource/resource.go:808: Failed to watch *v2.CiliumEndpoint: failed to list *v2.CiliumEndpoint: Get \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/apis/cilium.io/v2/ciliumendpoints?resourceVersion=58813701\": read tcp 192.168.130.138:59304->109.68.xxx.yyy:30153: read: connection timed out" subsys=k8s
2024-05-22 21:35:56.440	level=warning msg="github.com/cilium/cilium/pkg/k8s/resource/resource.go:808: failed to list *v2.CiliumEndpoint: Get \"https://27sdd5kjmq.dus2-1.REDACTED.org:30153/apis/cilium.io/v2/ciliumendpoints?resourceVersion=58813701\": read tcp 192.168.130.138:59304->109.68.xxx.yyy:30153: read: connection timed out" subsys=klog
2024-05-22 21:35:56.439	level=error msg=k8sError error="github.com/cilium/cilium/pkg/k8s/informer/informer.go:46: Failed to watch *v2.CiliumNode: failed to list *v2.CiliumNode: unexpected error when reading response body. Please retry. Original error: read tcp 192.168.130.138:59304->109.68.xxx.yyy:30153: read: connection timed out" subsys=k8s
2024-05-22 21:35:56.438	level=warning msg="github.com/cilium/cilium/pkg/k8s/informer/informer.go:46: failed to list *v2.CiliumNode: unexpected error when reading response body. Please retry. Original error: read tcp 192.168.130.138:59304->109.68.xxx.yyy:30153: read: connection timed out" subsys=klog
2024-05-22 21:35:56.438	level=error msg="Unexpected error when reading response body: read tcp 192.168.130.138:59304->109.68.xxx.yyy:30153: read: connection timed out" subsys=klog
2024-05-22 21:35:56.437	Unexpected error when reading response body: read tcp 192.168.130.138:59304->109.68.xxx.yyy:30153: read: connection timed out
2024-05-22 21:35:55.689	level=info msg="FQDN garbage collector work deleted 3 name entries: logs-msvc.REDACTED2.org.,kubernetes.default.svc.cluster.local.,google.com." controller=dns-garbage-collector-job subsys=fqdn
2024-05-22 21:35:48.264	level=info msg="Imported CiliumNetworkPolicy" ciliumNetworkPolicyName=deny-all-host k8sApiVersion=cilium.io/v2 k8sNamespace= subsys=k8s-watcher
2024-05-22 21:35:48.264	level=info msg="Policy imported via API, recalculating..." policyAddRequest=61505eda-1cca-4fc4-8f6c-0d7e38c3d256 policyRevision=226 subsys=daemon
2024-05-22 21:35:48.264	level=info msg="Policy Add Request" ciliumNetworkPolicy="[&{EndpointSelector:{} NodeSelector:{} Ingress:[{IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[remote-node health] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc000859fc0 requirements:0xc000898618 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.health: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[remote-node] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:8472 Protocol:UDP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[world] aggregatedSelectors:[{LabelSelector:0xc000859ee0 requirements:0xc000898378 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.world: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc000859f00 requirements:0xc0008983d8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.world-ipv4: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc000859f20 requirements:0xc000898438 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.world-ipv6: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:22 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[remote-node health] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc000859fc0 requirements:0xc000898618 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.health: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:4240 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[{\"matchLabels\":{\"any:app.kubernetes.io/name\":\"grafana-agent\",\"k8s:io.kubernetes.pod.namespace\":\"k8s-monitoring\"}}] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[]} ToPorts:[{Ports:[{Port:10250 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[{\"matchLabels\":{\"any:app\":\"konnectivity-agent\",\"k8s:io.kubernetes.pod.namespace\":\"kube-system\"}}] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[]} ToPorts:[{Ports:[{Port:10250 Protocol:TCP} {Port:9253 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[{\"matchLabels\":{\"any:app\":\"metrics-server\",\"k8s:io.kubernetes.pod.namespace\":\"kube-system\"}}] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[]} ToPorts:[{Ports:[{Port:10250 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[{\"matchLabels\":{\"any:app.kubernetes.io/name\":\"grafana-agent\",\"k8s:io.kubernetes.pod.namespace\":\"k8s-monitoring\"}}] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[]} ToPorts:[{Ports:[{Port:9965 Protocol:TCP} {Port:9962 Protocol:TCP} {Port:9963 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[{\"matchLabels\":{\"any:app.kubernetes.io/name\":\"hubble-relay\",\"k8s:io.kubernetes.pod.namespace\":\"kube-system\"}}] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[]} ToPorts:[{Ports:[{Port:4244 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR:[192.168.128.0/20] FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[{LabelSelector:0xc001040b60 requirements:0xc004666a68 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.192.168.128.0/20: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[] ICMPs:[] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR:[192.168.1.0/24] FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[{LabelSelector:0xc001040c80 requirements:0xc004666af8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.192.168.1.0/24: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[] ICMPs:[{Fields:[{Family:IPv4 Type:0}]}] Authentication:<nil>} {IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR:[192.168.1.0/24] FromCIDRSet:[] FromEntities:[] aggregatedSelectors:[{LabelSelector:0xc001040dc0 requirements:0xc004666b70 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.192.168.1.0/24: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:22 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ICMPs:[] Authentication:<nil>}] IngressDeny:[] Egress:[{EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR: ToCIDRSet:[] ToEntities:[remote-node health] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc000859fc0 requirements:0xc000898618 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.health: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:4240 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR: ToCIDRSet:[] ToEntities:[remote-node health] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc000859fc0 requirements:0xc000898618 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.health: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR: ToCIDRSet:[] ToEntities:[remote-node] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:8472 Protocol:UDP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR:[37.123.105.116/32,37.123.105.117/32] ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc001041d60 requirements:0xc0046673f8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.37.123.105.116/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc001041de0 requirements:0xc004667470 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.37.123.105.117/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:53 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>} {Ports:[{Port:53 Protocol:UDP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[{\"matchExpressions\":[{\"key\":\"k8s:io.kubernetes.pod.namespace\",\"operator\":\"Exists\"}]}] ToRequires:[] ToCIDR: ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[]} ToPorts:[] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR: ToCIDRSet:[] ToEntities:[kube-apiserver] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc0008b2020 requirements:0xc000898738 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.kube-apiserver: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR:[37.123.106.227/32,77.247.83.70/32,37.49.153.113/32,37.123.106.64/32] ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc001041f00 requirements:0xc0046674d0 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.37.123.106.227/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc001041f60 requirements:0xc004667548 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.77.247.83.70/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc001041fc0 requirements:0xc0046675c0 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.37.49.153.113/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc001246000 requirements:0xc004667620 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.37.123.106.64/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:8776 Protocol:TCP} {Port:5000 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR:[185.125.190.57/32,185.125.190.58/32,91.189.91.157/32,185.125.190.56/32] ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc001246040 requirements:0xc004667680 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.185.125.190.57/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc0012460a0 requirements:0xc0046676f8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.185.125.190.58/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc0012460e0 requirements:0xc004667770 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.91.189.91.157/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc001246120 requirements:0xc0046677d0 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.185.125.190.56/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:123 Protocol:UDP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR: ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[]} ToPorts:[{Ports:[{Port:443 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR:[192.168.128.0/20] ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc001246180 requirements:0xc004667848 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.192.168.128.0/20: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:67 Protocol:UDP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR:[91.189.91.122/32,185.125.190.38/32,185.125.190.41/32,91.189.91.121/32] ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc001246220 requirements:0xc0046678c0 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.91.189.91.122/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc0012462c0 requirements:0xc004667938 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.185.125.190.38/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc001246300 requirements:0xc0046679b0 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.185.125.190.41/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}} {LabelSelector:0xc001246380 requirements:0xc004667a28 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.91.189.91.121/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:80 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>} {EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR:[169.254.169.254/32] ToCIDRSet:[] ToEntities:[] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc001246420 requirements:0xc004667aa0 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{cidr.169.254.169.254/32: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[{Ports:[{Port:80 Protocol:TCP}] TerminatingTLS:<nil> OriginatingTLS:<nil> ServerNames:[] Listener:<nil> Rules:<nil>}] ToFQDNs:[] ICMPs:[] Authentication:<nil>}] EgressDeny:[] Labels:[k8s:io.cilium.k8s.policy.derived-from=CiliumClusterwideNetworkPolicy k8s:io.cilium.k8s.policy.name=deny-all-host k8s:io.cilium.k8s.policy.uid=7ff887fa-54d3-4d35-adc9-e785c338347f] Description:Deny all traffic by default.}]" policyAddRequest=61505eda-1cca-4fc4-8f6c-0d7e38c3d256 subsys=daemon
2024-05-22 21:35:48.259	level=info msg="Imported CiliumNetworkPolicy" ciliumNetworkPolicyName=cilium-health-checks k8sApiVersion=cilium.io/v2 k8sNamespace= subsys=k8s-watcher
2024-05-22 21:35:48.259	level=info msg="Policy imported via API, recalculating..." policyAddRequest=77abc538-8c3b-4f70-a5b5-c87076d24b59 policyRevision=224 subsys=daemon
2024-05-22 21:35:48.258	level=info msg="Policy Add Request" ciliumNetworkPolicy="[&{EndpointSelector:{\"matchLabels\":{\"reserved:health\":\"\"}} NodeSelector:{} Ingress:[{IngressCommonRule:{FromEndpoints:[] FromRequires:[] FromCIDR: FromCIDRSet:[] FromEntities:[remote-node] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[] ICMPs:[] Authentication:<nil>}] IngressDeny:[] Egress:[{EgressCommonRule:{ToEndpoints:[] ToRequires:[] ToCIDR: ToCIDRSet:[] ToEntities:[remote-node] ToServices:[] ToGroups:[] aggregatedSelectors:[{LabelSelector:0xc000859fa0 requirements:0xc0008985b8 cachedLabelSelectorString:&LabelSelector{MatchLabels:map[string]string{reserved.remote-node: ,},MatchExpressions:[]LabelSelectorRequirement{},}}]} ToPorts:[] ToFQDNs:[] ICMPs:[] Authentication:<nil>}] EgressDeny:[] Labels:[k8s:io.cilium.k8s.policy.derived-from=CiliumClusterwideNetworkPolicy k8s:io.cilium.k8s.policy.name=cilium-health-checks k8s:io.cilium.k8s.policy.uid=e678f83f-51f2-441f-8b41-b8f5f9b43416] Description:}]" policyAddRequest=77abc538-8c3b-4f70-a5b5-c87076d24b59 subsys=daemon
2024-05-22 21:35:43.799	level=info msg="regenerating all endpoints" reason="Kubernetes service endpoint added" subsys=endpoint-manager
2024-05-22 21:34:55.687	level=info msg="FQDN garbage collector work deleted 3 name entries: kubernetes.default.svc.cluster.local.,google.com.,logs-msvc.REDACTED2.org." controller=dns-garbage-collector-job subsys=fqdn
2024-05-22 21:33:55.687	level=info msg="FQDN garbage collector work deleted 3 name entries: logs-msvc.REDACTED2.org.,kubernetes.default.svc.cluster.local.,google.com." controller=dns-garbage-collector-job subsys=fqdn
2024-05-22 21:32:55.686	level=info msg="FQDN garbage collector work deleted 3 name entries: logs-msvc.REDACTED2.org.,kubernetes.default.svc.cluster.local.,google.com." controller=dns-garbage-collector-job subsys=fqdn
2024-05-22 21:31:55.684	level=info msg="FQDN garbage collector work deleted 3 name entries: kubernetes.default.svc.cluster.local.,google.com.,logs-msvc.REDACTED2.org." controller=dns-garbage-collector-job subsys=fqdn
2024-05-22 21:30:59.322	level=info msg="Envoy: Version 99c1c8f42c8de70fc8f6dd594f4a425cd38b6688/1.27.3/Distribution/RELEASE/BoringSSL" subsys=envoy-manager
2024-05-22 21:30:55.683	level=info msg="FQDN garbage collector work deleted 3 name entries: kubernetes.default.svc.cluster.local.,google.com.,logs-msvc.REDACTED2.org." controller=dns-garbage-collector-job subsys=fqdn

Anything else?

We have SSH access to broken nodes, logs in Loki and lots of metrics. If you need anything in particular to investigate this deeper, please let me know!

Also: It feels related to this issue -> #24502

Cilium Users Document

  • Are you a user of Cilium? Please add yourself to the Users doc

Code of Conduct

  • I agree to follow this project's Code of Conduct
@baurmatt baurmatt added kind/bug This is a bug in the Cilium logic. kind/community-report This was reported by a user in the Cilium community, eg via Slack. needs/triage This issue requires triaging to establish severity and next steps. labels May 24, 2024
@lmb lmb added sig/policy Impacts whether traffic is allowed or denied based on user-defined policies. sig/agent Cilium agent related. labels May 24, 2024
@lmb lmb changed the title Cilium denies egress traffic to kube-apiserver ClusterwideNetworkPolicy causes intermittent connection problems to k8s API May 24, 2024
@lmb
Copy link
Contributor

lmb commented May 24, 2024

Thanks for the report. Not having a sysdump is going to make it harder for us to diagnose unfortunately. Can you reproduce this if you upgrade to the latest point release?

@lmb lmb added the need-more-info More information is required to further debug or fix the issue. label May 24, 2024
@baurmatt
Copy link
Author

Hey @lmb, thanks for you answer! As mentioned, I've got quite few sysdumps. I just can't share them publicly. Should I share a link with you by mail?

We will attempt the latest point release update soon, but have little hope since this issue persistent for quite some time now.

@github-actions github-actions bot added info-completed The GH issue has received a reply from the author and removed need-more-info More information is required to further debug or fix the issue. labels May 24, 2024
@lmb
Copy link
Contributor

lmb commented May 24, 2024

I just can't share them publicly. Should I share a link with you by mail?

Sorry but we can't take responsibility for your confidential data. If that is something you need consider one of the enterprise vendors.

@baurmatt
Copy link
Author

baurmatt commented May 24, 2024

OK. I've attached one. Please let me know when you don't need it anymore. I will deleted it afterwards.

Edit: I've also me able to rollout the .dot version by now. Took only a couple of minutes for the first node to went into NotReady state. Seems like this didn't solve this bug.

@squeed
Copy link
Contributor

squeed commented May 27, 2024

This is a scary chicken-and-egg problem; the agent needs to be able to determine which IPs belong to the apiserver, and to do that, it needs access to the apiserver.

I would suggest enabling matching nodes via CIDR and then allowing access to the set of possible apiserver IPs.

@baurmatt
Copy link
Author

@squeed Thanks for you answer! I think that would be an option for when the pods are restarting, but I'd like to understand why those nodes loose the kube-apiserver identity in the first place. Those pods only restart, at least by my interpretation, because Cilium looses the kube-apiserver <-> CIDR mapping.

@squeed
Copy link
Contributor

squeed commented May 28, 2024

That is indeed interesting. We should probably log enough information to catch this in debug mode. If you like, you can enable debug mode globally in your cluster (set debug: true in your helm values) or on a per-node basis using per-node configuration overrides.

@baurmatt
Copy link
Author

baurmatt commented May 28, 2024

@squeed Got some debug logs while the error showed up 🥳

cilium-debug.log.zip

I think the relevant parts are:

$ ggrep -B2 -P '(^((?!EndpointSelector).)*kube-apiserver|Kubernetes service definition changed)' cilium-debug.log
2024-05-28T12:16:38+02:00 {} time="2024-05-28T10:16:38Z" level=debug msg="Processing 0 endpoints for EndpointSlice kubernetes" subsys=k8s
2024-05-28T12:16:38+02:00 {} time="2024-05-28T10:16:38Z" level=debug msg="EndpointSlice kubernetes has 0 backends" subsys=k8s
2024-05-28T12:16:38+02:00 {} time="2024-05-28T10:16:38Z" level=debug msg="Kubernetes service definition changed" action=service-updated endpoints= k8sNamespace=default k8sSvcName=kubernetes old-endpoints="109.68.224.35:30153/TCP" old-service=nil service="frontends:[10.106.0.1]/ports=[https]/selector=map[]" subsys=k8s-watcher
--
2024-05-28T12:16:38+02:00 {} time="2024-05-28T10:16:38Z" level=debug msg="Upserting IP into ipcache layer" identity="{16777231 custom-resource [] false true}" ipAddr=109.68.224.35/32 key=0 subsys=ipcache
2024-05-28T12:16:38+02:00 {} time="2024-05-28T10:16:38Z" level=debug msg="Daemon notified of IP-Identity cache state change" identity="{16777231 custom-resource [] false true}" ipAddr="{109.68.224.35 ffffffff}" modification=Upsert subsys=datapath-ipcache
2024-05-28T12:16:38+02:00 {} time="2024-05-28T10:16:38Z" level=debug msg="UpdateIdentities: Deleting identity" identity=16777339 labels="[cidr:0.0.0.0/0 cidr:0.0.0.0/1 cidr:104.0.0.0/5 cidr:108.0.0.0/6 cidr:108.0.0.0/7 cidr:109.0.0.0/8 cidr:109.0.0.0/9 cidr:109.64.0.0/10 cidr:109.64.0.0/11 cidr:109.64.0.0/12 cidr:109.64.0.0/13 cidr:109.68.0.0/14 cidr:109.68.0.0/15 cidr:109.68.0.0/16 cidr:109.68.128.0/17 cidr:109.68.192.0/18 cidr:109.68.224.0/19 cidr:109.68.224.0/20 cidr:109.68.224.0/21 cidr:109.68.224.0/22 cidr:109.68.224.0/23 cidr:109.68.224.0/24 cidr:109.68.224.0/25 cidr:109.68.224.0/26 cidr:109.68.224.32/27 cidr:109.68.224.32/28 cidr:109.68.224.32/29 cidr:109.68.224.32/30 cidr:109.68.224.34/31 cidr:109.68.224.35/32 cidr:64.0.0.0/2 cidr:96.0.0.0/3 cidr:96.0.0.0/4 reserved:kube-apiserver reserved:world]" subsys=policy
--
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Processing 1 endpoints for EndpointSlice kubernetes" subsys=k8s
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="EndpointSlice kubernetes has 1 backends" subsys=k8s
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Kubernetes service definition changed" action=service-updated endpoints="109.68.224.35:30153/TCP" k8sNamespace=default k8sSvcName=kubernetes old-endpoints= old-service=nil service="frontends:[10.106.0.1]/ports=[https]/selector=map[]" subsys=k8s-watcher
--
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Acquired service ID" backends="[109.68.224.35:30153]" l7LBFrontendPorts="[]" l7LBProxyPort=0 loadBalancerSourceRanges="[]" serviceID=145 serviceIP="{192.168.129.244 {TCP 30153} 0}" serviceName=kubernetes serviceNamespace=default sessionAffinity=false sessionAffinityTimeout=0 subsys=service svcExtTrafficPolicy=Cluster svcHealthCheckNodePort=0 svcIntTrafficPolicy=Cluster svcType=NodePort
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Deleting backends from session affinity match" backends="[]" serviceID=145 subsys=service
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Resolving identity" identityLabels="cidr:109.68.224.35/32,reserved:kube-apiserver,reserved:world" subsys=identity-cache
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="UpdateIdentities: Adding a new identity" identity=16777232 labels="[cidr:0.0.0.0/0 cidr:0.0.0.0/1 cidr:104.0.0.0/5 cidr:108.0.0.0/6 cidr:108.0.0.0/7 cidr:109.0.0.0/8 cidr:109.0.0.0/9 cidr:109.64.0.0/10 cidr:109.64.0.0/11 cidr:109.64.0.0/12 cidr:109.64.0.0/13 cidr:109.68.0.0/14 cidr:109.68.0.0/15 cidr:109.68.0.0/16 cidr:109.68.128.0/17 cidr:109.68.192.0/18 cidr:109.68.224.0/19 cidr:109.68.224.0/20 cidr:109.68.224.0/21 cidr:109.68.224.0/22 cidr:109.68.224.0/23 cidr:109.68.224.0/24 cidr:109.68.224.0/25 cidr:109.68.224.0/26 cidr:109.68.224.32/27 cidr:109.68.224.32/28 cidr:109.68.224.32/29 cidr:109.68.224.32/30 cidr:109.68.224.34/31 cidr:109.68.224.35/32 cidr:64.0.0.0/2 cidr:96.0.0.0/3 cidr:96.0.0.0/4 reserved:kube-apiserver reserved:world]" subsys=policy
--
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Short circuiting HTTP rules due to rule allowing all and no other rules needing attention" subsys=envoy-manager
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="preparing new cache transaction: upserting 1 entries, deleting 0 entries" subsys=xds xdsCachedVersion=16 xdsTypeURL=type.googleapis.com/cilium.NetworkPolicy
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Resolving identity" identityLabels="cidr:109.68.224.35/32,reserved:kube-apiserver,reserved:world" subsys=identity-cache
--
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Waiting for proxy updates to complete..." subsys=endpoint-manager
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Wait time for proxy updates: 56.608µs" subsys=endpoint-manager
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Upserting IP into ipcache layer" identity="{16777232 kube-apiserver [] false true}" ipAddr=109.68.224.35/32 key=0 subsys=ipcache
2024-05-28T12:16:39+02:00 {} time="2024-05-28T10:16:39Z" level=debug msg="Daemon notified of IP-Identity cache state change" identity="{16777232 kube-apiserver [] false true}" ipAddr="{109.68.224.35 ffffffff}" modification=Upsert subsys=datapath-ipcache
--
2024-05-28T12:17:38+02:00 {} time="2024-05-28T10:17:38Z" level=debug msg="Processing 0 endpoints for EndpointSlice kubernetes" subsys=k8s
2024-05-28T12:17:38+02:00 {} time="2024-05-28T10:17:38Z" level=debug msg="EndpointSlice kubernetes has 0 backends" subsys=k8s
2024-05-28T12:17:38+02:00 {} time="2024-05-28T10:17:38Z" level=debug msg="Kubernetes service definition changed" action=service-updated endpoints= k8sNamespace=default k8sSvcName=kubernetes old-endpoints="109.68.224.35:30153/TCP" old-service=nil service="frontends:[10.106.0.1]/ports=[https]/selector=map[]" subsys=k8s-watcher

The kubernetes service in the default namespace looses it's endpoint and thus Cilium reacts on it. The reason for this to happen seems to be a rolling restart (or similar) of the apiserver deployment (2 pods, clean restart of the deployment). On startup or shutdown it updates the endpoints of the kubernetes service for a short amount of time to <none>:

$ kubectl get endpoints kubernetes -n kube-system -w
NAME         ENDPOINTS             AGE
kubernetes   109.68.224.35:30153   94d


kubernetes   <none>                94d
kubernetes   109.68.224.35:30153   94d
kubernetes   <none>                94d
kubernetes   109.68.224.35:30153   94d

@baurmatt
Copy link
Author

This is a core functionality from Kubernetes. It removes the endpoint from the kubernetes on apiserver shutdown -> https://github.com/kubernetes/kubernetes/blob/fad52aedfcc14061cf20370be061789b4f3d97d9/pkg/controlplane/controller/kubernetesservice/controller.go#L130

@squeed
Copy link
Contributor

squeed commented May 28, 2024

Exactly right.

There's not much we can do in this scenario. If you would like to restrict access in this manner, you will need to set up something like a load balancer to ensure the apiserver has a consistent IP.

@baurmatt
Copy link
Author

@squeed That is a static IP provided by a Load Balancer in front of a Managed Kubernetes cluster thus the apiserver component is run separately with the cloud provider. The apiserver uses --advertise-address to correctly announce the IP address.

@squeed
Copy link
Contributor

squeed commented May 29, 2024

Indeed. That said, it seems that Cilium is doing the "right thing" -- or, at least what it has been told. Access is restricted to IPs know to be apiserver IPs, and that service is empty.

I could imagine a world in which we have some hysteresis for the apiserver to prevent these sorts of issues, but those are only papering over the real problem: it is too easy a Host Firewall policy to lose access to the apiserver on upgrades or failovers.

We should document this limitation.

@baurmatt
Copy link
Author

Thank you for clarifying! If I interpret your answer correct, this means: Don't use kube-apiserver (and other entities?) in NetworkPolicies because they might not be stable 100% of the time - at least in the current implementation state. Is that correct?

I'd currently consider dropping all kube-apiserver rules in favor of toFQDNs. This should work without policy-cidr-match-mode=nodes because we run the apiserver outside of the cluster, right?

+1 for documenting this and/or implementing something like a cache TTL for the entity <> CIDR mapping.

@squeed
Copy link
Contributor

squeed commented May 29, 2024

Don't use kube-apiserver (and other entities?) in NetworkPolicies because they might not be stable 100% of the time

No, the kube-apiserver entity works well. The bigger issue is: be careful when using Host Firewall. Specifically, how the kube-apiserver is defined must not rely on the kube-apiserver always being up.

I'd currently consider dropping all kube-apiserver rules in favor of toFQDNs. This should work without policy-cidr-match-mode=nodes because we run the apiserver outside of the cluster, right?

ToFQDNs relies on layer 7 interception, which does not work for host firewall. You really have to allow access to the apiserver by 100% static means right now.

@ti-mo ti-mo removed the needs/triage This issue requires triaging to establish severity and next steps. label Jun 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info-completed The GH issue has received a reply from the author kind/bug This is a bug in the Cilium logic. kind/community-report This was reported by a user in the Cilium community, eg via Slack. sig/agent Cilium agent related. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies.
Projects
None yet
Development

No branches or pull requests

4 participants