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
policy: Track policy rule labels from which map entries are derived from #10512
Conversation
83a6de7
to
b50f082
Compare
test-me-please |
pkg/policy/l4.go
Outdated
@@ -358,12 +356,13 @@ func (l4 *L4Filter) IdentitySelectionUpdated(selector CachedSelector, selections | |||
// that we could not push updates on a stale policy. | |||
l4Policy := (*L4Policy)(atomic.LoadPointer(&l4.policy)) | |||
if l4Policy != nil { | |||
derivedFrom := l4.DerivedFromRules.DeepCopy().Sort() |
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.
Why do we need to:
- DeepCopy()?
- Sort the rules?
Can't both of these be avoided if we simply insert the labels by order when l4.DerivedFromRules
is created / appended?
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.
They need to be sorted because the insert is not deterministic (see commit message) and we need to be able to have them sorted so we can compare them here:
Line 114 in b50f082
return e.ProxyPort == o.ProxyPort && e.DerivedFromRules.Equals(o.DerivedFromRules) |
They need to be copied to avoid accidentally sorting the original array. As an added bonus, sorting them also makes the unit tests much easier to read.
Edit: I think I slightly misread your comment. Ideally yes, we would have them sorted properly when we insert a new rule. However, given that the insert order is not deterministic, I think it's cheaper to do the sorting here instead of trying to use a heap or something.
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.
But here we are doing a DeepCopy of the full array plus sorting it. Which operation will be performed more frequently? This one or when we insert a new label into o.DerivedFromRules
?
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.
My understanding of the policy code is still somewhat limited, so I might be wrong. But it is my understanding that inserting a new label is much more frequent, as it is called for each rule of each policy applicable to the endpoint when the endpoint is regenerated. While this code here is only called once for each endpoint regeneration.
Edit: Note that the MapStateEntry.DerivedFromRules
is never modified after the entry is created here. Only L4Filter.DerivedFromRules
is being modified when multiple rules are being merged.
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 I'm not mistaken (/cc @jrajahalme) IdentitySelectionUpdated()
can be invoked any time any new identity appears anywhere in the cluster. In large-scale clusters with constant churn, this may happen quite frequently.
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 see, that's a good pointer. That's a case then where we indeed should probably sort L4Filter.DerivedFromRules
once we are certain that there are no rules which can be added to the L4Filter
anymore. I will have to look a bit more deeply where that place would be.
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.
@joestringer is correct, typically policy computations are less frequent than map state generation due to identities being created either for new endpoints or newly resolved DNS names.
@gandro L4Filter.attach()
is called once when the merging is over to "attach" the computed policy to the filter. Sorting in the beginning of this function is likely the right thing to do:
func (l4 *L4Filter) attach(ctx PolicyContext, l4Policy *L4Policy) {
// sort here
...
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.
Thank you all for the feedback, I think that helped me quite understand the code quite a bit better! I have pushed a new version where we sort the labels in L4Filter.attach
. This also allows me to avoid having to create a copy, since this call seems to happen after any modifications to the DerivedFromRules
.
b50f082
to
b883a53
Compare
`Equals` is more idiomatic than `Same` and consistent with Label.Equals. Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
These functions are used to create canonical representations of the LabelArrayList that can be used to check if two LabelArrayList contain the same set of labels. Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
This commit allows us to track the policies for which a certain policy map entry has been created. It is implemented by copying over the `DerivedFromRules` from the merged ingress/egress filters to the user-space representation of the policy map state. These entries are then moved over into the `realizedPolicy` of each endpoint when the policy maps are synced. Since the order of the `DerivedFromRules` rules is not deterministic, sort each LabelArrayList when the computed policy is attached. Default entries such as `AllowAnyIngress`, `AllowAnyEgress` and `AllowLocalHostIngress` are annotated with artificial labels (of label source `reserved`). Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
This function allows callers to get the list of policies which caused a certain policy map entry to be added for a given endpoint. Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
b883a53
to
2442d14
Compare
test-me-please Edit: Hit https://github.com/cilium/cilium/projects/97#card-33577672 |
test-me-please |
This PR allows us to track the policies for which a certain policy map entry has been created.
It is implemented by copying over the
DerivedFromRules
from the merged ingress/egress filters to the user-space representation of the policy map state. These entries are then moved over into therealizedPolicy
of each endpoint when the policy maps are synced.Since the order of the
DerivedFromRules
rules is not deterministic, we create a sorted copy of eachLabelArrayList
. Default entries such asAllowAnyIngress
,AllowAnyEgress
andAllowLocalHostIngress
are annotated with artificial labels (of label sourcereserved
).Note to reviewer: This is the successor PR to #10293 - but with proper test coverage this time and hopefully addresses the feedback given in the other PR. Review per commit.
This change is