diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 825ae7acf31..6a891d8f42e 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -1084,7 +1084,12 @@ func (m *kubeGenericRuntimeManager) computeInitContainerActions(pod *v1.Pod, pod switch status.State { case kubecontainer.ContainerStateCreated: - // nothing to do but wait for it to start + // The main sync loop should have created and started the container + // in one step. If the init container is in the 'created' state, + // it is likely that the container runtime failed to start it. To + // prevent the container from getting stuck in the 'created' state, + // restart it. + changes.InitContainersToStart = append(changes.InitContainersToStart, i) case kubecontainer.ContainerStateRunning: if !types.IsRestartableInitContainer(container) { diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index c61c11b717c..be917c7bad0 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -1171,6 +1171,17 @@ func TestComputePodActions(t *testing.T) { ContainersToStart: []int{1}, }, }, + "Restart the container if the container is in created state": { + mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyNever }, + mutateStatusFn: func(status *kubecontainer.PodStatus) { + status.ContainerStatuses[1].State = kubecontainer.ContainerStateCreated + }, + actions: podActions{ + SandboxID: baseStatus.SandboxStatuses[0].Id, + ContainersToKill: map[kubecontainer.ContainerID]containerToKillInfo{}, + ContainersToStart: []int{1}, + }, + }, } { pod, status := makeBasePodAndStatus() if test.mutatePodFn != nil { @@ -1545,12 +1556,17 @@ func TestComputePodActionsWithRestartableInitContainers(t *testing.T) { ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), }, }, - "initialization in progress; do nothing": { + "an init container is stuck in the created state; restart it": { mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways }, mutateStatusFn: func(pod *v1.Pod, status *kubecontainer.PodStatus) { status.ContainerStatuses[2].State = kubecontainer.ContainerStateCreated }, - actions: noAction, + actions: podActions{ + SandboxID: baseStatus.SandboxStatuses[0].Id, + InitContainersToStart: []int{2}, + ContainersToStart: []int{}, + ContainersToKill: getKillMapWithInitContainers(basePod, baseStatus, []int{}), + }, }, "restartable init container has started; start the next": { mutatePodFn: func(pod *v1.Pod) { pod.Spec.RestartPolicy = v1.RestartPolicyAlways },