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

fixed conflict resolution behavior while apply podpresets #47864

Merged
merged 1 commit into from
Jul 24, 2017

Conversation

droot
Copy link
Contributor

@droot droot commented Jun 21, 2017

What this PR does / why we need it:
This fixes the PodPreset application behavior in case of conflicts occur during the merging of Pod's information with PodPreset's. More details are in issue #47861

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes #
fixes #47861

Special notes for your reviewer:
We are splitting the PodPreset application logic in two phases. In first phase, we try to detect the conflicts in information merging without modifying the Pod at all. If conflict occurs, then we reject the PodPresets injection. Incase of no conflicts, we apply the PodPresets and merge the information.

Release note:

PodPreset is not injected if conflict occurs while applying PodPresets to a Pod.

@k8s-ci-robot
Copy link
Contributor

Hi @droot. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with @k8s-bot ok to test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Jun 21, 2017
@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. release-note-label-needed labels Jun 21, 2017
@@ -27,6 +27,8 @@ ALLOW_SECURITY_CONTEXT=${ALLOW_SECURITY_CONTEXT:-""}
PSP_ADMISSION=${PSP_ADMISSION:-""}
NODE_ADMISSION=${NODE_ADMISSION:-""}
RUNTIME_CONFIG=${RUNTIME_CONFIG:-""}
# RUNTIME_CONFIG=${RUNTIME_CONFIG:-"settingsio/v1alpha1=true,settings.k8s.io/v1alpha1/podpreset=true"}
RUNTIME_CONFIG=${RUNTIME_CONFIG:-"api/all=true"}
Copy link
Member

Choose a reason for hiding this comment

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

What's your intended goal for "RUNTIME_CONFIG"? You're attempting to declare it on both lines 29 and 31.

Copy link
Contributor Author

@droot droot Jun 26, 2017

Choose a reason for hiding this comment

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

This file got checked in by mistake. I have cleaned it up and enabled "api/all" by default. PTAL.

Copy link
Member

Choose a reason for hiding this comment

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

@droot I don't see any changes to this file.

@droot
Copy link
Contributor Author

droot commented Jun 26, 2017

/assign @pmorie @jpeeler

@k8s-ci-robot
Copy link
Contributor

@droot: GitHub didn't allow me to assign the following users: jpeeler.

Note that only kubernetes members can be assigned.

In response to this:

/assign @pmorie @jpeeler

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@droot
Copy link
Contributor Author

droot commented Jun 26, 2017

/assign @jpeeler

@k8s-ci-robot
Copy link
Contributor

@droot: GitHub didn't allow me to assign the following users: jpeeler.

Note that only kubernetes members can be assigned.

In response to this:

/assign @jpeeler

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@droot droot force-pushed the podpreset-conflict-fix branch 3 times, most recently from a8ce205 to 78f7974 Compare June 26, 2017 18:11
@@ -26,7 +26,7 @@ ALLOW_PRIVILEGED=${ALLOW_PRIVILEGED:-""}
ALLOW_SECURITY_CONTEXT=${ALLOW_SECURITY_CONTEXT:-""}
PSP_ADMISSION=${PSP_ADMISSION:-""}
NODE_ADMISSION=${NODE_ADMISSION:-""}
RUNTIME_CONFIG=${RUNTIME_CONFIG:-""}
RUNTIME_CONFIG=${RUNTIME_CONFIG:-"api/all=true"}
Copy link
Member

Choose a reason for hiding this comment

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

Are these debugging changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Took it out. It is not needed. I thought it was needed to enable "settings..../v1alpha1" API endpoint, but I was wrong, so took it out. PTAL.

@droot droot force-pushed the podpreset-conflict-fix branch from 78f7974 to 51cd10a Compare June 26, 2017 23:39
@cblecker
Copy link
Member

/unassign

@@ -215,7 +215,7 @@ RKT_PATH=${RKT_PATH:-""}
RKT_STAGE1_IMAGE=${RKT_STAGE1_IMAGE:-""}
CHAOS_CHANCE=${CHAOS_CHANCE:-0.0}
CPU_CFS_QUOTA=${CPU_CFS_QUOTA:-true}
ENABLE_HOSTPATH_PROVISIONER=${ENABLE_HOSTPATH_PROVISIONER:-"false"}
ENABLE_HOSTPATH_PROVISIONER=${ENABLE_HOSTPATH_PROVISIONER:-"true"}
Copy link
Member

Choose a reason for hiding this comment

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

This is also a debugging change, right? Def out of scpe for this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Not scoped for this PR, took it out.

pod.ObjectMeta.Annotations[fmt.Sprintf("%s/podpreset-%s", annotationPrefix, pip.GetName())] = pip.GetResourceVersion()
func safeToApplyPodPresetsOnContainer(ctr *api.Container, podPresets []*settings.PodPreset) error {
var errs []error
if _, err := MergeEnv(ctr.Env, podPresets); 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.

Seems like mergeEnv is probably unintentionally exported; we should make it private unless it's used elsewhere

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good pt. Made it private.

// if there were no original envvar just return the pip envvar
if original == nil {
return pip.Spec.Env, nil
func MergeEnv(envVars []api.EnvVar, podPresets []*settings.PodPreset) ([]api.EnvVar, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Hrm, maybe it is intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't think so. Made it private.


var mergedEnvFrom []api.EnvFromSource

mergedEnvFrom = append(mergedEnvFrom, envSources...)
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 reason you chose a different form of allocate and copy here vs mergeenv?

Copy link
Contributor Author

@droot droot Jun 29, 2017

Choose a reason for hiding this comment

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

I followed the original code and didn't change it. I am trying to dig more in to why EnvFrom are treated differently. Quick look suggests, they should also be handled in the similar ways as Env, but I need to confirm that.

EDIT: Took a look at EnvFrom. So EnvFrom is used by envVars to source the value from one of Sources (ConfigMap, Secret, Pod Resource or Container Resource basically downward API). So it is list of those objects which are referred by EnvVars. So there is not question of conflict here, so these lists just need to be merged. However, we can have duplicates in the list referring to the same source, but is harmless.


// make sure they are identical or throw an error
if !reflect.DeepEqual(found, v) {
errs = append(errs, fmt.Errorf("merging volume mounts for %s has a conflict on %s: \n%#v\ndoes not match\n%#v\n in container", pp.GetName(), v.Name, v, found))
Copy link
Member

Choose a reason for hiding this comment

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

It might be helpful if this identified the 'for' as a podpreset

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Didn't understand it. Can you explain it.

continue
}

// make sure they are identical or throw an error
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if identical but duplicated mounts is an error - use case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm... good point. Have to think more about it. Made a note of it.

for _, v := range original {
orig[v.MountPath] = v
}
for _, pp := range podPresets {
Copy link
Member

Choose a reason for hiding this comment

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

It seems like we can do all of this in a single nested loop, since this is orthogonal to the above loop but covers the same space

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, refactored it.

continue
}

// make sure they are identical or throw an error
Copy link
Member

Choose a reason for hiding this comment

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

Also not sure about duplicate but equal volumes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah.. thinking more about it.

}
}

func applyPodPresetsOnContainer(ctr *api.Container, podPresets []*settings.PodPreset) {
Copy link
Member

Choose a reason for hiding this comment

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

I wiuld add a comment explaining that it shiuld be safe to ignore these errors

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@droot droot force-pushed the podpreset-conflict-fix branch from 51cd10a to 09bfe6f Compare June 29, 2017 16:56
Copy link
Contributor Author

@droot droot left a comment

Choose a reason for hiding this comment

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

Thanks @pmorie for the review. Have addressed all comments except one related to handling merge of EnvFrom. Will be investigating more about it today. PTAL.

@@ -215,7 +215,7 @@ RKT_PATH=${RKT_PATH:-""}
RKT_STAGE1_IMAGE=${RKT_STAGE1_IMAGE:-""}
CHAOS_CHANCE=${CHAOS_CHANCE:-0.0}
CPU_CFS_QUOTA=${CPU_CFS_QUOTA:-true}
ENABLE_HOSTPATH_PROVISIONER=${ENABLE_HOSTPATH_PROVISIONER:-"false"}
ENABLE_HOSTPATH_PROVISIONER=${ENABLE_HOSTPATH_PROVISIONER:-"true"}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Not scoped for this PR, took it out.

@@ -403,7 +403,7 @@ function start_apiserver {
fi

# Admission Controllers to invoke prior to persisting objects in cluster
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds,PodPreset
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pmorie Changed the order here. Moved PodPreset before the Pod Security Policy plugin because we want PSP to evaluate the modified PodSpec instead of original PodSpec.

pod.ObjectMeta.Annotations[fmt.Sprintf("%s/podpreset-%s", annotationPrefix, pip.GetName())] = pip.GetResourceVersion()
func safeToApplyPodPresetsOnContainer(ctr *api.Container, podPresets []*settings.PodPreset) error {
var errs []error
if _, err := MergeEnv(ctr.Env, podPresets); err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good pt. Made it private.

// if there were no original envvar just return the pip envvar
if original == nil {
return pip.Spec.Env, nil
func MergeEnv(envVars []api.EnvVar, podPresets []*settings.PodPreset) ([]api.EnvVar, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't think so. Made it private.

for _, v := range original {
orig[v.MountPath] = v
}
for _, pp := range podPresets {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, refactored it.

continue
}

// make sure they are identical or throw an error
Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm... good point. Have to think more about it. Made a note of it.


// make sure they are identical or throw an error
if !reflect.DeepEqual(found, v) {
errs = append(errs, fmt.Errorf("merging volume mounts for %s has a conflict on %s: \n%#v\ndoes not match\n%#v\n in container", pp.GetName(), v.Name, v, found))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Didn't understand it. Can you explain it.

continue
}

// make sure they are identical or throw an error
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah.. thinking more about it.

}
}

func applyPodPresetsOnContainer(ctr *api.Container, podPresets []*settings.PodPreset) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


var mergedEnvFrom []api.EnvFromSource

mergedEnvFrom = append(mergedEnvFrom, envSources...)
Copy link
Contributor Author

@droot droot Jun 29, 2017

Choose a reason for hiding this comment

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

I followed the original code and didn't change it. I am trying to dig more in to why EnvFrom are treated differently. Quick look suggests, they should also be handled in the similar ways as Env, but I need to confirm that.

EDIT: Took a look at EnvFrom. So EnvFrom is used by envVars to source the value from one of Sources (ConfigMap, Secret, Pod Resource or Container Resource basically downward API). So it is list of those objects which are referred by EnvVars. So there is not question of conflict here, so these lists just need to be merged. However, we can have duplicates in the list referring to the same source, but is harmless.

@droot
Copy link
Contributor Author

droot commented Jun 29, 2017

@pmorie addressed all the comments. Also updated the comment about EnvFrom. PTAL. (Also, I am not able to see review comment threads, thats very strange).

@pmorie
Copy link
Member

pmorie commented Jun 30, 2017

@k8s-bot ok to test

@k8s-ci-robot k8s-ci-robot removed the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jun 30, 2017
@pmorie
Copy link
Member

pmorie commented Jun 30, 2017

/release-note

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-label-needed labels Jun 30, 2017
@droot droot force-pushed the podpreset-conflict-fix branch from 09bfe6f to 7e7c3e9 Compare June 30, 2017 22:07
@droot
Copy link
Contributor Author

droot commented Jun 30, 2017

/test pull-kubernetes-verify

@droot
Copy link
Contributor Author

droot commented Jun 30, 2017

/test pull-kubernetes-node-e2e

@droot
Copy link
Contributor Author

droot commented Jul 7, 2017

/assign @shiywang

Copy link
Member

@pmorie pmorie left a comment

Choose a reason for hiding this comment

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

Just a couple nits; I also think godoc for each method would be fantastic to have.

@@ -406,8 +406,7 @@ function start_apiserver {
fi

# Admission Controllers to invoke prior to persisting objects in cluster
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds

ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,PodPreset,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds
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 were to do it again, I would say to make this change in another PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. Took it out. Will make a separate PR for this.

if err != nil {
// add event to pod
c.addEvent(pod, pip, err.Error())
glog.Infof("applied podpresets successfully on Pod: %s ", pod.GetGenerateName())
Copy link
Member

Choose a reason for hiding this comment

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

Is this always going to yield the right name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it to pod.Name. Also improved the logging a bit by making it more informative (added applied podpreset names as well)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pod.Name or pod.GetName() is empty, so kept pod.GenerateName(). I guess each pod instance will get a generated name.

@droot droot force-pushed the podpreset-conflict-fix branch from 7e7c3e9 to 91f804d Compare July 11, 2017 18:53
@droot
Copy link
Contributor Author

droot commented Jul 11, 2017

@pmorie addressed the comments. Please take a look.

@pmorie
Copy link
Member

pmorie commented Jul 14, 2017

@k8s-bot test this

@pmorie
Copy link
Member

pmorie commented Jul 14, 2017

/test pull-kubernetes-kubemark-e2e-gce

@pmorie
Copy link
Member

pmorie commented Jul 18, 2017

/lgtm

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

/approve

@k8s-cherrypick-bot
Copy link

Removing label cherrypick-candidate because no release milestone was set. This is an invalid state and thus this PR is not being considered for cherry-pick to any release branch. Please add an appropriate release milestone and then re-add the label.

@derekwaynecarr
Copy link
Member

/approve

@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 18, 2017
@droot droot force-pushed the podpreset-conflict-fix branch from 91f804d to 4d5b96f Compare July 21, 2017 20:22
@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jul 21, 2017
@droot
Copy link
Contributor Author

droot commented Jul 21, 2017

rebased with the master, so will need LGTM.

@pmorie
Copy link
Member

pmorie commented Jul 24, 2017

/lgtm

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

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: derekwaynecarr, droot, pmorie, pwittrock

Associated issue: 47861

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
Copy link

Automatic merge from submit-queue (batch tested with PRs 49444, 47864, 48584, 49395, 49118)

@k8s-github-robot k8s-github-robot merged commit 633079e into kubernetes:master Jul 24, 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 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PodPreset application on Pod is not consistent incase of a merge conflict
9 participants