-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Manage runner with label #355
Conversation
@@ -270,6 +316,12 @@ func (r *RunnerDeploymentReconciler) newRunnerReplicaSet(rd v1alpha1.RunnerDeplo | |||
|
|||
newRSTemplate.Labels = labels | |||
|
|||
if rd.Spec.Selector == 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 seems like a breaking change and I'd like to make it backward-compatible as much as possible.
Sorry if I'm missing something or I have any misconception - but can we use labels
to compose the default rd.Spec.Selector here? As far as remember, labels
is inherited to RunnerReplicaSet.ObjectMeta.Labels and and Runner.ObjectMeta.Labels, which might be enough for resolving the original issue.
As far as it is backward compatible. I think I'm fine to add selector
and matchLabels
, matchExpressions
. But it isn't strictly needed for the original issue, right?
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've tried to express the above as code in 62fcd5f. Does it make sense to you?
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.
62fcd5f basically looks good, but it's not completely backward-compatiblem, IMO.
Let's say users upgrades the controller while RunnerReplicaSet
s already exist.
The new controller cannot find the existing RunnerReplicaSet
s, because it looks for RunnerReplicaSet
s by labels but the existing RunnerReplicaSet
s are not labeled.
I guess that new RunnerReplicaSet
s will be created after the controller is upgraded.
I found 2 ways to avoid that.
- The controller lists
RunnerReplicaSet
s both withlabels
andownerReference
and makes a set of both. - The controller lists
RunnerReplicaSet
s first, and if they are not labeled, it labelsRunnerReplicaSet
s first.
Then, it listsRunnerReplicaSet
s both withlabels
again.
These are temporal. and you can delete them when you are forced to break backward compatibility.
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.
@tapih Thanks! Could you double-check my idea?
The new controller cannot find the existing RunnerReplicaSets, because it looks for RunnerReplicaSets by labels but the existing RunnerReplicaSets are not labeled.
I guess that new RunnerReplicaSets will be created after the controller is upgraded.
Would this be about the updated controller results in recreating RunnerReplicaSet due to the replicasets' template hash change by the addition of the selector? As long as the controller update doesn't result in requiring the user to manually update K8s resources other than the controller's, it looks fine to me. WDYT?
My motivation behind 62fcd5f was to keep backward-compatibility in the sense of the RunnerDeployment API / avoid forcing users to manually update their RunnerDeployment resources to include Spec.Template.Selector.
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.
desiredRS
would change due to the addition of the selector, but these lines in the current code does not get the existing RunnerReplicaSet
s in the first place because it now matches RunnerReplicaSet
s with labels but RunnerReplicaSet
s are not labeled before the controller is updated, IIUC.
I understand your motivation here and agree with you, so we should do what I suggested here to avoid this problem, .
What do you think about it? Thank you.
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.
RunnerReplicaSet manages Runner with labels?
Thanks to your change, RunnerReplicaSet already seems to manage Runner with labels. After 9d75e30, the controller even works correctly for RunnerReplicaSet with/without Spec.Selector.
If so, I'm gonna make another small fix for HRA to work when no selector is given.
Are you willing to add something like the owner-reference check similar to 9d75e30 the below?
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.
@tapih Just a friendly reminder for the case that you missed my comment 😃
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.
Sorry, I took a day off yesterday...
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 took this way to fix the HRA bug because I thought we should basically use labels to have RunnerDeployment
manage Runner
s to make the logic as symmetric as possible with k8s's Deployment
At the same time, I undestood that you didn't want to break the compatibility, so I made some patches not to break the compatibility afterwards.
However, now the code is getting more and more complex, and I'm being strongly concerned that this would make it unnecessaliry harder to maintain this project later.
I'm really sorry for taking your time so much, but I would like to suggest taking the following steps:
- Fix the HRA bug without using labels
- Merge the PR which has the
RunnerDeployment
manageRunner
s with labels when you are forced to break the compatibility later
I'm willing to make PRs again. What do you think about it?
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.
@tapih Just to be clear, I was actually inclined to add selector
to RunnerDeployment and RunnerReplicaSet, despite that it requires some work to make it backward-compatible.
Not only it helps us shape RunnerDeplomyet as much as similar as K8s Deployment, I found that selector
itself can be a good/common language that allows the third-party(user) to easily find a specific set of runners managed by a runnerreplicaset/runnerdeployment.
Without selector
, one had to read actions-runner-controller code to see what information can be used to correlate a runner deployment/replicaset to the corresponding runner(s).
So we now seem to have another benefit that we weren't aware of, for adding selector
.
In addition to that-
Fix the HRA bug without using labels
(I may have been pretty confused, but) if you literally meant to NOT use labels, I'm not sure how we can achieve that. If you meant to not use selectors, I'm still unsure how easy it is.
HRA needs to find the latest runners managed by the targeted RunnerDeployment anyway.
Just following owner-references from HRA, RD, RS, and Runners would be not enough.
For HRA-RD, RS-R it's fine, as there might be only 1-to-1 relationship among them. However for RD, there may be two or more RS. They have different runner-template-hash
label values and that label has been already there for RunnerReplicaSet, so using it for filtering RunnerReplicaSet seems natural.
We also need to determine which runner-template-hash
value is one for the latest runner spec. Instead of relying on Selector
, we can probably modify the HRA controller to call the same hash computing function on the RD.Spec.Template as the RD controller for that. But doing so would make a tight coupling between RD and HRA controllers. Wouldn't it be easier to add/use Selector
then, in terms of design/implementation complexity?
WDYT?
You may have thought that it's really up to me to decide which direction we should go, but I'd really appreciate your feedback!
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: binoue <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: binoue <[email protected]>
Signed-off-by: binoue <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
…ward compatibility
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
Signed-off-by: Hiroshi Muraoka <[email protected]>
8de84f9
to
9f8220c
Compare
It seems like we get |
…mplate hash change
151e3b7
to
d6b3475
Compare
ctx, | ||
&runnerList, | ||
client.InNamespace(rd.Namespace), | ||
client.MatchingLabelsSelector{Selector: selector}, |
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 I have roughly mentioned in #355 (comment), this might be incorrect.
We don't include runner-template-hash
into account here, so at least this can result in runners from multiple RunnerReplicaSet to match. It would double numRunners
while replacing RunnerReplicaSet due to RD.Spec.Template change.
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.
Probably we could just use rd.Spec.Replicas
(that defaults to 1 if missing) instead of numRunners := len(runnerList.Items)
, while keeping this line as-is.
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.
Well, it might be out-of-scope- the above issue should have been there before this PR.
Actually, I'm unsure if we really need |
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.
@tapih Let me merge this anyway so that everyone can participate in testing!
To be clear, I'm pretty confident this is working as expected.
But still wondering if we can remove matchExpression
for simplicity.
I'll shortly fix #355 (comment). It's clearly out of the scope of this PR.
Other than those, I'm not aware of any other enhancements we need on top of this right now.
If you have any comments/opinions/feedbacks/etc, it's more than welcome!
@@ -143,6 +144,28 @@ func (r *RunnerDeploymentReconciler) Reconcile(req ctrl.Request) (ctrl.Result, e | |||
return ctrl.Result{RequeueAfter: 5 * time.Second}, nil | |||
} | |||
|
|||
if !reflect.DeepEqual(newestSet.Spec.Selector, desiredRS.Spec.Selector) { |
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.
AFAIK, and to be clear, Selector
is immutable in the standard K8s deployment. But we'd prefer making this mutable for our use-case
PercentageRunnerBusy seems to have regressed since #355 due to that RunnerDeployment.Spec.Selector is empty by default and the HRA controller was using that empty selector to query runners, which somehow returned 0 runners. This fixes that by using the newly added automatic `runner-deployment-name` label for the default runner label and the selector, which avoids querying with empty selector. Ref #377 (comment)
PercentageRunnerBusy seems to have regressed since #355 due to that RunnerDeployment.Spec.Selector is empty by default and the HRA controller was using that empty selector to query runners, which somehow returned 0 runners. This fixes that by using the newly added automatic `runner-deployment-name` label for the default runner label and the selector, which avoids querying with empty selector. Ref #377 (comment)
This PR fixes #330 .
RunnerDeployment
managesRunnerReplicaSet
with label selectorRunnerReplicaSet
managesRunner
s with label selectorHorizontalRunnerAutoscler
listsRunner
s by labels whenPercentageRunnersBusy
is specifiedI manually checked that
HorizontalRunnerAutoscler
works properly on thePercentageRunnersBusy
mode when multipleRunnerDeployment
exist in the same namespace.