-
Notifications
You must be signed in to change notification settings - Fork 187
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
feat: implement cmpd's PolicyRules #8328
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8328 +/- ##
==========================================
+ Coverage 60.04% 60.30% +0.25%
==========================================
Files 376 377 +1
Lines 45858 45915 +57
==========================================
+ Hits 27535 27688 +153
+ Misses 15739 15621 -118
- Partials 2584 2606 +22
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
relevant addon PR: apecloud/kubeblocks-addons#1197 |
apis/apps/v1/cluster_types.go
Outdated
// The service account will be bound to a default role named "kubeblocks-cluster-pod-role" which is installed together with KubeBlocks. | ||
// If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}" | ||
// If not specified, KubeBlocks automatically creates a default ServiceAccount named | ||
// "kb-{cluster.name}-{component.name}", bound to a role with rules defined in ComponentDefinition's |
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.
As a further improvement, components with the same cmp can share a default service account.
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.
So that the rbac provision can be moved to cmpd controller?
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.
I ignored a problem. Cmpd is not namespaced, but serviceaccount/rolebinding is. So that it is not feasible to move rbac provision to cmpd controller. Cmpd controller can watch
a component to trigger reconcile. The reconcilation related to rbac may look like this:
- It lists all components that references the cmpd. Find all the namespaces of them (list 1).
- It lists all managed rbac resources (serviceaccount/rolebinding/role) using label selector. Find all the namespaces of them (list 2).
- Create/update rbac resources in list 1.
- Delete rbac resouces in list 2 but not in list 1.
After a second thought, rbac provision will remain in component controller. To share rbac resources among multiple components, these rbac resources will use the component which first creates them as their owner. If the component has been deleted, their owner will be transfered to another component which shares a same cmpd. If no such component can be found, they will be deleted. Another note: equality.Semantic is used to replace reflect.DeepEqual to avoid the false alarm of something like |
if serviceAccount == nil { | ||
transCtx.Logger.V(1).Info("buildServiceAccounts returns serviceAccount nil") | ||
if !viper.GetBool(constant.EnableRBACManager) { | ||
transCtx.EventRecorder.Event(transCtx.Cluster, corev1.EventTypeWarning, EventReasonRBACManager, "RBAC manager is disabled") |
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.
No need to initiate a warning event, logging or a normal event is sufficient.
string(ictrlutil.ErrorTypeNotFound), fmt.Sprintf("ServiceAccount %s is not exist", serviceAccount.Name)) | ||
return ictrlutil.NewRequeueError(time.Second, "RBAC manager is disabled, but service account is not exist") | ||
var err error | ||
if serviceAccountName == "" { |
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.
Even if the service account is specified by user, should we consider setting a finalizer to prevent accidental deletion by the user?
return nil | ||
graphCli, _ := transCtx.Client.(model.GraphClient) | ||
|
||
if err := cleanOldResource(transCtx, graphCli, dag, synthesizedComp); err != nil { |
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 can be implemented when transitioning old version clusters to version 1.0.
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.
Where is the transitioning code?
Owns(&corev1.ServiceAccount{}) | ||
} else { | ||
b.Watches(&rbacv1.RoleBinding{}, handler.EnqueueRequestsFromMapFunc(r.filterComponentResources)). | ||
Watches(&corev1.ServiceAccount{}, handler.EnqueueRequestsFromMapFunc(r.filterComponentResources)) |
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.
How should it be handled when the service account is specified by user?
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.
It's not owned by the component controller.
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.
IMO a service account specified by user should not be modified by KB, even if it's deleted by user. So kb doesn't need to receive events from these service accounts.
if len(rules) == 0 { | ||
return nil | ||
} | ||
return builder.NewRoleBuilder(synthesizedComp.Namespace, saName). |
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.
If the role is shared within a cmpd, the name should not use the service account name, as it might be specified by user.
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.
Ok, I'll use cmpd's name as role/rolebinding's name.
return nil | ||
} | ||
return builder.NewRoleBuilder(synthesizedComp.Namespace, saName). | ||
AddLabelsInMap(constant.GetCompLabels(synthesizedComp.ClusterName, synthesizedComp.Name)). |
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.
And these labels become meaningless because they do not belong to any specific object.
return false, err | ||
} | ||
// if any, transfer ownership to any other component | ||
for _, otherComp := range compList.Items { |
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.
skip deleting component
Fixes #8310. Things done in this PR:
serviceAccountName
in cluster and component CR. KB now does not create rbac resources if user has specified a service account.kb-<clusterName>-<compName>
.Addon changes (like update pg addon's cmpd policyRule since we removed kubeblocks-patroni-pod-role) will be addressed in apecloud/kubeblocks-addons#1197.