Skip to content

Conversation

foyerunix
Copy link

@foyerunix foyerunix commented Feb 19, 2025

Hello,

Fixes: #37577

Following my issue, I continued my investigations to understand why the UDP sockets weren't closed.

I first added a log line at the beginning of TerminateUDPConnectionsToBackend to check if I enter the function as I ddin't see the "handling udp connections to deleted backend" log.

What I discovered is that the l3n4Addr.Protocol field wasn't set to "UDP" but to "ANY", which I understood being due to having both a TCP and an UDP port on my service.

I therefore added a check for "ANY" in l3n4Addr.Protocol and then set the protocol variable to UDP.

It resolved my issue in my environment, and, as I understand the code, cannot cause any new issue.

Best Regards.

Fix connections to deleted service backends not getting terminated in certain cases involving services with multiple protocol ports.

@foyerunix foyerunix requested a review from a team as a code owner February 19, 2025 13:06
@foyerunix foyerunix requested a review from aditighag February 19, 2025 13:06
@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Feb 19, 2025
@github-actions github-actions bot added the kind/community-contribution This was a contribution made by a community member. label Feb 19, 2025
@joestringer joestringer added the release-note/bug This PR fixes an issue in a previous release of Cilium. label Feb 20, 2025
@maintainer-s-little-helper maintainer-s-little-helper bot removed the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Feb 20, 2025
@aditighag
Copy link
Member

/test

@foyerunix
Copy link
Author

Hello @aditighag,

Thanks for running the tests. I've reviewed the failures:

"The action 'Wait for images to be available (downgrade)' has timed out after 10 minutes."

  • This seems to be a build error unrelated to my PR.

"Failed to execute tcpdump on cilium-test-3/host-netns-wtqnd (kind-worker2): command failed (pod=cilium-test-3/host-netns-wtqnd, container=): error reading from error stream: next reader: websocket: close 1006 (abnormal closure): unexpected EOF"

  • This appears to be an error during the test setup. Tcpdump needs to run to check if the captured packets match some condition.

"command 'curl -w %{local_ip}:%{local_port} -> %{remote_ip}:%{remote_port} = %{response_code}\n --silent --fail --show-error --output /dev/null --connect-timeout 2 --max-time 10 http://[fc00:c111::5]:30755' failed: command failed (pod=cilium-test-4/host-netns-non-cilium-pjg8p, container=host-netns-non-cilium): command terminated with exit code 28"

  • This might indicate my PR is breaking TCP connections.

"Expected to capture packets, but none found. This check might be broken."

  • This could be a flaky test.

"timeout=5s error='rpc error: code = Unavailable desc = dns: A record lookup error: lookup hubble-peer.kube-system.svc.cluster.local. on 10.100.0.10:53: read udp 192.168.122.27:33793->10.100.0.10:53: i/o timeout' subsys=hubble-relay"

  • This might be due to my patch overclosing sockets.

Could you help me distinguish between CI issues and those caused by my fix?

Additionally, I'd appreciate your feedback on the code itself. It works in my environment without issues, but I'm open to reworking my PR if you see a better solution.

Best regards.

Copy link
Member

@aditighag aditighag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rebase your PR? There were certain CI issues that were fixed upstream recently.
I wonder if this is a regression introduced by the protocol differentiation changes - https://github.com/cilium/cilium/pull/33434/commits. Are you able to reproduce this issue by setting the config flag bpf-lb-proto-diff to false?
Also, I've added a release note to the PR description - https://docs.cilium.io/en/stable/contributing/development/contributing_guide/#submitting-a-pull-request.

@aditighag aditighag added the dont-merge/needs-rebase This PR needs to be rebased because it has merge conflicts. label Feb 28, 2025
@foyerunix foyerunix force-pushed the fix-socket-force-close branch 2 times, most recently from dc3fe8c to d9c69e1 Compare March 3, 2025 06:54
@foyerunix
Copy link
Author

Hello @aditighag,

Thank for fixing the release note, I thought my PR title was suitable as a release note.

I made the following test:

  • deploy Cilium 1.17.0
  • set bpf-lb-proto-diff to false in the Cilium configmap
  • restart the Cilium daemonset
  • restart the daemonset of the service that is receiving packets from long lived UDP connections

After looking at Hubble, I still see the symptomatic drops of UDP packets going to non-existing backends.

The PR was rebased and I accepted your change.

Best Regards.

@aditighag
Copy link
Member

/test

@aditighag aditighag removed the dont-merge/needs-rebase This PR needs to be rebased because it has merge conflicts. label Mar 3, 2025
@aditighag
Copy link
Member

@foyerunix All tests passed. Can you drop my sign-off from the commit? Once you've force pushed to the PR, we need not run the full CI test suite before merging the PR.

@aditighag
Copy link
Member

@foyerunix I wasn't able to reproduce the issue locally. See snippets from my testing below.

Can you share the repro steps including your service manifest?

$ k get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
echo            ClusterIP   10.96.132.231   <none>        80/TCP,69/UDP     119s

$ ks logs cilium-mtskr | grep -i handling
time="2025-03-04T21:31:24.278942184Z" level=info msg="handling udp connections to deleted backend 10.244.1.54:80/TCP" subsys=service
time="2025-03-04T21:31:24.279089498Z" level=info msg="handling udp connections to deleted backend 10.244.1.54:69/UDP" subsys=service

diff --git a/pkg/service/connections.go b/pkg/service/connections.go
index 292d1ba4db..b12465a541 100644
--- a/pkg/service/connections.go
+++ b/pkg/service/connections.go
@@ -25,6 +25,7 @@ import (
 var opSupported = true

 func (s *Service) TerminateUDPConnectionsToBackend(l3n4Addr *lb.L3n4Addr) {
+       log.Infof("handling udp connections to deleted backend %v", l3n4Addr)
        // With socket-lb, existing client applications can continue to connect to
        // deleted backends. Destroy any client sockets connected to the deleted backend.
        if !(option.Config.EnableSocketLB || option.Config.BPFSocketLBHostnsOnly) {

@foyerunix foyerunix force-pushed the fix-socket-force-close branch from d9c69e1 to 4791a1e Compare March 6, 2025 05:15
@foyerunix
Copy link
Author

Hello @aditighag,

I dropped your sign-off from the commit.

I didn't build a minimal reproducer that allow to reproduce the issue without having to install the Datadog agent.

I have looked at your snippets and:

time="2025-03-04T21:31:24.278942184Z" level=info msg="handling udp connections to deleted backend 10.244.1.54:80/TCP" subsys=service
time="2025-03-04T21:31:24.279089498Z" level=info msg="handling udp connections to deleted backend 10.244.1.54:69/UDP" subsys=service

Is not what I got when I added debugging. You should have: 10.244.1.54:69/ANY.

Here is my service spec:

spec:
  clusterIP: [redacted]
  clusterIPs:
  - [redacted]
  internalTrafficPolicy: Local
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: dogstatsdport
    port: 8125
    protocol: UDP
    targetPort: 8125
  - name: traceport
    port: 8126
    protocol: TCP
    targetPort: 8126
  selector:
    app: datadog
  sessionAffinity: None
  type: ClusterIP

Best Regards.

@aditighag
Copy link
Member

What cilium version have you installed on your cluster? Can you try installing the latest version?

@julianwiedmann julianwiedmann added area/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. area/loadbalancing Impacts load-balancing and Kubernetes service implementations feature/socket-lb Impacts the Socket-LB part of Cilium's kube-proxy replacement. labels Mar 7, 2025
@joestringer
Copy link
Member

Seems like this stalled - are we looking for further confirmation from @foyerunix or do we think the change is right? As far as I follow it seems like the calling code doesn't discriminate on the protocol of the service, and ANY could mean there are UDP connections. Or do we already expand out ANY to each individual protocol in l3n4Addr?

I couldn't immediately find tests for this functionality but I guess if we extended the testsuite that could help to prove the correct behavior.

@foyerunix
Copy link
Author

foyerunix commented Mar 25, 2025

Hello @joestringer,

I saw that @aditighag asked me to do a test with the latest Cilium version. Meanwhile I don't have the Datadog agent installed in a sandbox environment. I need either to start a Cilium upgrade cycle on my clusters, or to take the risk to just launch the latest Cilium agent on an impacted cluster as is. I'm still unsure about what to do.

I run Cilium 1.17.0.

Best Regards.

@aditighag
Copy link
Member

Hi @foyerunix We are getting more test coverage as part of this PR - #37600. /cc @tommyp1ckles
@tommyp1ckles Would you recommend @foyerunix to cherry pick your commit, and see if the issue he reported still persists?

@foyerunix
Copy link
Author

Hello @aditighag,

I can confirm that I have the same issue with Cilium 1.17.2.

@borkmann
Copy link
Member

borkmann commented Apr 2, 2025

I have looked at your snippets and:

time="2025-03-04T21:31:24.278942184Z" level=info msg="handling udp connections to deleted backend 10.244.1.54:80/TCP" subsys=service
time="2025-03-04T21:31:24.279089498Z" level=info msg="handling udp connections to deleted backend 10.244.1.54:69/UDP" subsys=service

Does this mean that we also attempt to close TCP from above, but eventually fail since socket cookie + TCP doesn't exist?
I think temporary we should land this, but iirc @tommyp1ckles might be following up with actually terminating TCP as well which should then also land till 1.18.

@aditighag
Copy link
Member

/test

@aditighag
Copy link
Member

Hi @foyerunix Could you rebase your PR?

@aditighag aditighag added the dont-merge/needs-rebase This PR needs to be rebased because it has merge conflicts. label Apr 14, 2025
@foyerunix foyerunix force-pushed the fix-socket-force-close branch from 4791a1e to 9ca3361 Compare April 16, 2025 05:42
Add a check for services whose protocol is "ANY" to close their UDP
connections too.

Fixes: cilium#37577

Signed-off-by: foyerunix <foyerunix@foyer.lu>
@foyerunix foyerunix force-pushed the fix-socket-force-close branch from 9ca3361 to 7a9a085 Compare April 16, 2025 06:12
@foyerunix
Copy link
Author

Hi @aditighag,

Done.

Best Regards.

@aditighag aditighag removed the dont-merge/needs-rebase This PR needs to be rebased because it has merge conflicts. label Apr 16, 2025
@aditighag
Copy link
Member

/test

@aditighag
Copy link
Member

aditighag commented Apr 16, 2025

🟥 failed to flush ct entries: %w command failed (pod=kube-system/cilium-zds6t, container=cilium-agent): "time="2025-04-16T15:13:14.440649371Z" level=info msg="completed ctmap gc pass" aliveEntries=0 deleted=3611 family=ipv4 proto=TCP skipped=0 subsys=map-ct\ntime="2025-04-16T15:13:14.444586669Z" level=info msg="completed ctmap gc pass" aliveEntries=0 deleted=422 family=ipv4 proto=non-TCP skipped=0 subsys=map-ct\ntime="2025-04-16T15:13:14.446563167Z" level=info msg="completed ctmap gc pass" aliveEntries=0 deleted=120 family=ipv6 proto=TCP skipped=0 subsys=map-ct\ntime="2025-04-16T15:13:14.447961547Z" level=info msg="completed ctmap gc pass" aliveEntries=0 deleted=66 family=ipv6 proto=non-TCP skipped=0 subsys=map-ct\n"

Hit unrelated CI issue.

Context - #38956.

@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Apr 16, 2025
@aditighag aditighag added this pull request to the merge queue Apr 16, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 16, 2025
@julianwiedmann julianwiedmann added this pull request to the merge queue Apr 17, 2025
Merged via the queue into cilium:main with commit d3c80fa Apr 17, 2025
67 checks passed
@deadok22
Copy link

Hey @foyerunix, thanks for the fix!

We just ran into this very issue!

Could you help me understand the new behavior?

Once s.backendConnectionHandler.Destroy(...) is called, what is going to happen, from the perspective of a client attempting writes through a connected udp socket? Do such clients get to continue using the existing socket fd or do they need to make a new one?

@foyerunix
Copy link
Author

Hello @deadok22,

My PR doesn't change the behavior of socketLB socket termination. It just ensure that UDP connections are terminated when the LB type is "ANY". As I understand, the client need to open a new socket as the kernel forcefully close the existing one.

@julianwiedmann
Copy link
Member

👋 @foyerunix @aditighag curious, is this essentially caused by the termination code assuming that all services are created with L4 protocol differentation (-> #33434) - and we didn't consider services that were created on a pre-v1.17 cluster with ANY protocol?

If so I think we should backport this fix to v1.17. And add some tests to confirm that we're handling such legacy service definitions as expected.

@foyerunix
Copy link
Author

Hello @julianwiedmann,

I can confirm that my Datadog service was created before upgrading to Cilium 1.17.

@ysksuzuki ysksuzuki added the needs-backport/1.17 This PR / issue needs backporting to the v1.17 branch label May 12, 2025
@ysksuzuki
Copy link
Member

When loadBalancer.protocolDifferentiation.enabled=false, the service protocol is treated as ANY. In this case, TerminateUDPConnectionsToBackend does not terminate UDP sockets. Since v1.17 supports protocol differentiation but it may be disabled, we should backport this fix.

if !option.Config.LoadBalancerProtocolDifferentiation {
oldSvc = stripServiceProtocol(oldSvc)
svc = stripServiceProtocol(svc)
endpoints = stripEndpointsProtocol(endpoints)
}

@nbusseneau nbusseneau mentioned this pull request May 15, 2025
9 tasks
@nbusseneau nbusseneau added backport-pending/1.17 The backport for Cilium 1.17.x for this PR is in progress. and removed needs-backport/1.17 This PR / issue needs backporting to the v1.17 branch labels May 15, 2025
@github-actions github-actions bot added backport-done/1.17 The backport for Cilium 1.17.x for this PR is done. and removed backport-pending/1.17 The backport for Cilium 1.17.x for this PR is in progress. labels May 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. area/loadbalancing Impacts load-balancing and Kubernetes service implementations backport-done/1.17 The backport for Cilium 1.17.x for this PR is done. feature/socket-lb Impacts the Socket-LB part of Cilium's kube-proxy replacement. kind/community-contribution This was a contribution made by a community member. ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/bug This PR fixes an issue in a previous release of Cilium.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Long lived unidirectional UDP connections trough a service failing to reach new endpoints
8 participants