k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/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 // LookupRuntimeHandler is implemented by *runtimeclass.Manager. 101 type RuntimeHandlerResolver interface { 102 LookupRuntimeHandler(runtimeClassName *string) (string, error) 103 } 104 105 // namespacesForPod returns the runtimeapi.NamespaceOption for a given pod. 106 // An empty or nil pod can be used to get the namespace defaults for v1.Pod. 107 func NamespacesForPod(pod *v1.Pod, runtimeHelper kubecontainer.RuntimeHelper, rcManager RuntimeHandlerResolver) (*runtimeapi.NamespaceOption, error) { 108 runtimeHandler := "" 109 if pod != nil && rcManager != nil { 110 var err error 111 runtimeHandler, err = rcManager.LookupRuntimeHandler(pod.Spec.RuntimeClassName) 112 if err != nil { 113 return nil, err 114 } 115 } 116 userNs, err := runtimeHelper.GetOrCreateUserNamespaceMappings(pod, runtimeHandler) 117 if err != nil { 118 return nil, err 119 } 120 121 return &runtimeapi.NamespaceOption{ 122 Ipc: IpcNamespaceForPod(pod), 123 Network: NetworkNamespaceForPod(pod), 124 Pid: PidNamespaceForPod(pod), 125 UsernsOptions: userNs, 126 }, nil 127 }