所有文章

k8s CRI

CRI(container runtime interface)

在1.5以前的版本中,k8s依赖于dokcer,为了与docker解耦并支持更多的容器运行时,比如rkt、containerd,kubelet从1.5开始加入了CRI,作为k8s和容器运行时通信的标准,CRI是一组rpc接口,也就是说只要是实现了这组接口都可以作为kubelet的运行时,另外在k8s内部将之前的Pod抽象为一种更为通用的SandBox。

接口定义

接口实现

提出了CRI标准以后,意味着在新的版本里需要使用新的连接方式与docker通信,也就是说docker端需要按CRI的标准实现一个rpc的服务端,所以为了兼容以前的版本,不改变用户习惯,k8s提供了针对docker的CRI实现,也就是k8s源码中kubelet包下的dockershim包,dockershim是一个rpc服务,监听一个端口供kubelet连接,dockershim收到kubelet的请求后,将其转化为REST API请求,发送给物理机上的docker daemon,以下是创建和启动dockershim的代码(k8s v1.11版本):

pkg/kubelet/kubelet.go:NewMainKubelet():617

// 创建dockershim
ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,
...
// 启动rpc服务
if err := server.Start(); err != nil {

创建Docker客户端的逻辑是在创建dockershim的过程中,关键代码:

pkg/kubelet/dockershim/libdocker/client.go:100

client, err := getDockerClient(dockerEndpoint)

client对象就是docker的客户端,包含了我们常用的docker rundocker images等所有操作,其中dockerEndpoint变量就是kubelet启动参数--container-runtime-endpoint选项的值,默认是unix:///var/run/docker.sock

k8s调用容器运行时过程如下:

kubelet -> remote -> CRI -> dockershim -> docker_client -> docker_daemon

在Github上阅读完整的源码: - CRI客户端实现(remote包): pkg/kubelet/remote,与容器相关的逻辑主要在remote_runtime.go文件中。 - CRI服务端实现(dockershim包): pkg/kubelet/dockershim,与容器相关的逻辑主要在docker_container.go文件中。 - dockershim调用Docker的逻辑: pkg/kubelet/dockershim/libdocker

kubelet相关参数

//指定资源管理驱动
--runtime-cgroups cgroupfs
//指定容器运行时
--container-runtime docker
//指定docker daemon的地址
--docker-endpoint unix:///var/run/docker.sock
//创建dockershim服务,供kubelet连接
--container-runtime-endpoint unix:///var/run/dockershim.sock
--image-service-endpoint unix:///var/run/dockershim.sock

相关资料


编写日期:2018-07-21