kubelet触发cni del基本流程和异常流程分析
k8s v1.19.0
结论
kubelet删除pod时,先停止业务容器,再完成cni del。
如果cni del失败(非no such file or directory错误),那么kubelet会一直重试。
kubelet调用docker,才会打印"Calling network plugin"日志;kubelet调用cri,不会打印这个。
正常流程
pkg/kubelet/kubelet.go
syncLoopIteration方法
感知到pod进入删除中
pkg/kubelet/kubelet.go
dispatchWork方法
异步处理删除中pod
pkg/kubelet/kubelet.go
syncPod方法
根据pod的DeletionTimestamp条件,开始清理pod。
pkg/kubelet/kuberuntime/kuberuntime_manager.go
killPodWithSyncResult方法
停止pause容器
pkg/kubelet/cri/remote/remote_runtime.go
StopPodSandbox方法
通过cri停止pause容器
pkg/kubelet/dockershim/docker_sandbox.go
StopPodSandbox方法
通过docker调用cni del
pkg/kubelet/dockershim/network/plugins.go
TearDownPod方法
调用cni插件完成网络删除
pkg/kubelet/dockershim/network/cni/cni.go
deleteFromNetwork方法
删除网络时支持幂等,忽略不存在ns等no such file or directory错误。
异常流程
pkg/kubelet/pod_workers.go
managePodLoop方法
cni del失败时(非no such file or directory错误),导致kubelet的syncPod流程失败,通过wrapUp方法重新把pod放入队列后重试。
pkg/kubelet/pod_workers.go
wrapUp方法
重新把pod放入队列后重试。
问题1:如何判断先停止业务容器再cni del?
pkg/kubelet/kuberuntime/kuberuntime_manager.go
killPodWithSyncResult方法
先停止业务容器再停止pause容器(调用cni插件完成del)
pkg/kubelet/kuberuntime/kuberuntime_container.go
killContainersWithSyncResult方法
停止所有业务容器