...

Source file src/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go

Documentation: k8s.io/kubernetes/pkg/kubelet/kuberuntime/util

     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  }
   128  

View as plain text