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

Relax update validation of uninitialized pod #51733

Conversation

caesarxuchao
Copy link
Member

@caesarxuchao caesarxuchao commented Aug 31, 2017

Split from #50344

Fix #47837

  • Let the podStrategy to only call validation.ValidatePod() if the old pod is not initialized, so fields are mutable.
  • Let the podStatusStrategy refuse updates if the old pod is not initialized.

cc @smarterclayton

Pod spec is mutable when the pod is uninitialized. The apiserver requires the pod spec to be valid even if it's uninitialized. Updating the status field of uninitialized pods is invalid.

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 31, 2017
@caesarxuchao
Copy link
Member Author

/release-note-none
/sig api-machinery

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. labels Aug 31, 2017
@caesarxuchao caesarxuchao force-pushed the only-relax-uninitialized-pod-validation branch from 5494a31 to 408892f Compare August 31, 2017 18:59
@@ -92,6 +94,14 @@ func (podStrategy) AllowCreateOnUpdate() bool {
// ValidateUpdate is the default update validation for an end user.
func (podStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
errorList := validation.ValidatePod(obj.(*api.Pod))
oldMeta, err := meta.Accessor(old)
Copy link
Member

Choose a reason for hiding this comment

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

wrap all of this with a check of the initializers feature gate

Copy link
Member

@liggitt liggitt Aug 31, 2017

Choose a reason for hiding this comment

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

or actually, maybe just a helper func:

initialized, err := IsInitializedObject(old)
switch {
  case err != nil:
    return append(errorList, field.InternalError(field.NewPath("metadata"), err))
  case !initialized:
    return errorList
  default:
    return append(errorList, validation.ValidatePodUpdate(obj.(*api.Pod), old.(*api.Pod))...)
}

@@ -148,71 +149,71 @@ var _ = framework.KubeDescribe("ResourceQuota", func() {
})

It("should create a ResourceQuota and capture the life of an uninitialized pod.", func() {
Copy link
Member

Choose a reason for hiding this comment

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

depends on initializer feature, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

marked as [Feature: Initializers]

@@ -92,6 +94,14 @@ func (podStrategy) AllowCreateOnUpdate() bool {
// ValidateUpdate is the default update validation for an end user.
func (podStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
errorList := validation.ValidatePod(obj.(*api.Pod))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why shouldn't a pod be allowed to be invalid during the process of initialization? It is possible to do with admission today and given a "my special defaulter that can take an invalid user object and choose a good/valid default" initializer, seems even more useful after.

Copy link
Member

@liggitt liggitt Aug 31, 2017

Choose a reason for hiding this comment

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

It is possible to do with admission today

not in a persisted, visible state that someone getting an object from the API has to deal with, or that migration has to take into account. bad data in etcd is not something I'm excited about.

Copy link
Contributor

Choose a reason for hiding this comment

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

not in a persisted, visible state that someone getting an object from the API has to deal with, or that migration has to take into account. bad data in etcd is not something I'm excited about.

It's uninitialized data. Not allowing someone to initialize that data to a shape of their choosing seems excessively restrictive. I know that I would respond to an API not letting me do it by pushing garbage into fields that fail validation and using magic values.

Our API already has problems dealing with new fields and I don't see forcing this limitation as helping.

Copy link
Member

Choose a reason for hiding this comment

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

if we want to further relax this in the future, I think we can, if there are compelling use cases that outweigh the downsides of persisting bad data.

Copy link
Contributor

Choose a reason for hiding this comment

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

if we want to further relax this in the future, I think we can, if there are compelling use cases that outweigh the downsides of persisting bad data.

I suppose its true that we can't go the other way around. If we do it, I reserve the right to say "I told you so" twice. :)

Copy link
Member Author

Choose a reason for hiding this comment

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

seems even more useful after.

It might be useful. However, user can GET uninitialized objects. I think it's more important to never persist invalid objects.

Copy link
Member

@liggitt liggitt Aug 31, 2017

Choose a reason for hiding this comment

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

I suppose its true that we can't go the other way around. If we do it, I reserve the right to say "I told you so" twice. :)

let the record show that @deads2k and @liggitt do not always agree :)

@caesarxuchao caesarxuchao force-pushed the only-relax-uninitialized-pod-validation branch from fc34efe to 7eebea4 Compare August 31, 2017 20:27
// ValidateUpdate is the default update validation for an end user.
func (podStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList {
errorList := validation.ValidatePod(obj.(*api.Pod))
uninitializedUpdate, err := isUpdatingUninitializedPod(old)
Copy link
Member Author

Choose a reason for hiding this comment

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

@liggitt I just saw the code you posted. Do you have a strong preference using the switch statement?

Copy link
Member

Choose a reason for hiding this comment

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

I find it easier to read, but don't feel strongly

@@ -89,9 +93,31 @@ func (podStrategy) AllowCreateOnUpdate() bool {
return false
}

func isUpdatingUninitializedPod(old runtime.Object) (bool, error) {
if !utilfeature.DefaultFeatureGate.Enabled(features.Initializers) {
Copy link
Member Author

Choose a reason for hiding this comment

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

The generic registry will delete the initiailizers if the feature gate is disabled, so the check here is just to be future-proof.


// TODO: uncomment the test when the replenishment_controller uses the
// sharedInformer that list/watches uninitialized objects.
It("[Feature: Initializers] should create a ResourceQuota and capture the life of an uninitialized pod.", func() {
Copy link
Member

Choose a reason for hiding this comment

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

[Feature:Initializers]

@caesarxuchao caesarxuchao force-pushed the only-relax-uninitialized-pod-validation branch from 7eebea4 to b0cbaa5 Compare August 31, 2017 20:43
@liggitt
Copy link
Member

liggitt commented Aug 31, 2017

@derekwaynecarr is there an issue tracking the quota admission updates that need to be done?

@caesarxuchao
Copy link
Member Author

caesarxuchao commented Aug 31, 2017

@liggitt @derekwaynecarr my sharedInformer PR (#51247) isn't going to get merged before the deadline, so the quota replenishment controller won't capture the deletion of uninitialized objects. I will send a follow-up PR to let the quota admission only charge the quota when the object is initialized.

@caesarxuchao
Copy link
Member Author

@liggitt I sent out #51749, which makes the quota admission only charges the final update that removes the last pending finalizer.

@caesarxuchao
Copy link
Member Author

@LiGgit this PR doesn't need to wait for #51749. The quota leak issue existed when we first introduced initializers.

@caesarxuchao
Copy link
Member Author

@liggitt do you have other concerns for this PR?

The quota problem is addressed in #51749, where we charge the quota when pod is initialized, so no need to worry about if the quota system can handle updates of uninitialized pods here.

@liggitt
Copy link
Member

liggitt commented Sep 1, 2017

/lgtm
needs release note

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 1, 2017
@caesarxuchao
Copy link
Member Author

Release notes added.

@deads2k could you approve? Thanks.

@deads2k
Copy link
Contributor

deads2k commented Sep 1, 2017

/approve

@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: caesarxuchao, deads2k, liggitt

Associated issue: 47837

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 1, 2017
@liggitt
Copy link
Member

liggitt commented Sep 1, 2017

added an item to do this generically and remove the pod special case in #49038

@caesarxuchao
Copy link
Member Author

Added the item to the umbrella issue.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

9 similar comments
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@caesarxuchao
Copy link
Member Author

/retest

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

add UninitializedStatusUpdateErrorMsg
@caesarxuchao caesarxuchao force-pushed the only-relax-uninitialized-pod-validation branch from b0cbaa5 to dac486a Compare September 5, 2017 20:57
@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 5, 2017
@caesarxuchao
Copy link
Member Author

caesarxuchao commented Sep 5, 2017

The unit test was broken because I tightened up the rule for initializer name in another PR. Fixed the test and reapplying the label.

@caesarxuchao caesarxuchao added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 5, 2017
@caesarxuchao
Copy link
Member Author

/retest

1 similar comment
@caesarxuchao
Copy link
Member Author

/retest

@liggitt
Copy link
Member

liggitt commented Sep 6, 2017

still seeing the test error:

--- FAIL: TestEtcdStatusUpdateUninitialized (0.10s)
	storage_test.go:758: unexpected error: Pod "foo" is invalid: metadata.initializers.pending[0].name: Invalid value: "init": should be a domain with at least three segments separated by dots

@caesarxuchao caesarxuchao force-pushed the only-relax-uninitialized-pod-validation branch from dac486a to 3432e38 Compare September 6, 2017 05:08
@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 6, 2017
@caesarxuchao
Copy link
Member Author

Thanks. Somehow lost part of the changes during squash.

@caesarxuchao caesarxuchao added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 6, 2017
@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 51733, 51838)

@k8s-github-robot k8s-github-robot merged commit 7951549 into kubernetes:master Sep 6, 2017
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. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants