Merge pull request #128676 from vivzbansal/sidecar-3

Refactor: Move IsRestartableInitContainer to common utility package
This commit is contained in:
Kubernetes Prow Robot 2024-11-08 02:21:50 +00:00 committed by GitHub
commit 210f129bb0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 62 additions and 61 deletions

View File

@ -1227,6 +1227,16 @@ func hasInvalidLabelValueInAffinitySelector(spec *api.PodSpec) bool {
return false return false
} }
// IsRestartableInitContainer returns true if the container has ContainerRestartPolicyAlways.
// This function is not checking if the container passed to it is indeed an init container.
// It is just checking if the container restart policy has been set to always.
func IsRestartableInitContainer(initContainer *api.Container) bool {
if initContainer == nil || initContainer.RestartPolicy == nil {
return false
}
return *initContainer.RestartPolicy == api.ContainerRestartPolicyAlways
}
func MarkPodProposedForResize(oldPod, newPod *api.Pod) { func MarkPodProposedForResize(oldPod, newPod *api.Pod) {
if len(newPod.Spec.Containers) != len(oldPod.Spec.Containers) { if len(newPod.Spec.Containers) != len(oldPod.Spec.Containers) {
// Update is invalid: ignore changes and let validation handle it // Update is invalid: ignore changes and let validation handle it

View File

@ -406,3 +406,13 @@ func UpdatePodCondition(status *v1.PodStatus, condition *v1.PodCondition) bool {
// Return true if one of the fields have changed. // Return true if one of the fields have changed.
return !isEqual return !isEqual
} }
// IsRestartableInitContainer returns true if the container has ContainerRestartPolicyAlways.
// This function is not checking if the container passed to it is indeed an init container.
// It is just checking if the container restart policy has been set to always.
func IsRestartableInitContainer(initContainer *v1.Container) bool {
if initContainer == nil || initContainer.RestartPolicy == nil {
return false
}
return *initContainer.RestartPolicy == v1.ContainerRestartPolicyAlways
}

View File

@ -22,9 +22,9 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
kubefeatures "k8s.io/kubernetes/pkg/features" kubefeatures "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/metrics"
"k8s.io/kubernetes/pkg/kubelet/types"
podresourcesv1 "k8s.io/kubelet/pkg/apis/podresources/v1" podresourcesv1 "k8s.io/kubelet/pkg/apis/podresources/v1"
) )
@ -70,7 +70,7 @@ func (p *v1PodResourcesServer) List(ctx context.Context, req *podresourcesv1.Lis
pRes.Containers = make([]*podresourcesv1.ContainerResources, 0, len(pod.Spec.InitContainers)+len(pod.Spec.Containers)) pRes.Containers = make([]*podresourcesv1.ContainerResources, 0, len(pod.Spec.InitContainers)+len(pod.Spec.Containers))
for _, container := range pod.Spec.InitContainers { for _, container := range pod.Spec.InitContainers {
if !types.IsRestartableInitContainer(&container) { if !podutil.IsRestartableInitContainer(&container) {
continue continue
} }
@ -130,7 +130,7 @@ func (p *v1PodResourcesServer) Get(ctx context.Context, req *podresourcesv1.GetP
podResources.Containers = make([]*podresourcesv1.ContainerResources, 0, len(pod.Spec.InitContainers)+len(pod.Spec.Containers)) podResources.Containers = make([]*podresourcesv1.ContainerResources, 0, len(pod.Spec.InitContainers)+len(pod.Spec.Containers))
for _, container := range pod.Spec.InitContainers { for _, container := range pod.Spec.InitContainers {
if !types.IsRestartableInitContainer(&container) { if !podutil.IsRestartableInitContainer(&container) {
continue continue
} }

View File

@ -30,7 +30,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
"k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/metrics"
"k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/utils/cpuset" "k8s.io/utils/cpuset"
) )
@ -298,7 +297,7 @@ func (p *staticPolicy) updateCPUsToReuse(pod *v1.Pod, container *v1.Container, c
// If so, add its cpuset to the cpuset of reusable CPUs for any new allocations. // If so, add its cpuset to the cpuset of reusable CPUs for any new allocations.
for _, initContainer := range pod.Spec.InitContainers { for _, initContainer := range pod.Spec.InitContainers {
if container.Name == initContainer.Name { if container.Name == initContainer.Name {
if types.IsRestartableInitContainer(&initContainer) { if podutil.IsRestartableInitContainer(&initContainer) {
// If the container is a restartable init container, we should not // If the container is a restartable init container, we should not
// reuse its cpuset, as a restartable init container can run with // reuse its cpuset, as a restartable init container can run with
// regular containers. // regular containers.
@ -489,7 +488,7 @@ func (p *staticPolicy) podGuaranteedCPUs(pod *v1.Pod) int {
requestedCPU := p.guaranteedCPUs(pod, &container) requestedCPU := p.guaranteedCPUs(pod, &container)
// See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/753-sidecar-containers#resources-calculation-for-scheduling-and-pod-admission // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/753-sidecar-containers#resources-calculation-for-scheduling-and-pod-admission
// for the detail. // for the detail.
if types.IsRestartableInitContainer(&container) { if podutil.IsRestartableInitContainer(&container) {
requestedByRestartableInitContainers += requestedCPU requestedByRestartableInitContainers += requestedCPU
} else if requestedByRestartableInitContainers+requestedCPU > requestedByInitContainers { } else if requestedByRestartableInitContainers+requestedCPU > requestedByInitContainers {
requestedByInitContainers = requestedByRestartableInitContainers + requestedCPU requestedByInitContainers = requestedByRestartableInitContainers + requestedCPU

View File

@ -37,6 +37,7 @@ import (
"k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/healthz"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors"
@ -49,7 +50,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/lifecycle" "k8s.io/kubernetes/pkg/kubelet/lifecycle"
"k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/metrics"
"k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache"
"k8s.io/kubernetes/pkg/kubelet/types"
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework"
) )
@ -384,7 +384,7 @@ func (m *ManagerImpl) Allocate(pod *v1.Pod, container *v1.Container) error {
if err := m.allocateContainerResources(pod, container, m.devicesToReuse[string(pod.UID)]); err != nil { if err := m.allocateContainerResources(pod, container, m.devicesToReuse[string(pod.UID)]); err != nil {
return err return err
} }
if !types.IsRestartableInitContainer(&initContainer) { if !podutil.IsRestartableInitContainer(&initContainer) {
m.podDevices.addContainerAllocatedResources(string(pod.UID), container.Name, m.devicesToReuse[string(pod.UID)]) m.podDevices.addContainerAllocatedResources(string(pod.UID), container.Name, m.devicesToReuse[string(pod.UID)])
} else { } else {
// If the init container is restartable, we need to keep the // If the init container is restartable, we need to keep the

View File

@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
corev1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" corev1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
"k8s.io/kubernetes/pkg/kubelet/cm/containermap" "k8s.io/kubernetes/pkg/kubelet/cm/containermap"
@ -36,7 +37,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
"k8s.io/kubernetes/pkg/kubelet/config" "k8s.io/kubernetes/pkg/kubelet/config"
"k8s.io/kubernetes/pkg/kubelet/status" "k8s.io/kubernetes/pkg/kubelet/status"
"k8s.io/kubernetes/pkg/kubelet/types"
) )
// memoryManagerStateFileName is the file name where memory manager stores its state // memoryManagerStateFileName is the file name where memory manager stores its state
@ -228,7 +228,7 @@ func (m *manager) AddContainer(pod *v1.Pod, container *v1.Container, containerID
// Since a restartable init container remains running for the full // Since a restartable init container remains running for the full
// duration of the pod's lifecycle, we should not remove it from the // duration of the pod's lifecycle, we should not remove it from the
// memory manager state. // memory manager state.
if types.IsRestartableInitContainer(&initContainer) { if podutil.IsRestartableInitContainer(&initContainer) {
continue continue
} }

View File

@ -34,7 +34,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
"k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/metrics"
"k8s.io/kubernetes/pkg/kubelet/types"
) )
const policyTypeStatic policyType = "Static" const policyTypeStatic policyType = "Static"
@ -353,7 +352,7 @@ func getPodRequestedResources(pod *v1.Pod) (map[v1.ResourceName]uint64, error) {
// See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/753-sidecar-containers#resources-calculation-for-scheduling-and-pod-admission // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/753-sidecar-containers#resources-calculation-for-scheduling-and-pod-admission
// for the detail. // for the detail.
if types.IsRestartableInitContainer(&ctr) { if podutil.IsRestartableInitContainer(&ctr) {
reqRsrcsByRestartableInitCtrs[rsrcName] += qty reqRsrcsByRestartableInitCtrs[rsrcName] += qty
} else if reqRsrcsByRestartableInitCtrs[rsrcName]+qty > reqRsrcsByInitCtrs[rsrcName] { } else if reqRsrcsByRestartableInitCtrs[rsrcName]+qty > reqRsrcsByInitCtrs[rsrcName] {
reqRsrcsByInitCtrs[rsrcName] = reqRsrcsByRestartableInitCtrs[rsrcName] + qty reqRsrcsByInitCtrs[rsrcName] = reqRsrcsByRestartableInitCtrs[rsrcName] + qty
@ -969,7 +968,7 @@ func (p *staticPolicy) updateInitContainersMemoryBlocks(s state.State, pod *v1.P
break break
} }
if types.IsRestartableInitContainer(&initContainer) { if podutil.IsRestartableInitContainer(&initContainer) {
// we should not reuse the resource from any restartable init // we should not reuse the resource from any restartable init
// container // container
continue continue
@ -1011,7 +1010,7 @@ func (p *staticPolicy) updateInitContainersMemoryBlocks(s state.State, pod *v1.P
func isRegularInitContainer(pod *v1.Pod, container *v1.Container) bool { func isRegularInitContainer(pod *v1.Pod, container *v1.Container) bool {
for _, initContainer := range pod.Spec.InitContainers { for _, initContainer := range pod.Spec.InitContainers {
if initContainer.Name == container.Name { if initContainer.Name == container.Name {
return !types.IsRestartableInitContainer(&initContainer) return !podutil.IsRestartableInitContainer(&initContainer)
} }
} }

View File

@ -1585,7 +1585,7 @@ func getPhase(pod *v1.Pod, info []v1.ContainerStatus, podIsTerminal bool) v1.Pod
// regular init containers // regular init containers
for _, container := range spec.InitContainers { for _, container := range spec.InitContainers {
if kubetypes.IsRestartableInitContainer(&container) { if podutil.IsRestartableInitContainer(&container) {
// Skip the restartable init containers here to handle them separately as // Skip the restartable init containers here to handle them separately as
// they are slightly different from the init containers in terms of the // they are slightly different from the init containers in terms of the
// pod phase. // pod phase.
@ -1628,7 +1628,7 @@ func getPhase(pod *v1.Pod, info []v1.ContainerStatus, podIsTerminal bool) v1.Pod
if utilfeature.DefaultFeatureGate.Enabled(features.SidecarContainers) { if utilfeature.DefaultFeatureGate.Enabled(features.SidecarContainers) {
// restartable init containers // restartable init containers
for _, container := range spec.InitContainers { for _, container := range spec.InitContainers {
if !kubetypes.IsRestartableInitContainer(&container) { if !podutil.IsRestartableInitContainer(&container) {
// Skip the regular init containers, as they have been handled above. // Skip the regular init containers, as they have been handled above.
continue continue
} }

View File

@ -50,6 +50,7 @@ import (
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
remote "k8s.io/cri-client/pkg" remote "k8s.io/cri-client/pkg"
kubelettypes "k8s.io/kubelet/pkg/types" kubelettypes "k8s.io/kubelet/pkg/types"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/kubelet/events"
@ -1069,13 +1070,13 @@ func (m *kubeGenericRuntimeManager) computeInitContainerActions(pod *v1.Pod, pod
// If the container is previously initialized but its status is not // If the container is previously initialized but its status is not
// found, it means its last status is removed for some reason. // found, it means its last status is removed for some reason.
// Restart it if it is a restartable init container. // Restart it if it is a restartable init container.
if isPreviouslyInitialized && types.IsRestartableInitContainer(container) { if isPreviouslyInitialized && podutil.IsRestartableInitContainer(container) {
changes.InitContainersToStart = append(changes.InitContainersToStart, i) changes.InitContainersToStart = append(changes.InitContainersToStart, i)
} }
continue continue
} }
if isPreviouslyInitialized && !types.IsRestartableInitContainer(container) { if isPreviouslyInitialized && !podutil.IsRestartableInitContainer(container) {
// after initialization, only restartable init containers need to be kept // after initialization, only restartable init containers need to be kept
// running // running
continue continue
@ -1091,11 +1092,11 @@ func (m *kubeGenericRuntimeManager) computeInitContainerActions(pod *v1.Pod, pod
changes.InitContainersToStart = append(changes.InitContainersToStart, i) changes.InitContainersToStart = append(changes.InitContainersToStart, i)
case kubecontainer.ContainerStateRunning: case kubecontainer.ContainerStateRunning:
if !types.IsRestartableInitContainer(container) { if !podutil.IsRestartableInitContainer(container) {
break break
} }
if types.IsRestartableInitContainer(container) { if podutil.IsRestartableInitContainer(container) {
if container.StartupProbe != nil { if container.StartupProbe != nil {
startup, found := m.startupManager.Get(status.ID) startup, found := m.startupManager.Get(status.ID)
if !found { if !found {
@ -1166,7 +1167,7 @@ func (m *kubeGenericRuntimeManager) computeInitContainerActions(pod *v1.Pod, pod
// If the init container failed and the restart policy is Never, the pod is terminal. // If the init container failed and the restart policy is Never, the pod is terminal.
// Otherwise, restart the init container. // Otherwise, restart the init container.
case kubecontainer.ContainerStateExited: case kubecontainer.ContainerStateExited:
if types.IsRestartableInitContainer(container) { if podutil.IsRestartableInitContainer(container) {
changes.InitContainersToStart = append(changes.InitContainersToStart, i) changes.InitContainersToStart = append(changes.InitContainersToStart, i)
} else { // init container } else { // init container
if isInitContainerFailed(status) { if isInitContainerFailed(status) {
@ -1189,7 +1190,7 @@ func (m *kubeGenericRuntimeManager) computeInitContainerActions(pod *v1.Pod, pod
} }
default: // kubecontainer.ContainerStatusUnknown or other unknown states default: // kubecontainer.ContainerStatusUnknown or other unknown states
if types.IsRestartableInitContainer(container) { if podutil.IsRestartableInitContainer(container) {
// If the restartable init container is in unknown state, restart it. // If the restartable init container is in unknown state, restart it.
changes.ContainersToKill[status.ID] = containerToKillInfo{ changes.ContainersToKill[status.ID] = containerToKillInfo{
name: container.Name, name: container.Name,

View File

@ -46,6 +46,7 @@ import (
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/credentialprovider" "k8s.io/kubernetes/pkg/credentialprovider"
"k8s.io/kubernetes/pkg/credentialprovider/plugin" "k8s.io/kubernetes/pkg/credentialprovider/plugin"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
@ -1327,7 +1328,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po
container := &pod.Spec.InitContainers[idx] container := &pod.Spec.InitContainers[idx]
// Start the next init container. // Start the next init container.
if err := start(ctx, "init container", metrics.InitContainer, containerStartSpec(container)); err != nil { if err := start(ctx, "init container", metrics.InitContainer, containerStartSpec(container)); err != nil {
if types.IsRestartableInitContainer(container) { if podutil.IsRestartableInitContainer(container) {
klog.V(4).InfoS("Failed to start the restartable init container for the pod, skipping", "initContainerName", container.Name, "pod", klog.KObj(pod)) klog.V(4).InfoS("Failed to start the restartable init container for the pod, skipping", "initContainerName", container.Name, "pod", klog.KObj(pod))
continue continue
} }

View File

@ -22,7 +22,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/kubelet/types" podutil "k8s.io/kubernetes/pkg/api/v1/pod"
) )
// terminationOrdering is used to enforce a termination ordering for sidecar containers. It sets up // terminationOrdering is used to enforce a termination ordering for sidecar containers. It sets up
@ -80,7 +80,7 @@ func newTerminationOrdering(pod *v1.Pod, runningContainerNames []string) *termin
close(channel) close(channel)
} }
if types.IsRestartableInitContainer(&ic) { if podutil.IsRestartableInitContainer(&ic) {
// sidecars need to wait for all main containers to exit // sidecars need to wait for all main containers to exit
to.prereqs[ic.Name] = append(to.prereqs[ic.Name], mainContainerChannels...) to.prereqs[ic.Name] = append(to.prereqs[ic.Name], mainContainerChannels...)

View File

@ -24,6 +24,7 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/component-helpers/scheduling/corev1" "k8s.io/component-helpers/scheduling/corev1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/types"
@ -141,7 +142,7 @@ func (w *predicateAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult
// TODO: Remove this after the SidecarContainers feature gate graduates to GA. // TODO: Remove this after the SidecarContainers feature gate graduates to GA.
if !utilfeature.DefaultFeatureGate.Enabled(features.SidecarContainers) { if !utilfeature.DefaultFeatureGate.Enabled(features.SidecarContainers) {
for _, c := range admitPod.Spec.InitContainers { for _, c := range admitPod.Spec.InitContainers {
if types.IsRestartableInitContainer(&c) { if podutil.IsRestartableInitContainer(&c) {
message := fmt.Sprintf("Init container %q may not have a non-default restartPolicy", c.Name) message := fmt.Sprintf("Init container %q may not have a non-default restartPolicy", c.Name)
klog.InfoS("Failed to admit pod", "pod", klog.KObj(admitPod), "message", message) klog.InfoS("Failed to admit pod", "pod", klog.KObj(admitPod), "message", message)
return PodAdmitResult{ return PodAdmitResult{

View File

@ -26,10 +26,10 @@ import (
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/component-base/metrics" "k8s.io/component-base/metrics"
"k8s.io/klog/v2" "k8s.io/klog/v2"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/prober/results" "k8s.io/kubernetes/pkg/kubelet/prober/results"
"k8s.io/kubernetes/pkg/kubelet/status" "k8s.io/kubernetes/pkg/kubelet/status"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
kubeutil "k8s.io/kubernetes/pkg/kubelet/util" kubeutil "k8s.io/kubernetes/pkg/kubelet/util"
"k8s.io/utils/clock" "k8s.io/utils/clock"
) )
@ -171,7 +171,7 @@ func (t probeType) String() string {
func getRestartableInitContainers(pod *v1.Pod) []v1.Container { func getRestartableInitContainers(pod *v1.Pod) []v1.Container {
var restartableInitContainers []v1.Container var restartableInitContainers []v1.Container
for _, c := range pod.Spec.InitContainers { for _, c := range pod.Spec.InitContainers {
if kubetypes.IsRestartableInitContainer(&c) { if podutil.IsRestartableInitContainer(&c) {
restartableInitContainers = append(restartableInitContainers, c) restartableInitContainers = append(restartableInitContainers, c)
} }
} }
@ -325,7 +325,7 @@ func (m *manager) UpdatePodStatus(pod *v1.Pod, podStatus *v1.PodStatus) {
klog.V(4).InfoS("Mismatch between pod spec and status, likely programmer error", "pod", klog.KObj(pod), "containerName", c.Name) klog.V(4).InfoS("Mismatch between pod spec and status, likely programmer error", "pod", klog.KObj(pod), "containerName", c.Name)
continue continue
} }
if !kubetypes.IsRestartableInitContainer(&initContainer) { if !podutil.IsRestartableInitContainer(&initContainer) {
if c.State.Terminated != nil && c.State.Terminated.ExitCode == 0 { if c.State.Terminated != nil && c.State.Terminated.ExitCode == 0 {
podStatus.InitContainerStatuses[i].Ready = true podStatus.InitContainerStatuses[i].Ready = true
} }

View File

@ -24,7 +24,6 @@ import (
podutil "k8s.io/kubernetes/pkg/api/v1/pod" podutil "k8s.io/kubernetes/pkg/api/v1/pod"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
runtimeutil "k8s.io/kubernetes/pkg/kubelet/kuberuntime/util" runtimeutil "k8s.io/kubernetes/pkg/kubelet/kuberuntime/util"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
) )
const ( const (
@ -57,7 +56,7 @@ func GenerateContainersReadyCondition(spec *v1.PodSpec, containerStatuses []v1.C
unreadyContainers := []string{} unreadyContainers := []string{}
for _, container := range spec.InitContainers { for _, container := range spec.InitContainers {
if !kubetypes.IsRestartableInitContainer(&container) { if !podutil.IsRestartableInitContainer(&container) {
continue continue
} }
@ -159,7 +158,7 @@ func GeneratePodReadyCondition(spec *v1.PodSpec, conditions []v1.PodCondition, c
} }
func isInitContainerInitialized(initContainer *v1.Container, containerStatus *v1.ContainerStatus) bool { func isInitContainerInitialized(initContainer *v1.Container, containerStatus *v1.ContainerStatus) bool {
if kubetypes.IsRestartableInitContainer(initContainer) { if podutil.IsRestartableInitContainer(initContainer) {
if containerStatus.Started == nil || !*containerStatus.Started { if containerStatus.Started == nil || !*containerStatus.Started {
return false return false
} }

View File

@ -552,7 +552,7 @@ func hasPodInitialized(pod *v1.Pod) bool {
} }
containerStatus := pod.Status.InitContainerStatuses[l-1] containerStatus := pod.Status.InitContainerStatuses[l-1]
if kubetypes.IsRestartableInitContainer(&container) { if podutil.IsRestartableInitContainer(&container) {
if containerStatus.State.Running != nil && if containerStatus.State.Running != nil &&
containerStatus.Started != nil && *containerStatus.Started { containerStatus.Started != nil && *containerStatus.Started {
return true return true
@ -616,7 +616,7 @@ func checkContainerStateTransition(oldStatuses, newStatuses *v1.PodStatus, podSp
return fmt.Errorf("found mismatch between pod spec and status, container: %v", oldStatus.Name) return fmt.Errorf("found mismatch between pod spec and status, container: %v", oldStatus.Name)
} }
// Skip any restartable init container as it always is allowed to restart // Skip any restartable init container as it always is allowed to restart
if kubetypes.IsRestartableInitContainer(&initContainer) { if podutil.IsRestartableInitContainer(&initContainer) {
continue continue
} }
// Skip any container that wasn't terminated // Skip any container that wasn't terminated

View File

@ -21,6 +21,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
) )
@ -193,21 +194,11 @@ func IsNodeCriticalPod(pod *v1.Pod) bool {
return IsCriticalPod(pod) && (pod.Spec.PriorityClassName == scheduling.SystemNodeCritical) return IsCriticalPod(pod) && (pod.Spec.PriorityClassName == scheduling.SystemNodeCritical)
} }
// IsRestartableInitContainer returns true if the initContainer has
// ContainerRestartPolicyAlways.
func IsRestartableInitContainer(initContainer *v1.Container) bool {
if initContainer.RestartPolicy == nil {
return false
}
return *initContainer.RestartPolicy == v1.ContainerRestartPolicyAlways
}
// HasRestartableInitContainer returns true if the pod has any restartable init // HasRestartableInitContainer returns true if the pod has any restartable init
// container // container
func HasRestartableInitContainer(pod *v1.Pod) bool { func HasRestartableInitContainer(pod *v1.Pod) bool {
for _, container := range pod.Spec.InitContainers { for _, container := range pod.Spec.InitContainers {
if IsRestartableInitContainer(&container) { if podutil.IsRestartableInitContainer(&container) {
return true return true
} }
} }

View File

@ -53,7 +53,8 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/util/certificate/csr" "k8s.io/client-go/util/certificate/csr"
podutil "k8s.io/kubernetes/pkg/api/v1/pod" podutil "k8s.io/kubernetes/pkg/api/pod"
podutilv1 "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/apis/admissionregistration" "k8s.io/kubernetes/pkg/apis/admissionregistration"
"k8s.io/kubernetes/pkg/apis/apiserverinternal" "k8s.io/kubernetes/pkg/apis/apiserverinternal"
"k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps"
@ -896,7 +897,7 @@ func printPod(pod *api.Pod, options printers.GenerateOptions) ([]metav1.TableRow
initContainers := make(map[string]*api.Container) initContainers := make(map[string]*api.Container)
for i := range pod.Spec.InitContainers { for i := range pod.Spec.InitContainers {
initContainers[pod.Spec.InitContainers[i].Name] = &pod.Spec.InitContainers[i] initContainers[pod.Spec.InitContainers[i].Name] = &pod.Spec.InitContainers[i]
if isRestartableInitContainer(&pod.Spec.InitContainers[i]) { if podutil.IsRestartableInitContainer(&pod.Spec.InitContainers[i]) {
totalContainers++ totalContainers++
} }
} }
@ -911,7 +912,7 @@ func printPod(pod *api.Pod, options printers.GenerateOptions) ([]metav1.TableRow
lastRestartDate = terminatedDate lastRestartDate = terminatedDate
} }
} }
if isRestartableInitContainer(initContainers[container.Name]) { if podutil.IsRestartableInitContainer(initContainers[container.Name]) {
restartableInitContainerRestarts += int(container.RestartCount) restartableInitContainerRestarts += int(container.RestartCount)
if container.LastTerminationState.Terminated != nil { if container.LastTerminationState.Terminated != nil {
terminatedDate := container.LastTerminationState.Terminated.FinishedAt terminatedDate := container.LastTerminationState.Terminated.FinishedAt
@ -923,7 +924,7 @@ func printPod(pod *api.Pod, options printers.GenerateOptions) ([]metav1.TableRow
switch { switch {
case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0: case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0:
continue continue
case isRestartableInitContainer(initContainers[container.Name]) && case podutil.IsRestartableInitContainer(initContainers[container.Name]) &&
container.Started != nil && *container.Started: container.Started != nil && *container.Started:
if container.Ready { if container.Ready {
readyContainers++ readyContainers++
@ -993,7 +994,7 @@ func printPod(pod *api.Pod, options printers.GenerateOptions) ([]metav1.TableRow
if pod.DeletionTimestamp != nil && pod.Status.Reason == node.NodeUnreachablePodReason { if pod.DeletionTimestamp != nil && pod.Status.Reason == node.NodeUnreachablePodReason {
reason = "Unknown" reason = "Unknown"
} else if pod.DeletionTimestamp != nil && !podutil.IsPodPhaseTerminal(apiv1.PodPhase(podPhase)) { } else if pod.DeletionTimestamp != nil && !podutilv1.IsPodPhaseTerminal(apiv1.PodPhase(podPhase)) {
reason = "Terminating" reason = "Terminating"
} }
@ -3227,17 +3228,6 @@ func (list SortableResourceNames) Less(i, j int) bool {
return list[i] < list[j] return list[i] < list[j]
} }
func isRestartableInitContainer(initContainer *api.Container) bool {
if initContainer == nil {
return false
}
if initContainer.RestartPolicy == nil {
return false
}
return *initContainer.RestartPolicy == api.ContainerRestartPolicyAlways
}
func isPodInitializedConditionTrue(status *api.PodStatus) bool { func isPodInitializedConditionTrue(status *api.PodStatus) bool {
for _, condition := range status.Conditions { for _, condition := range status.Conditions {
if condition.Type != api.PodInitialized { if condition.Type != api.PodInitialized {