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

Rerun init containers when the pod needs to be restarted #47599

Merged
merged 1 commit into from
Aug 17, 2017

Conversation

yujuhong
Copy link
Contributor

@yujuhong yujuhong commented Jun 15, 2017

Whenever pod sandbox needs to be recreated, all containers associated
with it will be killed by kubelet. This change ensures that the init
containers will be rerun in such cases.

The change also refactors the compute logic so that the control flow of
init containers act is more aligned with the regular containers. Unit
tests are added to verify the logic.

This fixes #36485

@yujuhong yujuhong added the release-note-none Denotes a PR that doesn't merit a release note. label Jun 15, 2017
@yujuhong yujuhong self-assigned this Jun 15, 2017
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jun 15, 2017
@yujuhong yujuhong added do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. and removed cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Jun 15, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: yujuhong

No associated issue. Update pull-request body to add a reference to an issue, or get approval with /approve no-issue

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 size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jun 15, 2017
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jun 15, 2017
@yujuhong yujuhong force-pushed the restart-init branch 3 times, most recently from 6a9cc3f to c683ca0 Compare June 15, 2017 22:54
@k8s-github-robot k8s-github-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 16, 2017
@yujuhong
Copy link
Contributor Author

/cc @yifan-gu
Still WIP; not a large-scale improvement, but at least this PR should make init containers work more similar to regular containers.

@k8s-ci-robot k8s-ci-robot requested a review from yifan-gu June 19, 2017 22:44
@yujuhong yujuhong changed the title WIP/testing: restart init containers Rerun init containers when the pod needs to be restarted Jun 21, 2017
@yujuhong yujuhong removed the do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. label Jun 21, 2017
@yujuhong yujuhong assigned Random-Liu and feiskyer and unassigned yujuhong Jun 21, 2017
@yujuhong
Copy link
Contributor Author

/cc @smarterclayton

@yujuhong yujuhong added this to the v1.8 milestone Jun 22, 2017
@yujuhong
Copy link
Contributor Author

/cc @dchen1107

mutatePodFn func(*v1.Pod)
mutateStatusFn func(*kubecontainer.PodStatus)
actions podActions
}{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smarterclayton @dchen1107, please read the description of the test cases and make sure they meet your expectation. Thanks!

@yujuhong
Copy link
Contributor Author

/retest

@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 10, 2017
@feiskyer
Copy link
Member

LGTM

initContainerNames.Insert(container.Name)
}
for name := range initContainerNames {
count := 0
Copy link
Member

@munnerz munnerz Jul 14, 2017

Choose a reason for hiding this comment

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

From what I can see here, this count variable never increments? It's printed below on L673, and in the previous implementation would be incremented on each iteration of the podStatus.ContainerStatuses loop.

I'm not particularly familiar with this bit of code, so I could be wrong. I'm currently attempting to port this patch to the 1.6 dockertools implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the count should be incremented. Will do this later, after getting more comments. The variable is only used in the log message, so it does not affect the functionality of the code.

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

@yujuhong
Copy link
Contributor Author

@dchen1107 @Random-Liu @smarterclayton PTAL.

@smarterclayton
Copy link
Contributor

Tests look good to me. This is generally LGTM, although I can do a deeper pass if necessary.

@yujuhong
Copy link
Contributor Author

Tests look good to me. This is generally LGTM, although I can do a deeper pass if necessary.

Thanks for the review! That's exactly what I needed from you and @dchen1107

@feiskyer already took a pass and LGTM'd the PR. I'll keep the PR open for a couple more days because @Random-Liu mentioned that he may have time to look at it.

defer r.Unlock()

for id, c := range r.Containers {
if c.Metadata.Name == name && c.Metadata.Attempt == attempt {
Copy link
Member

Choose a reason for hiding this comment

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

Why not compare sandboxID?

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. Added.

@@ -620,7 +620,7 @@ func (m *kubeGenericRuntimeManager) killContainersWithSyncResult(pod *v1.Pod, ru
// pruneInitContainers ensures that before we begin creating init containers, we have reduced the number
Copy link
Member

Choose a reason for hiding this comment

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

s/pruneInitContainers/pruneInitContainersBeforeStart

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.

if _, ok := initContainersToKeep[status.ID]; ok {
// prune all other init containers that match this container name
glog.V(4).Infof("Removing init container %q instance %q %d", status.Name, status.ID.ID, count)
if err := m.DeleteContainer(status.ID); 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.

Why use DeleteContainer here but use runtimeService.RemoveContainer below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right. Switching both to m.removeContainer(status.ID.ID) to make them consistent. I think we do need to clean up the log here since we don't do it anywhere else.

@@ -620,7 +620,7 @@ func (m *kubeGenericRuntimeManager) killContainersWithSyncResult(pod *v1.Pod, ru
// pruneInitContainers ensures that before we begin creating init containers, we have reduced the number
// of outstanding init containers still present. This reduces load on the container garbage collector
// by only preserving the most recent terminated init container.
func (m *kubeGenericRuntimeManager) pruneInitContainersBeforeStart(pod *v1.Pod, podStatus *kubecontainer.PodStatus, initContainersToKeep map[kubecontainer.ContainerID]int) {
func (m *kubeGenericRuntimeManager) pruneInitContainersBeforeStart(pod *v1.Pod, podStatus *kubecontainer.PodStatus) {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe just add one argument, e.g. force bool or something.
If it's force, delete all; if not, keep latest exited one?

The 2 functions are almost the same, :)

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 disagree. I think it's clear what each function does with the current naming. Adding a boolean would make the function more complicated and harder to test.

containerStatus := podStatus.FindContainerStatusByName(container.Name)
// If container does not exist, or is not running, check whehter we
Copy link
Member

Choose a reason for hiding this comment

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

s/whehter/whether

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

reason = "Container failed liveness probe."
} else {
// Keep the container.
keepCount += 1
Copy link
Member

Choose a reason for hiding this comment

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

nit: ++

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 think both are perfectly fine unless this documented as convention(?)

m.pruneInitContainersBeforeStart(pod, podStatus, podContainerChanges.InitContainersToKeep)
// This is an optmization because container removals are typically handled
// by container garbage collector.
m.pruneInitContainersBeforeStart(pod, podStatus)
Copy link
Member

Choose a reason for hiding this comment

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

We purge and prune, add an options seems cleaner.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Still think it's clear to keep both functions.

@yujuhong
Copy link
Contributor Author

@Random-Liu comments addressed. PTAL again, thanks

@yujuhong
Copy link
Contributor Author

Pushed a new commit to address a bug @Random-Liu found (good catch!). Also added a new unit test for it.

@Random-Liu
Copy link
Member

Random-Liu commented Aug 16, 2017

@yujuhong LGTM without full confidence.

I could understand the current behavior, and it looks much cleaner than before!
However, It's hard to figure out the original behavior, so I don't have full confidence that there won't be regression or behavior change.

I think we could only rely on the test to catch it for us. :p

Whenever pod sandbox needs to be recreated, all containers associated
with it will be killed by kubelet. This change ensures that the init
containers will be rerun in such cases.

The change also refactors the compute logic so that the control flow of
init containers act is more aligned with the regular containers. Unit
tests are added to verify the logic.
@yujuhong
Copy link
Contributor Author

Rebased and squashed the commits.
Applying the lgtm label based on LGTMs from #47599 (comment) and #47599 (comment)

@yujuhong yujuhong added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 16, 2017
@feiskyer
Copy link
Member

@yujuhong Adds a release-note for this?

@yujuhong yujuhong added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-none Denotes a PR that doesn't merit a release note. labels Aug 17, 2017
@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 46317, 48922, 50651, 50230, 47599)

@k8s-github-robot k8s-github-robot merged commit 4bfe9b1 into kubernetes:master Aug 17, 2017
@yujuhong yujuhong deleted the restart-init branch September 11, 2017 20:32
openshift-merge-robot added a commit to openshift/origin that referenced this pull request Oct 17, 2017
Automatic merge from submit-queue (batch tested with PRs 16889, 16865).

UPSTREAM: 53857: kubelet sync pod throws more detailed events

Also includes the following upstream dependant PRs:

UPSTREAM: 50350: Wait for container cleanup before deletion
UPSTREAM: 48970: Recreate pod sandbox when the sandbox does not have an IP address.
UPSTREAM: 48589: When faild create pod sandbox record event.
UPSTREAM: 48584: Move event type
UPSTREAM: 47599: Rerun init containers when the pod needs to be restarted

xrefs:
kubernetes/kubernetes#53857
kubernetes/kubernetes#50350
kubernetes/kubernetes#48970
kubernetes/kubernetes#48589
kubernetes/kubernetes#48584
kubernetes/kubernetes#47599
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/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Containers from init-containers section do not execute during node reboots
8 participants