生成容器引用信息

基于kubernetes v1.18.6,关于基于windows平台运行kubelet的相关代码逻辑不作解析。

概述

kubelet通过以下四个步骤,来启动pod容器:

  1. 拉取镜像
  2. 创建容器
  3. 启动容器
  4. 执行容器启动后的钩子

其中创建容器又分为以下子步骤:

  1. 设置容器重启次数
  2. 生成创建容器所需配置
  3. 创建容器
  4. 预启动容器
  5. 生成容器引用信息

本文主要解析创建容器/创建容器阶段kubelet所做工作,首先我们先看下创建容器阶段的代码逻辑

func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, spec *startSpec, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string, podIPs []string) (string, error) {
...
    containerID, err := m.runtimeService.CreateContainer(podSandboxID, containerConfig, podSandboxConfig)
...
}

接下来我们分析m.runtimeService.CreateContainer()函数调用

m.runtimeService.CreateContainer()函数解析

流程解析

流程很简单:调用容器运行时创建容器,返回容器ID

入参:

  • 沙箱ID
  • 沙箱配置
  • 容器元数据 返回值: 容器ID、异常

源码解析

kubernetes\pkg\kubelet\remote\remote_runtime.go

func (r *RemoteRuntimeService) CreateContainer(podSandBoxID string, config *runtimeapi.ContainerConfig, sandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
    ctx, cancel := getContextWithTimeout(r.timeout)
    defer cancel()

    resp, err := r.runtimeClient.CreateContainer(ctx, &runtimeapi.CreateContainerRequest{
        PodSandboxId:  podSandBoxID,
        Config:        config,
        SandboxConfig: sandboxConfig,
    })
    if err != nil {
        klog.Errorf("CreateContainer in sandbox %q from runtime service failed: %v", podSandBoxID, err)
        return "", err
    }

    if resp.ContainerId == "" {
        errorMessage := fmt.Sprintf("ContainerId is not set for container %q", config.GetMetadata())
        klog.Errorf("CreateContainer failed: %s", errorMessage)
        return "", errors.New(errorMessage)
    }

    return resp.ContainerId, nil
}

关于沙箱

前文我们了解到: kubelet通过调用容器运行时创建容器,返回容器ID。其中入参中有沙箱相关的参数。

那么沙箱到底是什么?

沙箱其实是CRI定义的。当运行时为docker时,sandbox实质就是pause容器。 pause容器作为一个pod内其他所有容器的父角色,拥有很多pod级别资源,如: DNS配置、命名空间(主机名、IP地址、端口映射列表),父级控制组(pod内容器控制组的父控制组由pause容器定义)等

关于pause容器介绍,建议您移步The Almighty Pause Container

PodSandboxConfig沙箱配置对象数据结构解析

type PodSandboxConfig struct {
    // Metadata of the sandbox. This information will uniquely identify the
    // sandbox, and the runtime should leverage this to ensure correct
    // operation. The runtime may also use this information to improve UX, such
    // as by constructing a readable name.
    Metadata *PodSandboxMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
    // Hostname of the sandbox. Hostname could only be empty when the pod
    // network namespace is NODE.
    Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"`
    // Path to the directory on the host in which container log files are
    // stored.
    // By default the log of a container going into the LogDirectory will be
    // hooked up to STDOUT and STDERR. However, the LogDirectory may contain
    // binary log files with structured logging data from the individual
    // containers. For example, the files might be newline separated JSON
    // structured logs, systemd-journald journal files, gRPC trace files, etc.
    // E.g.,
    //     PodSandboxConfig.LogDirectory = `/var/log/pods/<podUID>/`
    //     ContainerConfig.LogPath = `containerName/Instance#.log`
    //
    // WARNING: Log management and how kubelet should interface with the
    // container logs are under active discussion in
    // https://issues.k8s.io/24677. There *may* be future change of direction
    // for logging as the discussion carries on.
    LogDirectory string `protobuf:"bytes,3,opt,name=log_directory,json=logDirectory,proto3" json:"log_directory,omitempty"`
    // DNS config for the sandbox.
    DnsConfig *DNSConfig `protobuf:"bytes,4,opt,name=dns_config,json=dnsConfig,proto3" json:"dns_config,omitempty"`
    // Port mappings for the sandbox.
    PortMappings []*PortMapping `protobuf:"bytes,5,rep,name=port_mappings,json=portMappings,proto3" json:"port_mappings,omitempty"`
    // Key-value pairs that may be used to scope and select individual resources.
    Labels map[string]string `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
    // Unstructured key-value map that may be set by the kubelet to store and
    // retrieve arbitrary metadata. This will include any annotations set on a
    // pod through the Kubernetes API.
    //
    // Annotations MUST NOT be altered by the runtime; the annotations stored
    // here MUST be returned in the PodSandboxStatus associated with the pod
    // this PodSandboxConfig creates.
    //
    // In general, in order to preserve a well-defined interface between the
    // kubelet and the container runtime, annotations SHOULD NOT influence
    // runtime behaviour.
    //
    // Annotations can also be useful for runtime authors to experiment with
    // new features that are opaque to the Kubernetes APIs (both user-facing
    // and the CRI). Whenever possible, however, runtime authors SHOULD
    // consider proposing new typed fields for any new features instead.
    Annotations map[string]string `protobuf:"bytes,7,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
    // Optional configurations specific to Linux hosts.
    Linux                *LinuxPodSandboxConfig `protobuf:"bytes,8,opt,name=linux,proto3" json:"linux,omitempty"`
    XXX_NoUnkeyedLiteral struct{}               `json:"-"`
    XXX_sizecache        int32                  `json:"-"`
}
Copyright © weiliang 2021 all right reserved,powered by Gitbook本书发布时间: 2024-04-22 16:03:41

results matching ""

    No results matching ""