Skip to content
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

Use SSA to add pod failure conditions #113304

Merged

Conversation

mimowo
Copy link
Contributor

@mimowo mimowo commented Oct 24, 2022

What type of PR is this?

/kind bug
/kind cleanup

What this PR does / why we need it:

In order to eliminate the risk of failures due to conflicts when adding pod disruption conditions. Currently, pod conditions
are added by patches without resource version validation which can lead even to dropping a condition when combined with condition removals: kubernetes/enhancements#3463 (comment)

Which issue(s) this PR fixes:

Special notes for your reviewer:

Added a 5s poll when asserting on the observed actions. This is because otherwise the test is flaky, probably even more than before because as it observes patches it takes longer than before to apply them.

Does this PR introduce a user-facing change?

The `kube-scheduler` and `kube-controller-manager` now use server side apply to set conditions related to pod disruption.

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

- [KEP]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/3329-retriable-and-non-retriable-failures 

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. kind/bug Categorizes issue or PR as related to a bug. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. sig/apps Categorizes an issue or PR as relevant to SIG Apps. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Oct 24, 2022
@mimowo
Copy link
Contributor Author

mimowo commented Oct 24, 2022

/assign @lavalamp @alculquicondor

@mimowo
Copy link
Contributor Author

mimowo commented Oct 24, 2022

/retest

@mimowo mimowo force-pushed the handling-pod-failures-beta-ssa branch from a323594 to 0e387bd Compare October 24, 2022 16:24
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Oct 24, 2022
@lavalamp
Copy link
Member

@apelisse can you take a first pass on this?

@mimowo
Copy link
Contributor Author

mimowo commented Oct 24, 2022

/retest

1 similar comment
@mimowo
Copy link
Contributor Author

mimowo commented Oct 24, 2022

/retest

@mimowo mimowo changed the title SSA to add pod failure conditions - ready for review SSA to add pod failure conditions Oct 24, 2022
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Oct 24, 2022
@mimowo mimowo force-pushed the handling-pod-failures-beta-ssa branch from 18f50e9 to 0dee1c1 Compare October 25, 2022 06:53
@mimowo mimowo changed the title SSA to add pod failure conditions Use SSA to add pod failure conditions Oct 25, 2022
@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 25, 2022
pkg/controller/disruption/disruption.go Outdated Show resolved Hide resolved
WithStatus(v1.ConditionTrue).
WithReason("DeletionByTaintManager").
WithMessage("Taint manager: deleting due to NoExecute taint").
WithLastTransitionTime(metav1.Now()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that there is no alternative today? Or should we be copying the transition time from the condition if we see it in the status?

}
if action.GetVerb() == "delete" && action.GetResource().Resource == "pods" {
podDeleted = true
err := wait.PollImmediate(10*time.Millisecond, 5*time.Second, func() (bool, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the poll necessary now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test is time-based (as we await for the controller to make progress with its actions), waiting only 500ms to observer the actions.

As a result the test occasionally fails (it so happened that it failed on my branch, but was passing consistently locally). Thus, I thought that I could loop to wait a little longer to make the test more stable. I think I could decouple it from the code changes I made.

Also note that, before introducing pod disruption conditions, the test only waited for controller to perform the fake DELETE requests, but now it also needs to perform the fake PATCH / APPLY, so it makes sense to give it a little more time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reverted the change and the tests passed, so probably the test flaked yesterday on the infra. Still, I think my changes make sense to make the test more reliable, but I can decouple them into a separate PR. Keep reverted from this PR for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ticketed in an independent PR: #113386

pkg/controller/podgc/gc_controller.go Outdated Show resolved Hide resolved
pkg/controller/podgc/gc_controller.go Outdated Show resolved Hide resolved
return err
}
}
}
return gcc.kubeClient.CoreV1().Pods(pod.Namespace).Delete(ctx, pod.Name, *metav1.NewDeleteOptions(0))
}

func updatePodCondition(podStatusApply *corev1apply.PodStatusApplyConfiguration, condition *corev1apply.PodConditionApplyConfiguration) {
if conditionIndex, _ := findPodConditionApplyByType(podStatusApply.Conditions, *condition.Type); conditionIndex < 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we be looking at all the conditions (including the ones that are not owned by this controller)?

WithLastTransitionTime(metav1.Now()),
)

if _, err := cs.CoreV1().Pods(victim.Namespace).ApplyStatus(ctx, victimPodApply, metav1.ApplyOptions{FieldManager: "Scheduler", Force: true}); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a rule that the field manager is camel case? We should be using the profile name (which matches the scheduler name)

Copy link
Contributor Author

@mimowo mimowo Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no rule it should be camel case or in any other format - the documentation of the field is pretty relaxed:

FieldManager string `json:"fieldManager,omitempty" protobuf:"bytes,3,name=fieldManager"`
. In this blog post hypen is used: https://kubernetes.io/blog/2021/08/06/server-side-apply-ga/. I propose camel case just to pick something and be consistent as being consistent was one of the remarks by @apelisse. Also, we generally use camel-case in the reason field when naming the actor, for example PreemptionByKubeScheduler.

As for the profile name - could you explain what the value is, is it a constant?

I searched for profile name within the package and found this "

ProfileName() string
, but it doesn't seem ready to use in preemption.go as it is not passed via PostFilter invocations. I guess it would require extending the set of parameters when calling PostFilter or passing the value in context as a keyed value.

I think staying with a constant value for the actor is good enough, until we have a scenario in which it is problematic.

@alculquicondor
Copy link
Member

/approve
for scheduler

@mimowo
Copy link
Contributor Author

mimowo commented Oct 27, 2022

/approve for scheduler

@alculquicondor please unhold the PR if no further issues

@alculquicondor
Copy link
Member

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 27, 2022
@mimowo mimowo force-pushed the handling-pod-failures-beta-ssa branch from e6a31ea to fea8836 Compare October 27, 2022 16:22
@mimowo
Copy link
Contributor Author

mimowo commented Oct 27, 2022

Applied remarks and squashed commits.
@apelisse please let me know if there is something more needed or lgtm so that it gets merged.

@leilajal
Copy link
Contributor

/cc @apelisse
/triage accepted

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Oct 27, 2022
@alculquicondor
Copy link
Member

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 28, 2022
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alculquicondor, lavalamp, mimowo

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot merged commit 3c9928e into kubernetes:master Oct 28, 2022
@k8s-ci-robot k8s-ci-robot added this to the v1.26 milestone Oct 28, 2022
@sftim
Copy link
Contributor

sftim commented Nov 7, 2022

My suggestion for the changelog entry:

The `kube-scheduler` and `kube-controller-manager` now use server side apply to set conditions related to  pod disruption.

@mimowo mimowo deleted the handling-pod-failures-beta-ssa branch March 18, 2023 18:42
@@ -181,7 +181,7 @@ func ObjectReaction(tracker ObjectTracker) ReactionFunc {
if err := json.Unmarshal(modified, obj); err != nil {
return true, nil, err
}
case types.StrategicMergePatchType:
case types.StrategicMergePatchType, types.ApplyPatchType:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change silently enabled unit tests written with server-side apply to appear to succeed, while actually testing subtly different behavior... I really don't think client-side strategic merge patch application is a good way to treat apply patches in the fake client

This is more likely to lead someone to release code they think they tested and have it break in weird and subtle ways in real life.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it might be problematic in some cases. I've done it to enable adjusting the unit tests. I'm wondering how we should fix it. Some options that come to me:

  1. provide a complete implementation in the testing library that would mimic the server (would be preferred, but is it feasible?)
  2. detect some unsupported uses in the testing library and return an error, still allowing for simple test cases to work
  3. revert the change, but then it isn't clear to me how to write / adjust existing unit tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would start by reverting the change to avoid misleading random unit tests that try to use apply

To enable specific unit tests, they could add a reactor that handles this patch type, asserts receiving specific apply patch content, and mocks the application of that patch to the test object

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I have opened the issue for now: #116851. Hope there are some contributors who can help with that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apelisse has some stuff in flight to make unit testing SSA easier / possible...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/apps Categorizes an issue or PR as relevant to SIG Apps. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants