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
Bug 1687940: deployment: fix scope of pod anti-affinity #167
Bug 1687940: deployment: fix scope of pod anti-affinity #167
Conversation
caa6a43
to
6fce585
Compare
|
/retest |
|
Not seeing anything suspicious about the router in the logs, the flakes are concerning... /retest |
|
/retest |
|
/test e2e-aws-operator |
|
/retest |
1 similar comment
|
/retest |
|
Need to fix the label selectors in |
|
Good catch — there might be a gap here in how we construct the selector if it must be shared |
|
Well, turns out that the YAML/manifestfactory business was hiding an entanglement of the deployment pod selector (i.e. in addition to the deployment itself, the internal service also needs to match the deployment pods). So I gave the internal service the usual refactoring treatment and extracted the naming and deployment pod selector stuff into A rotten cluster has stymied my testing, so might have to continue this one on Monday (unless it happens that the CI tests pass and there are no issues during code review). |
| } | ||
|
|
||
| s.Spec.Selector = map[string]string{ | ||
| s.Spec.Selector[controllerDeploymentLabel]: IngressControllerDeploymentLabel(ic), |
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 think this is already an improvement, but another possibility I see is to use the selector from the deployment itself here (perhaps by extracting a function into names.go which returns the deployment 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.
I went ahead and did this refactor too
|
So here's my post-hoc justification for increasing the complexity of the PR: The affinity setup in the manifest YAML is already pretty complex, and at the time I introduced it I thought the value would be static. However, as the bug shows, some of the affinity definition is actually dynamic as a function of the ingress controller. One option would have been to leave the static parts in YAML and mutate just the dynamic piece at runtime, and there's precedent within the codebase for that. However, based on previous conversations, I thought it would be easier to comprehend if we kept the whole affinity piece defined in code closer to the mutation. I also cleaned up the deployment selector names as part of that, which I thought would be trivial. But, during the course of the refactor, it became clear that the deployment pod selector is used in many contexts, and the as a result I ended up having to touch the related pieces. I'm hoping the improved clarity of coupling between these parts will justify the expanded scope of the changes. Thoughts? |
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.
Should delete ServingCertSecretAnnotation in manifests.go.
| ) | ||
|
|
||
| // ensureInternalRouterServiceForIngress ensures that an internal service exists | ||
| // for a given ClusterIngress. |
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.
"ClusterIngress"→"IngressController"
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.
Fixed
assets/router/service-internal.yaml
Outdated
| @@ -5,12 +5,8 @@ apiVersion: v1 | |||
| metadata: | |||
| # Name and Annotations are set at runtime. | |||
| namespace: openshift-ingress | |||
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.
Specifying namespace in the asset is redundant now that desiredInternalIngressControllerService sets 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.
Fixed
| } | ||
| deployment.Spec.Selector = IngressControllerDeploymentPodSelector(ci) | ||
|
|
||
| deployment.Spec.Template.Labels = IngressControllerDeploymentPodSelector(ci).MatchLabels |
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.
Looks like you could even simplify this to deployment.Spec.Template.Labels = deployment.Spec.Selector.MatchLabels.
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.
Changed
|
|
515600a
to
268eb2c
Compare
|
Updated Ready for review again. |
|
/retest |
|
/retest while I look at the failures... |
|
/retest |
|
Looks like CI account issues. /retest |
| @@ -175,69 +175,6 @@ func TestClusterIngressControllerCreateDelete(t *testing.T) { | |||
| } | |||
| } | |||
|
|
|||
| func TestRouterServiceInternalEndpoints(t *testing.T) { | |||
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.
Curious to know why this test is being removed.
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 the test isn't buying us much other than asserting the service exists, which is covered implicitly elsewhere. It did check the endpoints, but that's such a specific test you could cover with a unit (e.g. do the selectors match) and there's origin e2e coverage for metrics which actually uses the service (currently broken).
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.
Spoke offline and decided to do a followup which introduces a new test variant which exercises the metrics endpoint through the service (which will both implicitly test the endpoints and also the actual functional area around the internal service, which is enabling metrics integration)
|
/retest |
|
Still trying to get a cluster to try and reproduce any issues. Operator logs and router logs look fine... /retest |
|
/retest |
|
Okay, finally reproduced some of these in a local cluster. |
268eb2c
to
52875c9
Compare
Before, the anti-affinity rule for ingress controller deployment pods was such that no controller pods could colocate on a node, even if they were for different ingress controllers. Now, pods for different ingress controllers can be colocated on a node. Fixes bug https://bugzilla.redhat.com/show_bug.cgi?id=1687940.
52875c9
to
8130d69
Compare
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.
Minor nit, otherwise LGTM
| spec: | ||
| type: ClusterIP | ||
| selector: | ||
| app: router |
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.
Recent changes are hinting us that we don't have much value in creating assets anymore.
Probably we should ditch assets and create objects internally in the code.
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 we keep the assets, maybe we could at least use more abstract names, such as ClusterIPService, similar to how we have LoadBalancerService. I wouldn't object to removing the assets entirely though.
| // ensureInternalRouterServiceForIngress ensures that an internal service exists | ||
| // for a given IngressController. | ||
| func (r *reconciler) ensureInternalIngressControllerService(ic *operatorv1.IngressController, deploymentRef metav1.OwnerReference) (*corev1.Service, error) { | ||
| desired := desiredInternalIngressControllerService(ic, deploymentRef) |
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 line can be moved to line 33 where we use this desired object.
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.
manifests.go still has an unused definition for ServingCertSecretAnnotation.
| deployment.Labels = map[string]string{} | ||
| deployment.Labels = map[string]string{ | ||
| // associate the deployment with the ingresscontroller | ||
| manifests.OwningClusterIngressLabel: ci.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.
Should this be using IngressControllerDeploymentLabel?
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.
Not sure, this is the same as before, and deploymentLabel is for ingress.operator.openshift.io/ingress-controller-deployment — we might need to audit our labels generallly
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.
Meant for this comment to apply to controller_internal_service.go
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 no, this was to associate the deployment with the ingresscontroller, which is the intent of the label... IngressControllerDeploymentLabel was meant to be a way to associate other stuff with the deployment itself. The naming is probably poor
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.
What is the intended use of IngressControllerDeploymentLabel? I was assuming it was, "I have an ingresscontroller and need the label I would use to identify 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.
Sorry, just saw your last comment (GitHub didn't show it when I submitted mine last comment). I see now, IngressControllerDeploymentLabel identifies the deployment, and we need a label that identifies the ingresscontroller (for which we do not yet have a function). Please disregard my preceding comments.
| s.Name = name.Name | ||
|
|
||
| s.Labels = map[string]string{ | ||
| manifests.OwningClusterIngressLabel: ic.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.
Should this be using IngressControllerDeploymentLabel?
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 don't know if it matters since there's an owner ref to the deployment already
|
/retest |
|
/lgtm |
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
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ironcladlou, Miciah, pravisankar The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/test e2e-aws-operator |
/test e2e-aws-operator |
Before, the anti-affinity rule for ingress controller deployment pods was such
that no controller pods could colocate on a node, even if they were for
different ingress controllers. Now, pods for different ingress controllers can
be colocated on a node.
Fixes bug https://bugzilla.redhat.com/show_bug.cgi?id=1687940.