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

k8s: Fix data race between ServiceCache and K8sWatcher #25087

Merged

Conversation

joamaki
Copy link
Contributor

@joamaki joamaki commented Apr 24, 2023

correlateEndpoints was modifying a Backend object that was read by
K8sWatcher:

WARNING: DATA RACE
Read at 0x00c000942278 by goroutine 71:
github.com/cilium/cilium/pkg/k8s/watchers.genCartesianProduct()
    /home/chris/code/cilium/cilium/pkg/k8s/watchers/watcher.go:787 +0xb56
github.com/cilium/cilium/pkg/k8s/watchers.datapathSVCs()
    /home/chris/code/cilium/cilium/pkg/k8s/watchers/watcher.go:852 +0x77e
github.com/cilium/cilium/pkg/k8s/watchers.(*K8sWatcher).addK8sSVCs()
...
Previous write at 0x00c000942278 by goroutine 70:
github.com/cilium/cilium/pkg/k8s.(*ServiceCache).correlateEndpoints()
    /home/chris/code/cilium/cilium/pkg/k8s/service_cache.go:501 +0x409
github.com/cilium/cilium/pkg/k8s.(*ServiceCache).UpdateService()
    /home/chris/code/cilium/cilium/pkg/k8s/service_cache.go:214 +0x3e4
github.com/cilium/cilium/pkg/k8s/watchers.(*K8sWatcherSuite).TestChangeSVCPort()
    /home/chris/code/cilium/cilium/pkg/k8s/watchers/watcher_test.go:685 +0x1d09
...

Since the backends are owned by the ServiceCache and allowing to mutate them when holding a lock is something one might expect, fix the issues by making all public ServiceCache methods return a DeepCopy'd *Endpoint and *Backends.

Fix data race affecting the preferred mark in backends, e.g. backends selected by service with affinity set to local. In very rare cases a backend might be missing its preferred status and a non-local backend might be selected.

@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 Apr 24, 2023
@joamaki joamaki added release-note/bug This PR fixes an issue in a previous release of Cilium. and removed dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. labels Apr 24, 2023
@joamaki joamaki marked this pull request as ready for review April 24, 2023 13:47
@joamaki joamaki requested a review from a team as a code owner April 24, 2023 13:47
@joamaki joamaki requested a review from squeed April 24, 2023 13:47
@squeed
Copy link
Contributor

squeed commented Apr 24, 2023

wait, are these objects from the informer cache? what is writing to them?

@christarazi christarazi added sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. sig/k8s Impacts the kubernetes API, or kubernetes -> cilium internals translation layers. kind/bug This is a bug in the Cilium logic. labels Apr 24, 2023
@christarazi
Copy link
Member

While the release note is correct in describing the impact of the change, it doesn't describe what behavior / impact it is improving for users. As of now, this release note sounds quite scary for any user, so either we identify what specific symptoms this bug introduces (if we know), or we downgrade the release note to misc.

Comment on lines 57 to 59
//var buf bytes.Buffer
//json.Indent(&buf, jsonBytes, "", "\t")
//fmt.Printf("JSON spec:\n%s\n", buf.String())
Copy link
Member

Choose a reason for hiding this comment

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

Why not just remove the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These 3 lines are in many many places. @jrajahalme Can we clean these up?

Copy link
Member

Choose a reason for hiding this comment

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

I'd guess these are meant for debugging, so let's just remove them and file an issue to clean up the rest as a followup.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ended up just removing them from everywhere.

@christarazi
Copy link
Member

Given that #19521 introduced this bug, we'll need to backport to v1.12 and v1.13.

@christarazi christarazi added needs-backport/1.12 needs-backport/1.13 This PR / issue needs backporting to the v1.13 branch labels Apr 24, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.13.3 Apr 24, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.12.10 Apr 24, 2023
@joamaki
Copy link
Contributor Author

joamaki commented Apr 25, 2023

wait, are these objects from the informer cache? what is writing to them?

They're derived from them, but the cache objects are not mutated. What is mutating is the *k8s.Endpoints, or more specifically *loadbalancer.Backend inside *k8s.Endpoints. This is created and owned by ServiceCache which hands it over to K8sWatcher over the events channel. Bug is that the same*Backend is mutated that is handed over to K8sWatcher.

@joamaki
Copy link
Contributor Author

joamaki commented Apr 25, 2023

While the release note is correct in describing the impact of the change, it doesn't describe what behavior / impact it is improving for users. As of now, this release note sounds quite scary for any user, so either we identify what specific symptoms this bug introduces (if we know), or we downgrade the release note to misc.

Expanded the comment to mention the impact. Are we ok with this? Could also consider downgrading as the impact is minor.

@christarazi
Copy link
Member

The release note sounds better now. I don't think we've had any bug reports about backend preferred selection, but then again it's probably hard to pinpoint from a user's perspective that something went wrong there. I think we ship it given we've done our due diligence for as far as we know.

@christarazi
Copy link
Member

Rebasing to run CI

@christarazi christarazi force-pushed the pr/joamaki/fix-service-cache-endpoints-race branch from 2712e52 to b784ff8 Compare April 25, 2023 16:47
@christarazi
Copy link
Member

/test

@joamaki joamaki self-assigned this Apr 26, 2023
@@ -531,7 +531,7 @@ func (s *ServiceCache) correlateEndpoints(id ServiceID) (*Endpoints, bool) {

// Report the service as ready if a local endpoints object exists or if
// external endpoints have been identified
return endpoints, hasLocalEndpoints || hasExternalEndpoints
return endpoints.DeepCopy(), hasLocalEndpoints || hasExternalEndpoints
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed with @squeed that it'd be cleaner to DeepCopy the backend that's mutated rather than the whole thing here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ended up flipping this. Now the backends are mutated in-place (with lock held), but all public methods in ServiceCache will always return a copy of the Backends.

@joamaki joamaki force-pushed the pr/joamaki/fix-service-cache-endpoints-race branch from b784ff8 to 1905319 Compare May 2, 2023 08:19
@joamaki
Copy link
Contributor Author

joamaki commented May 2, 2023

/test

Job 'Cilium-PR-K8s-1.24-kernel-5.4' failed:

Click to show.

Test Name

K8sDatapathConfig Host firewall With native routing and endpoint routes

Failure Output

FAIL: Error deleting resource /home/jenkins/workspace/Cilium-PR-K8s-1.24-kernel-5.4/src/github.com/cilium/cilium/test/k8s/manifests/host-policies.yaml: Cannot retrieve "cilium-jh7j5"'s policy revision: cannot get policy revision: ""

Jenkins URL: https://jenkins.cilium.io/job/Cilium-PR-K8s-1.24-kernel-5.4/1934/

If it is a flake and a GitHub issue doesn't already exist to track it, comment /mlh new-flake Cilium-PR-K8s-1.24-kernel-5.4 so I can create one.

Then please upload the Jenkins artifacts to that issue.

Job 'Cilium-PR-K8s-1.26-kernel-net-next' failed:

Click to show.

Test Name

K8sDatapathCustomCalls Basic test with byte-counter Loads byte-counter and gets consistent values

Failure Output

FAIL: failed to ensure the namespace kube-system exists: signal: killed

Jenkins URL: https://jenkins.cilium.io/job/Cilium-PR-K8s-1.26-kernel-net-next/2028/

If it is a flake and a GitHub issue doesn't already exist to track it, comment /mlh new-flake Cilium-PR-K8s-1.26-kernel-net-next so I can create one.

Then please upload the Jenkins artifacts to that issue.

Comment on lines 57 to 59
//var buf bytes.Buffer
//json.Indent(&buf, jsonBytes, "", "\t")
//fmt.Printf("JSON spec:\n%s\n", buf.String())
Copy link
Member

Choose a reason for hiding this comment

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

I'd guess these are meant for debugging, so let's just remove them and file an issue to clean up the rest as a followup.

@joamaki joamaki requested a review from a team as a code owner May 5, 2023 07:29
Remove leftover debugging code in envoy-related tests.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
correlateEndpoints was modifying a Backend object that was read by
K8sWatcher:

  WARNING: DATA RACE
  Read at 0x00c000942278 by goroutine 71:
    github.com/cilium/cilium/pkg/k8s/watchers.genCartesianProduct()
        /home/chris/code/cilium/cilium/pkg/k8s/watchers/watcher.go:787 +0xb56
    github.com/cilium/cilium/pkg/k8s/watchers.datapathSVCs()
        /home/chris/code/cilium/cilium/pkg/k8s/watchers/watcher.go:852 +0x77e
    github.com/cilium/cilium/pkg/k8s/watchers.(*K8sWatcher).addK8sSVCs()
    ...
  Previous write at 0x00c000942278 by goroutine 70:
    github.com/cilium/cilium/pkg/k8s.(*ServiceCache).correlateEndpoints()
        /home/chris/code/cilium/cilium/pkg/k8s/service_cache.go:501 +0x409
    github.com/cilium/cilium/pkg/k8s.(*ServiceCache).UpdateService()
        /home/chris/code/cilium/cilium/pkg/k8s/service_cache.go:214 +0x3e4
    github.com/cilium/cilium/pkg/k8s/watchers.(*K8sWatcherSuite).TestChangeSVCPort()
        /home/chris/code/cilium/cilium/pkg/k8s/watchers/watcher_test.go:685 +0x1d09
    ...

Since the backends are owned by the ServiceCache and allowing to mutate them when
holding a lock is something one might expect, fix the issues by making all public
ServiceCache methods return a DeepCopy'd *Endpoint and *Backends.

Fixes: cilium#25071
Fixes: aa3c85f ("k8s: Add preferred attribute in Endpoints")
Signed-off-by: Jussi Maki <jussi@isovalent.com>
@joamaki joamaki force-pushed the pr/joamaki/fix-service-cache-endpoints-race branch from 6f1e356 to 4cf827b Compare May 5, 2023 07:30
@joamaki
Copy link
Contributor Author

joamaki commented May 5, 2023

/test

Job 'Cilium-PR-K8s-1.26-kernel-net-next' failed:

Click to show.

Test Name

K8sDatapathServicesTest Checks N/S loadbalancing With host policy Tests NodePort

Failure Output

FAIL: Can not connect to service "tftp://[fd04::12]:31608/hello" from outside cluster (1/10)

Jenkins URL: https://jenkins.cilium.io/job/Cilium-PR-K8s-1.26-kernel-net-next/2090/

If it is a flake and a GitHub issue doesn't already exist to track it, comment /mlh new-flake Cilium-PR-K8s-1.26-kernel-net-next so I can create one.

Then please upload the Jenkins artifacts to that issue.

@joamaki
Copy link
Contributor Author

joamaki commented May 5, 2023

/test-1.26-net-next

Copy link
Member

@nathanjsweet nathanjsweet left a comment

Choose a reason for hiding this comment

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

I am worried about memory usage, but this all looks good.

@joamaki joamaki added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label May 8, 2023
@youngnick
Copy link
Contributor

Looks like Chart CI Push hit #25274, merging.

@youngnick youngnick merged commit bc3028e into cilium:main May 8, 2023
56 of 57 checks passed
@YutaroHayakawa YutaroHayakawa mentioned this pull request May 10, 2023
14 tasks
@YutaroHayakawa YutaroHayakawa added backport-pending/1.13 The backport for Cilium 1.13.x for this PR is in progress. and removed needs-backport/1.13 This PR / issue needs backporting to the v1.13 branch labels May 10, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Needs backport from main to Backport pending to v1.13 in 1.13.3 May 10, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot removed the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label May 10, 2023
@YutaroHayakawa YutaroHayakawa mentioned this pull request May 10, 2023
7 tasks
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Needs backport from main to Backport pending to v1.12 in 1.12.10 May 10, 2023
@YutaroHayakawa YutaroHayakawa added backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. and removed backport-pending/1.12 labels May 15, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.12 to Backport done to v1.12 in 1.12.10 May 15, 2023
@julianwiedmann julianwiedmann added backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. and removed backport-pending/1.13 The backport for Cilium 1.13.x for this PR is in progress. labels Jul 31, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.13 to Backport done to v1.13 in 1.13.3 Jul 31, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.13 to Backport done to v1.13 in 1.13.3 Jul 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. kind/bug This is a bug in the Cilium logic. release-note/bug This PR fixes an issue in a previous release of Cilium. sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. sig/k8s Impacts the kubernetes API, or kubernetes -> cilium internals translation layers.
Projects
No open projects
1.12.10
Backport done to v1.12
1.13.3
Backport done to v1.13
Development

Successfully merging this pull request may close these issues.

None yet

7 participants