先来简单回顾上一篇博客《kubernetes/k8s CRI 分析-容器运行时接口分析》的内容。
上篇博文先对 CRI 做了介绍,然后对 kubelet CRI 相关源码包括 kubelet 组件 CRI 相关启动参数分析、CRI 相关 interface/struct 分析、CRI 相关初始化分析 3 个部分进行了分析,没有看的小伙伴,可以点击上面的链接去看一下。
把上一篇博客分析到的CRI架构图再贴出来一遍。
本篇博文将对kubelet调用CRI创建pod做分析。
kubelet中CRI相关的源码分析
kubelet的CRI源码分析包括如下几部分:
(1)kubelet CRI相关启动参数分析;
(2)kubelet CRI相关interface/struct分析;
(3)kubelet CRI初始化分析;
(4)kubelet调用CRI创建pod分析;
(5)kubelet调用CRI删除pod分析。
上篇博文先对前三部分做了分析,本篇博文将对kubelet调用CRI创建pod做分析。
基于tag v1.17.4
https://github.com/kubernetes/kubernetes/releases/tag/v1.17.4
4.kubelet调用CRI创建pod分析
kubelet CRI创建pod调用流程
下面以kubelet dockershim创建pod调用流程为例做一下分析。
kubelet通过调用dockershim来创建并启动容器,而dockershim则调用docker来创建并启动容器,并调用CNI来构建pod网络。
图1:kubelet dockershim创建pod调用流程图示
dockershim属于kubelet内置CRI shim,其余remote CRI shim的创建pod调用流程其实与dockershim调用基本一致,只不过是调用了不同的容器引擎来操作容器,但一样由CRI shim调用CNI来构建pod网络。
下面开始详细的源码分析。
直接看到kubeGenericRuntimeManager
的SyncPod
方法,调用CRI创建pod的逻辑将在该方法里触发发起。
从该方法代码也可以看出,kubelet创建一个pod的逻辑为:
(1)先创建并启动pod sandbox容器,并构建好pod网络;
(2)创建并启动ephemeral containers;
(3)创建并启动init containers;
(4)最后创建并启动normal containers(即普通业务容器)。
这里对调用m.createPodSandbox
来创建pod sandbox
进行分析,m.startContainer
等调用分析可以参照该分析自行进行分析,调用流程几乎一致。
// pkg/kubelet/kuberuntime/kuberuntime_manager.go
// SyncPod syncs the running pod into the desired pod by executing following steps:
//
// 1. Compute sandbox and container changes.
// 2. Kill pod sandbox if necessary.
// 3. Kill any containers that should not be running.
// 4. Create sandbox if necessary.
// 5. Create ephemeral containers.
// 6. Create init containers.
// 7. Create normal containers.
func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff) (result kubecontainer.PodSyncResult) {
...
// Step 4: Create a sandbox for the pod if necessary.
podSandboxID := podContainerChanges.SandboxID
if podContainerChanges.CreateSandbox {
var msg string
var err error
klog.V(4).Infof("Creating sandbox for pod %q", format.Pod(pod))
createSandboxResult := kubecontainer.NewSyncResult(kubecontainer.CreatePodSandbox, format.Pod(pod))
result.AddSyncResult(createSandboxResult)
podSandboxID, msg, err = m.createPodSandbox(pod, podContainerChanges.Attempt)
...
}
4.1 m.createPodSandbox
m.createPodSandbox方法主要是调用m.runtimeService.RunPodSandbox
。
runtimeService即RemoteRuntimeService,实现了CRI shim客户端-容器运行时接口RuntimeService interface
,持有与CRI shim容器运行时服务端通信的客户端。所以调用m.runtimeService.RunP