-
Notifications
You must be signed in to change notification settings - Fork 3.4k
k8s: modularize k8s watcher #32878
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: modularize k8s watcher #32878
Conversation
/test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, just some minor comments left inline. 🚀
Regarding the overall approach, I'd say that the long term solution should be to get rid of the k8s watchers cell, as IMHO that is a not so useful layer over the single Resource[T] streams. Instead, we should go for separate well-defined and independent cells that take care of handling their type-specific events without injecting the big k8sWatchers cell in the daemon.
Moreover, IIRC some of these functionalities have been replaced by equivalent ones managed by Resource[T] internally (I'm thinking about the k8s objects related metrics).
Anyway, this PR seems still a nice improvement: it already allows to break some dependencies to the k8sWatcher in favor of the smaller ones, makes some tests easier and blends better with the current hive structure, so I'd say it's a step in the right direction 👍
f3d0f01
to
51f497d
Compare
Thanks for your fast feedback @pippolo84 . I addressed your feedback 👍
I couldn't agree more. That's exactly the intend behind this PR - to pave the way forward. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks 💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice modularity efforts!
I ran through each commit and the changes look good to me. For the most part this is all code-reorg with no major changes to how Cilium's business logic functions.
Looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes it possible to be dependent on only one specific watcher, which can help to avoid circular dependencies that can occur when depending on the whole k8sWatcher.
Very nice improvement! 👍
High-level comment about the design of individual watcher cells: I wonder if there is an opportunity to use generics with interfaces to extract the common methods across all the watcher cells. The interface methods would be init, add/deleteResource[T], stop, etc. There is still lot of duplicated logic in the watcher cells. Wdyt?
(I understand that it's probably outside the scope of this PR.)
k8s: extract k8sCiliumLRPWatcher
k8s: extract k8sCiliumEndpointWatcher
LGTM with a minor improvement suggestion
51f497d
to
c222dc3
Compare
rebased to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mhofstetter Nice clean up. Good work Marco!
Currently, the k8swatcher is initialized in the daemon bootstrap function `newDaemon`. With the modularization of all its dependencies into their own Hive Cell, it's about time to move the initialization of the k8sWatcher into its own Hive Cell too. In a first step, the cell only provides the pre-initialized struct, without moving any of the lifecycle aspects into the Cell. For the time being, these are being kept in the daemon initialization. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, k8s event reporting is part of the k8sWatcher. It's used by sub-watchers of the k8swatcher itself, but also by external watchers (e.g. IPAM watcher). As a first step to further modularize the k8swatcher into its smaller components, the k89s event reporting is extracted into an own cell and struct `k8sEventReporter`. This way, other components can depend on it. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, all the k8s watchers of the `k8sWatcher` are defined in the same struct, have access to all the same dependency fields and are provided as one Cell. This commit extracts the k8s Pod watcher into it's own sub-cell that is provided privately. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, all the k8s watchers of the `k8sWatcher` are defined in the same struct, have access to all the same dependency fields and are provided as one Cell. This commit extracts the k8s CiliumNode watcher into it's own sub-cell that is provided privately. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, all the k8s watchers of the `k8sWatcher` are defined in the same struct, have access to all the same dependency fields and are provided as one Cell. This commit extracts the k8s Namespace watcher into it's own sub-cell that is provided privately. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, all the k8s watchers of the `k8sWatcher` are defined in the same struct, have access to all the same dependency fields and are provided as one Cell. This commit extracts the k8s Service watcher into it's own sub-cell that is provided privately. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, all the k8s watchers of the `k8sWatcher` are defined in the same struct, have access to all the same dependency fields and are provided as one Cell. This commit extracts the k8s Endpoints watcher into it's own sub-cell that is provided privately. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, all the k8s watchers of the `k8sWatcher` are defined in the same struct, have access to all the same dependency fields and are provided as one Cell. This commit extracts the k8s CiliumLRP watcher into it's own sub-cell that is provided privately. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, all the k8s watchers of the `k8sWatcher` are defined in the same struct, have access to all the same dependency fields and are provided as one Cell. This commit extracts the k8s CiliumEndpoints watcher into it's own sub-cell that is provided privately. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, during daemon initialization, multiple components access the k8sSvcCache through the corresponding exported field in the k8sWatcher. This commit removes the field from the k8swatcher and forces the daemon to depend on the `k8sSvcCache` directly. In addition, some tests of the k8sWatcher would have been freed up from using the k8sWatcher at all, as they were only testing service logic. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, the file `watcher_test.go` mostly contains service related unit tests. Therefore, the file gets renamed to `service_test.go`. An upcoming commit will extract the only K8sWatcher related test into `watcher_test.go`. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
This commit extracts the k8sWatcher related unit test into it's own file `watcher_test.go`. (Separate commit to keep the git history). Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
Currently, the k8sWatcher is set as dependency on the nodeDiscovery during agent initialization by using the method `RegisterK8sSetters`. Trying to add an explicit dependency from the NodeDiscovery to the `K8sWatcher` results in a cyclic dependency via datapath. With the modularization of the k8sWatcher into smaller cells, it's possible to define the explicit dependency only to the `k8sCiliumNodeWatcher`, as this is the only part the NodeDiscovery is intersted in. This way, there's no cyclic dependency. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
With the removal of the k8swatcher initialization from the daemon bootstrap, the dependency to the policyUpdater can be removed from the daemon & daemonParams struct. Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
c222dc3
to
bf56cea
Compare
rebased to |
/test |
Currently, the global k8swatcher is initialized in the daemon bootstrap function
newDaemon
.With the modularization of all its dependencies into their own Hive Cell, it's about time to move the initialization of the k8sWatcher into its own Hive Cell too.
In a first step, the cell only provides the pre-initialized struct, without moving any of the lifecycle aspects into the Cell. For the time being, these are being kept in the daemon initialization (calls function on the k8sWatcher).
In addition the k8sWatcher has been split up into its smaller components/watchers (k8sEventReporter, k8sNamespaceWatcher, k8sPodWatcher, k8sServiceWatcher, k8sEndpointsWatcher, k8sCiliumNodeWatcher, k8sCiliumEndpointsWatcher, k8sCiliumLRPWatcher) - each defining its dependencies. This makes it possible to be dependent on only one specific watcher, which can help to avoid circular dependencies that can occur when depending on the whole
k8sWatcher
.Please review the individual commits.
Note:
+3,098 −2,824
seems huge, but this comes mostly from the overall-diff from moving / splitting up thewatcher_test.go
(2640 LoC) intowatcher_test.go
&service_test.go
(with two commits two keep the history: rename & move one test function)