美文网首页
深入分析kubelet(9)—— 根据resp注入pod信息

深入分析kubelet(9)—— 根据resp注入pod信息

作者: 陈先生_9e91 | 来源:发表于2019-02-21 16:11 被阅读0次

    之前分析过kubelet与device plugin的交互,那么返回的resp kubelet是如何使用的呢?

    猜想:
    CRI在需要生成container运行参数的时候,调用某个方法,该方法会根据spec以及device plugin response返回opt,这样就实现了device plugin response注入到container。

    kubernetes/pkg/kubelet/apis/deviceplugin/v1beta1/api.pb.go

    type ContainerAllocateResponse struct {
       // List of environment variable to be set in the container to access one of more devices.
       Envs map[string]string `protobuf:"bytes,1,rep,name=envs" json:"envs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
       // Mounts for the container.
       Mounts []*Mount `protobuf:"bytes,2,rep,name=mounts" json:"mounts,omitempty"`
       // Devices for the container.
       Devices []*DeviceSpec `protobuf:"bytes,3,rep,name=devices" json:"devices,omitempty"`
       // Container annotations to pass to the container runtime
       Annotations map[string]string `protobuf:"bytes,4,rep,name=annotations" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
    }
    

    kubernetes/pkg/kubelet/cm/devicemanager/pod_devices.go

    // Returns combined container runtime settings to consume the container's allocated devices.
    func (pdev podDevices) deviceRunContainerOptions(podUID, contName string) *DeviceRunContainerOptions {
       containers, exists := pdev[podUID]
       resources, exists := containers[contName]
    
       opts := &DeviceRunContainerOptions{}
       // Maps to detect duplicate settings.
       devsMap := make(map[string]string)
       mountsMap := make(map[string]string)
       envsMap := make(map[string]string)
       annotationsMap := make(map[string]string)
       // Loops through AllocationResponses of all cached device resources.
       for _, devices := range resources {
          resp := devices.allocResp
          // Each Allocate response has the following artifacts.
          // Environment variables
          // Mount points
          // Device files
          // Container annotations
          // These artifacts are per resource per container.
          // Updates RunContainerOptions.Envs.
          for k, v := range resp.Envs {
             envsMap[k] = v
             opts.Envs = append(opts.Envs, kubecontainer.EnvVar{Name: k, Value: v})
          }
    
          // Updates RunContainerOptions.Devices.
          for _, dev := range resp.Devices {
             devsMap[dev.ContainerPath] = dev.HostPath
             opts.Devices = append(opts.Devices, kubecontainer.DeviceInfo{
                PathOnHost:      dev.HostPath,
                PathInContainer: dev.ContainerPath,
                Permissions:     dev.Permissions,
             })
          }
    
          // Updates RunContainerOptions.Mounts.
          for _, mount := range resp.Mounts {
             mountsMap[mount.ContainerPath] = mount.HostPath
             opts.Mounts = append(opts.Mounts, kubecontainer.Mount{
                Name:          mount.ContainerPath,
                ContainerPath: mount.ContainerPath,
                HostPath:      mount.HostPath,
                ReadOnly:      mount.ReadOnly,
                // TODO: This may need to be part of Device plugin API.
                SELinuxRelabel: false,
             })
          }
    
          // Updates for Annotations
          for k, v := range resp.Annotations {
             annotationsMap[k] = v
             opts.Annotations = append(opts.Annotations, kubecontainer.Annotation{Name: k, Value: v})
          }
       }
       return opts
    }
    

    根据resp.Annotations反过来找到deviceRunContainerOptions方法,这里其实很明确了,会将resp所有的内容都返回给opt

    kubernetes/pkg/kubelet/cm/devicemanager/manager.go

    // GetDeviceRunContainerOptions checks whether we have cached containerDevices
    // for the passed-in <pod, container> and returns its DeviceRunContainerOptions
    // for the found one. An empty struct is returned in case no cached state is found.
    func (m *ManagerImpl) GetDeviceRunContainerOptions(pod *v1.Pod, container *v1.Container) (*DeviceRunContainerOptions, error) {
    
       return m.podDevices.deviceRunContainerOptions(string(pod.UID), container.Name), nil
    }
    

    kubernetes/pkg/kubelet/cm/container_manager_linux.go

    // TODO: move the GetResources logic to PodContainerManager.
    func (cm *containerManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*kubecontainer.RunContainerOptions, error) {
       opts := &kubecontainer.RunContainerOptions{}
       // Allocate should already be called during predicateAdmitHandler.Admit(),
       // just try to fetch device runtime information from cached state here
       devOpts, err := cm.deviceManager.GetDeviceRunContainerOptions(pod, container)
    
       opts.Devices = append(opts.Devices, devOpts.Devices...)
       opts.Mounts = append(opts.Mounts, devOpts.Mounts...)
       opts.Envs = append(opts.Envs, devOpts.Envs...)
       opts.Annotations = append(opts.Annotations, devOpts.Annotations...)
       return opts, nil
    }
    

    kubernetes/pkg/kubelet/kubelet_pods.go

    // GenerateRunContainerOptions generates the RunContainerOptions, which can be used by
    // the container runtime to set parameters for launching a container.
    func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, func(), error) {
       opts, err := kl.containerManager.GetResources(pod, container)
       if err != nil {
          return nil, nil, err
       }
    
       return opts, cleanupAction, nil
    }
    

    这里就真相了,符合猜想,CRI根据resp生成的opt创建container

    相关文章

      网友评论

          本文标题:深入分析kubelet(9)—— 根据resp注入pod信息

          本文链接:https://www.haomeiwen.com/subject/itfdyqtx.html