k8s.io/kubernetes@v1.29.3/pkg/kubelet/kuberuntime/util/util.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 v1 "k8s.io/api/core/v1" 21 runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" 22 "k8s.io/klog/v2" 23 kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" 24 ) 25 26 // PodSandboxChanged checks whether the spec of the pod is changed and returns 27 // (changed, new attempt, original sandboxID if exist). 28 func PodSandboxChanged(pod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, uint32, string) { 29 if len(podStatus.SandboxStatuses) == 0 { 30 klog.V(2).InfoS("No sandbox for pod can be found. Need to start a new one", "pod", klog.KObj(pod)) 31 return true, 0, "" 32 } 33 34 readySandboxCount := 0 35 for _, s := range podStatus.SandboxStatuses { 36 if s.State == runtimeapi.PodSandboxState_SANDBOX_READY { 37 readySandboxCount++ 38 } 39 } 40 41 // Needs to create a new sandbox when readySandboxCount > 1 or the ready sandbox is not the latest one. 42 sandboxStatus := podStatus.SandboxStatuses[0] 43 if readySandboxCount > 1 { 44 klog.V(2).InfoS("Multiple sandboxes are ready for Pod. Need to reconcile them", "pod", klog.KObj(pod)) 45 return true, sandboxStatus.Metadata.Attempt + 1, sandboxStatus.Id 46 } 47 if sandboxStatus.State != runtimeapi.PodSandboxState_SANDBOX_READY { 48 klog.V(2).InfoS("No ready sandbox for pod can be found. Need to start a new one", "pod", klog.KObj(pod)) 49 return true, sandboxStatus.Metadata.Attempt + 1, sandboxStatus.Id 50 } 51 52 // Needs to create a new sandbox when network namespace changed. 53 if sandboxStatus.GetLinux().GetNamespaces().GetOptions().GetNetwork() != NetworkNamespaceForPod(pod) { 54 klog.V(2).InfoS("Sandbox for pod has changed. Need to start a new one", "pod", klog.KObj(pod)) 55 return true, sandboxStatus.Metadata.Attempt + 1, "" 56 } 57 58 // Needs to create a new sandbox when the sandbox does not have an IP address. 59 if !kubecontainer.IsHostNetworkPod(pod) && sandboxStatus.Network != nil && sandboxStatus.Network.Ip == "" { 60 klog.V(2).InfoS("Sandbox for pod has no IP address. Need to start a new one", "pod", klog.KObj(pod)) 61 return true, sandboxStatus.Metadata.Attempt + 1, sandboxStatus.Id 62 } 63 64 return false, sandboxStatus.Metadata.Attempt, sandboxStatus.Id 65 } 66 67 // IpcNamespaceForPod returns the runtimeapi.NamespaceMode 68 // for the IPC namespace of a pod 69 func IpcNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { 70 if pod != nil && pod.Spec.HostIPC { 71 return runtimeapi.NamespaceMode_NODE 72 } 73 return runtimeapi.NamespaceMode_POD 74 } 75 76 // NetworkNamespaceForPod returns the runtimeapi.NamespaceMode 77 // for the network namespace of a pod 78 func NetworkNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { 79 if pod != nil && pod.Spec.HostNetwork { 80 return runtimeapi.NamespaceMode_NODE 81 } 82 return runtimeapi.NamespaceMode_POD 83 } 84 85 // PidNamespaceForPod returns the runtimeapi.NamespaceMode 86 // for the PID namespace of a pod 87 func PidNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { 88 if pod != nil { 89 if pod.Spec.HostPID { 90 return runtimeapi.NamespaceMode_NODE 91 } 92 if pod.Spec.ShareProcessNamespace != nil && *pod.Spec.ShareProcessNamespace { 93 return runtimeapi.NamespaceMode_POD 94 } 95 } 96 // Note that PID does not default to the zero value for v1.Pod 97 return runtimeapi.NamespaceMode_CONTAINER 98 } 99 100 // namespacesForPod returns the runtimeapi.NamespaceOption for a given pod. 101 // An empty or nil pod can be used to get the namespace defaults for v1.Pod. 102 func NamespacesForPod(pod *v1.Pod, runtimeHelper kubecontainer.RuntimeHelper) (*runtimeapi.NamespaceOption, error) { 103 userNs, err := runtimeHelper.GetOrCreateUserNamespaceMappings(pod) 104 if err != nil { 105 return nil, err 106 } 107 108 return &runtimeapi.NamespaceOption{ 109 Ipc: IpcNamespaceForPod(pod), 110 Network: NetworkNamespaceForPod(pod), 111 Pid: PidNamespaceForPod(pod), 112 UsernsOptions: userNs, 113 }, nil 114 }