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: Introduce subscriber package to simplify & consolidate K8s watcher callbacks / event handling #15295

Conversation

christarazi
Copy link
Member

@christarazi christarazi commented Mar 10, 2021

This PR implements a new package which represents a subscriber to K8s watcher
events. This package simplifies the logic of K8s watchers and removes all the
unnecessary logic of the consumer (subscriber) from them.

In order for a subscriber to add their event handling to the K8s watcher, it
must use register itself. Depending on what kind of object it's subscribed to,
it must use implement the ServiceHandler interface if it's handling Service
objects, or use the "Raw" API where no such constraint on the object type
exists.

With this implementation, future subscribers can easily add their own logic
without worrying about polluting K8s watcher code with specific, irrelevant
details only really meant for them. Meanwhile, the K8s watchers themselves
simply call Notify*() depending on the event type. This notifies all the
subscribers to run their logic on the event.

In an upcoming PR, a BGP subscriber will utilize this infrastructure, all the
while, the core service watcher code remains unchanged.

This PR does not convert the rest of the Operator's watchers, but instead
provides the groundwork for future PRs.

See commit msgs.

  • watchers: Add subscriber package
  • operator/watchers: Convert service watcher to use subscriber

@christarazi christarazi added release-note/misc This PR makes changes that have no direct user impact. area/misc Impacts miscellaneous areas of the code not otherwise owned by another area. kind/cleanup This includes no functional changes. area/operator Impacts the cilium-operator component sig/k8s Impacts the kubernetes API, or kubernetes -> cilium internals translation layers. labels Mar 10, 2021
@maintainer-s-little-helper maintainer-s-little-helper bot added dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. and removed dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. labels Mar 10, 2021
@maintainer-s-little-helper maintainer-s-little-helper bot added this to In progress in 1.10.0 Mar 10, 2021
@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch from 0d07946 to fb02f3c Compare March 10, 2021 05:49
@christarazi christarazi requested a review from aanm March 10, 2021 05:50
@christarazi christarazi requested a review from brb March 10, 2021 05:50
@christarazi christarazi requested review from a team March 10, 2021 05:50
@christarazi christarazi marked this pull request as ready for review March 10, 2021 05:54
@christarazi christarazi added the kind/enhancement This would improve or streamline existing functionality. label Mar 10, 2021
Copy link
Member

@aanm aanm left a comment

Choose a reason for hiding this comment

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

It's not entirely clear what are we gaining by introducing another queue to process k8s events. We had queues for k8s events in the past but we have removed them because they are redundant as the k8s watcher library already has a really good implementation to handle them.

operator/watchers/queue/queue.go Outdated Show resolved Hide resolved
operator/watchers/queue/queue_test.go Outdated Show resolved Hide resolved
operator/watchers/queue/queue.go Outdated Show resolved Hide resolved
operator/watchers/queue/queue.go Outdated Show resolved Hide resolved
@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch from fb02f3c to f53283c Compare March 11, 2021 05:18
@christarazi christarazi requested a review from aanm March 11, 2021 05:27
@christarazi christarazi changed the title operator: Introduce K8s watcher queue to decouple object monitoring and event processing k8s: Introduce callbacks package to consolidate K8s watcher callbacks Mar 11, 2021
@christarazi christarazi changed the title k8s: Introduce callbacks package to consolidate K8s watcher callbacks k8s: Introduce callbacks package to simplify & consolidate K8s watcher callbacks / event handling Mar 11, 2021
@christarazi
Copy link
Member Author

@aanm I rewrote the PR to remove the use of the queue and instead just directly using a slice. Thanks for the suggestion

pkg/k8s/watchers/callbacks/callbacks.go Outdated Show resolved Hide resolved
pkg/k8s/watchers/callbacks/callbacks.go Outdated Show resolved Hide resolved
pkg/k8s/watchers/callbacks/callbacks.go Outdated Show resolved Hide resolved
pkg/k8s/watchers/callbacks/callbacks.go Outdated Show resolved Hide resolved
pkg/k8s/watchers/callbacks/callbacks.go Outdated Show resolved Hide resolved
operator/watchers/service_cache.go Outdated Show resolved Hide resolved
@aanm aanm removed their assignment Mar 11, 2021
@christarazi christarazi marked this pull request as draft March 11, 2021 17:32
@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch from f53283c to 0c7fdd3 Compare March 15, 2021 06:29
@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch from 0c7fdd3 to 8c62a3d Compare March 22, 2021 05:36
@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch from a1d5ce0 to 3abdba6 Compare March 25, 2021 18:04
@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch 2 times, most recently from 490679e to 44b6c52 Compare March 25, 2021 21:23

func (c *serviceCacheSubscriber) OnAdd(obj *slim_corev1.Service) {
log.WithField(logfields.ServiceName, obj.Name).Debugf("Received service addition %+v", obj)
K8sSvcCache.UpdateService(obj, c.swgSvcs)
Copy link
Member

Choose a reason for hiding this comment

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

K8sSvcCache.UpdateService sends the events to a buffered channel of some pre-configured capacity. Currently, we have only one buffered channel as K8sSvcCache.UpdateService is directly called from the watcher callback. But with this change there'll be a channel for every subscriber. Won't that increase memory usage of Cilium? Also, it looks like the code to parse the Service object, call correlateEndpoints, etc in K8sSvcCache.UpdateService be duplicated for every subscriber?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, that's not the intent. I opened #15471 to further address subscribers that depend on the service cache itself. An example is explained there.

Generally , the solution wouldn't be to create a new channel or duplicate anything for that matter for each subscriber, but rather refactor the downstream subscribers that depend on the service cache itself.

@christarazi christarazi changed the title k8s: Introduce callbacks package to simplify & consolidate K8s watcher callbacks / event handling k8s: Introduce subscriber package to simplify & consolidate K8s watcher callbacks / event handling Mar 25, 2021
@christarazi

This comment has been minimized.

@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch from 44b6c52 to d2b4795 Compare March 28, 2021 05:50
@christarazi

This comment has been minimized.

@christarazi

This comment has been minimized.

Copy link
Member

@aanm aanm left a comment

Choose a reason for hiding this comment

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

As this is part of the BGP PR, do we still want to keep this PR open?

@aanm aanm removed their assignment Mar 29, 2021
@christarazi
Copy link
Member Author

@aanm I intended for the BGP PR to be based off this one. There's also lots of context inside this PR that might be worth keeping, so let's use this one

This commit implements a package called subscriber for the K8s resource
/ object watchers. It contains a list of subscribers to notify when
handling a K8s add, update, or delete event, respectively.

This allows the watchers to be simpler and leaner than they previously
were. They no longer need to hold logic specific to the consumers.
Instead, they call Notify*() inside the watcher callbacks depending on
the event, passing the resource / object from the event. This notifies
all the subscribers registered with Register().

Subscribers (also referred to as consumers or handlers) must implement
either k8s.io/client-go/tools/cache.ResourceEventHandler and use the
"Raw" API of callbacks such as (*RawList).Register(), where there's no
strict contraint on the resource / object type, or implement the
provided ServiceHandler and use the "Service" specific API, such as
(*ServiceList).Register(). Consumers of the K8s Service watcher should
implement the ServiceHandler.

For now, only the raw and the service API is provided, due to strict
necessity. More specific handlers can be added easily by defining a new
interface similar to ServiceHandler, but differing on the object type.

Signed-off-by: Chris Tarazi <chris@isovalent.com>
This commit converts the service watcher in the Operator to use the new
subscriber package to handle K8s object events by defining a
ServiceHandler.

Signed-off-by: Chris Tarazi <chris@isovalent.com>
@christarazi christarazi force-pushed the pr/christarazi/refactor-operator-service-watcher branch from 9455269 to 2c5fa4a Compare March 31, 2021 06:34
@christarazi
Copy link
Member Author

test-me-please

@aanm
Copy link
Member

aanm commented Mar 31, 2021

hit #12891 merging

@aanm aanm merged commit 117ec3c into cilium:master Mar 31, 2021
1.10.0 automation moved this from In progress to Done Mar 31, 2021
@christarazi christarazi mentioned this pull request Apr 8, 2021
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/misc Impacts miscellaneous areas of the code not otherwise owned by another area. area/operator Impacts the cilium-operator component kind/cleanup This includes no functional changes. kind/enhancement This would improve or streamline existing functionality. release-note/misc This PR makes changes that have no direct user impact. sig/k8s Impacts the kubernetes API, or kubernetes -> cilium internals translation layers.
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

6 participants