一 前言
CNI和kubelet关系
kubelet负责创建POD,POD启动和删除(可以类比为虚拟机)需要设置网络环境。kubelet自身不关心网络实现,它调用CNI实现。
CNI实现能否同时存在多个?
答案:可以有多个,但是kubelet只会使用第一个有效的插件。如果不同的POD网络插件不一致,它们将无法通信。
二 kubelet启动
image
2.1 kubelet启动命令
kubelet \
--network-plugin=cni
--cni-conf-dir=/etc/cni/net.d
--cni-bin-dir=/opt/cni/bin
...
通过--network-plugin指定要使用的网络插件类型。
2.2 Runtime设置
cmd/kubelet/app/server.go:createAndInitKubelet
默认k8s的运行时是Docker。
switch containerRuntime {
case kubetypes.DockerContainerRuntime:
streamingConfig := getStreamingConfig(kubeCfg, kubeDeps, crOptions)
ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,
&pluginSettings, runtimeCgroups, kubeCfg.CgroupDriver, crOptions.DockershimRootDirectory, !crOptions.RedirectContainerStreaming)
// 省略...
case kubetypes.RemoteContainerRuntime:
// No-op.
break
default:
return nil, fmt.Errorf("unsupported CRI runtime: %q", containerRuntime)
}
2.3 网络插件加载
pkg/kubelet/dockershim/docker_service.go:NewDockerService
网络插件有两种实现cni、kubenet,一般都使用cni。
func NewDockerService(config *ClientConfig, podSandboxImage string, streamingConfig *streaming.Config, pluginSettings *NetworkPluginSettings,