资讯详情

Kubernetes权威指南——Kubernetes安装配置指南(容器运行时接口)

📅 2026/10/30 8:31:07 | 华诺云谱 👁 阅读
Kubernetes权威指南——Kubernetes安装配置指南(容器运行时接口)
Kubernetes安装配置指南9、CRI容器运行时接口详解9.1、CRI概述9.2、CRI的主要组件9.3、Pod和容器的生命周期管理9.4、面向容器级别的设计思路9.5、尝试使用新的Docker-CRI来创建容器9.6、CRI的进展9、CRI容器运行时接口详解归根结底Kubernetes Nodekubelet的主要功能就是启动和停止容器的组件我们称之为容器运行时Container Runtime​其中最知名的就是Docker了。为了更具扩展性Kubernetes从1.5版本开始就加入了容器运行时插件API即Container Runtime Interface简称CRI。9.1、CRI概述每个容器运行时都有特点因此不少用户希望Kubernetes能够支持更多的容器运行时。Kubernetes从1.5版本开始引入了CRI接口规范通过插件接口模式Kubernetes无须重新编译就可以使用更多的容器运行时。CRI包含Protocol Buffers、gRPC API、运行库支持及开发中的标准规范和工具。Docker的CRI实现在Kubernetes 1.6中被更新为Beta版本并在kubelet启动时默认启动。可替代的容器运行时支持是Kubernetes中的新概念。在Kubernetes 1.3发布时rktnetes项目同时发布让rkt容器引擎成为除Docker外的又一选择。然而不管是Docker还是rkt都用到了kubelet的内部接口同kubelet源码纠缠不清。这种程度的集成需要对kubelet的内部机制有非常深入的了解还会给社区带来管理压力这就给新生代容器运行时造成了难于跨越的集成壁垒。CRI接口规范试图用定义清晰的抽象层清除这一壁垒让开发者能够专注于容器运行时本身。在通向插件式容器支持及建设健康生态环境的路上这是一小步也是很重要的一步。9.2、CRI的主要组件kubelet使用gRPC框架通过UNIX Socket与容器运行时或CRI代理进行通信。在这个过程中kubelet是客户端CRI代理shim是服务端如图所示。Protocol Buffers API包含两个gRPC服务ImageService和RuntimeService。ImageService提供了从仓库拉取镜像、查看和移除镜像的功能。RuntimeService负责Pod和容器的生命周期管理以及与容器的交互exec/attach/port-forward​。rkt和Docker这样的容器运行时可以使用一个Socket同时提供两个服务在kubelet中可以用–container-runtime-endpoint和–image-service-endpoint参数设置这个Socket。9.3、Pod和容器的生命周期管理Pod由一组应用容器组成其中包含共有的环境和资源约束。在CRI里这个环境被称为PodSandbox。Kubernetes有意为容器运行时留下一些发挥空间它们可以根据自己的内部实现来解释PodSandbox。对于Hypervisor类的运行时PodSandbox会具体化为一个虚拟机。其他例如Docker会是一个Linux命名空间。在v1alpha1 API中kubelet会创建Pod级别的cgroup传递给容器运行时并以此运行所有进程来满足PodSandbox对Pod的资源保障。在启动Pod之前kubelet调用RuntimeService.RunPodSandbox来创建环境。这一过程包括为Pod设置网络资源分配IP等操作​。PodSandbox被激活之后就可以独立地创建、启动、停止和删除不同的容器了。kubelet会在停止和删除PodSandbox之前首先停止和删除其中的容器。kubelet的职责在于通过RPC管理容器的生命周期实现容器生命周期的钩子存活和健康监测以及执行Pod的重启策略等。RuntimeService服务包括对Sandbox和Container操作的方法下面的伪代码展示了主要的RPC方法serviceRuntimeService{// 沙箱操作 rpc RunPodSandbox(RunPodSandboxRequest)returns(RunPodSandboxResponse){}rpc StopPodSandbox(StopPodSandboxRequest)returns(StopPodSandboxResponse){}rpc RemovePodSandbox(RemovePodSandboxRequest)returns(RemovePodSandboxResponse){}rpc PodSandboxStatus(PodSandboxStatusRequest)returns(PodSandboxStatusResponse){}rpc ListPodSandbox(ListPodSandboxRequest)returns(ListPodSandboxResponse){}// 容器操作 rpc CreateContainer(CreateContainerRequest)returns(CreateContainerResponse){}rpc StartContainer(StartContainerRequest)returns(StartContainerResponse){}rpc StopContainer(StopContainerRequest)returns(StopContainerResponse){}rpc RemoveContainer(RemoveContainerRequest)returns(RemoveContainerResponse){}rpc ListContainers(ListContainersRequest)returns(ListContainersResponse){}rpc ContainerStatus(ContainerStatusRequest)returns(ContainerStatusResponse){}......}9.4、面向容器级别的设计思路众所周知Kubernetes的最小调度单元是Pod它曾经可能采用的一个CRI设计就是复用Pod对象使得容器运行时可以自行实现控制逻辑和状态转换这样一来就能极大地简化API让CRI能够更广泛地适用于多种容器运行时。但是经过深入讨论之后Kubernetes放弃了这一想法。首先kubelet有很多Pod级别的功能和机制例如crash-loop backoff机制​如果交给容器运行时去实现则会造成很重的负担其次且更重要的是Pod标准还在快速演进中。很多新功能如初始化容器都是由kubelet完成管理的无须交给容器运行时实现。CRI选择了在容器级别进行实现使得容器运行时能够共享这些通用特性以获得更快的开发速度。这并不意味着设计哲学的改变—kubelet要负责、保证容器应用的实际状态和声明状态的一致性。Kubernetes为用户提供了与Pod及其中的容器进行交互的功能kubectl exec/attach/port- forward​。kubelet目前提供了两种方式来支持这些功能。1调用容器的本地方法。2使用Node上的工具例如nsenter及socat​。因为多数工具都假设Pod用Linux namespace做了隔离因此使用Node上的工具并不是一种容易移植的方案。在CRI中显式定义了这些调用方法让容器运行时进行具体实现。下面的伪代码显示了Exec、Attach、PortForward这几个调用需要实现的RuntimeService方法service RuntimeService{......// ExecSync在容器中同步执行一个命令。rpcExecSync(ExecSyncRequest)returns(ExecSyncResponse){}// Exec在容器中执行命令rpcExec(ExecRequest)returns(ExecResponse){}// Attach附着在容器上rpcAttach(AttachRequest)returns(AttachResponse){}// PortForward从Pod沙箱中进行端口转发rpcPortForward(PortForwardRequest)returns(PortForwardResponse){}......}目前还有一个潜在问题是kubelet处理所有的请求连接使其有成为Node通信瓶颈的可能。在设计CRI时要让容器运行时能够跳过中间过程。容器运行时可以启动一个单独的流式服务来处理请求还能对Pod的资源使用情况进行记录​并将服务地址返回给kubelet。这样kubelet就能反馈信息给API Server使之可以直接连接到容器运行时提供的服务并连接到客户端。9.5、尝试使用新的Docker-CRI来创建容器要尝试新的Kubelet-CRI-Docker集成只需为kubelet启动参数加上–enable-critrue开关来启动CRI。这个选项从Kubernetes 1.6开始已经作为kubelet的默认选项了。如果不希望使用CRI则可以设置–enable-crifalse来关闭这个功能。查看kubelet的日志可以看到启用CRI和创建gRPCServer的日志I060315:08:28.9533323442container_manager_linux.go:250]Creating Container Manager object based on Node Config:{RuntimeCgroupsName: SystemCgroupsName: KubeletCgroupsName: ContainerRuntime:docker CgroupsPerQOS:true CgroupRoot:/ CgroupDriver:cgroupfs ProtectKernelDefaults:false EnableCRI:true NodeAllocatableConfig:{KubeReservedCgroupName: SystemReservedCgroupName: EnforceNodeAllocatable:map[pods:{}]KubeReserved:map[]SystemReserved:map[]HardEvictionThresholds:[{Signal:memory.available Operator:LessThan Value:{Quantity:100Mi Percentage:0}GracePeriod:0s MinReclaim:nil}]}ExperimentalQOSReserved:map[]}......I060315:08:29.0602833442kubelet.go:573]Starting the GRPC serverforthedockerCRI shim.创建一个Deployment$ kubectl run nginx--imagenginx deploymentnginx created查看Pod的详细信息可以看到将会创建沙箱Sandbox的Event$ kubectl describe pod nginx......Events:...From Type Reason Message...----------------- ----- --------------- -----------------------------...default-scheduler Normal Scheduled Successfully assigned nginx to k8s-node-1...kubelet, k8s-node-1 Normal SandboxReceived Pod sandbox received, it will be created.......这表明kubelet使用了CRI接口来创建容器。9.6、CRI的进展目前已经有多款开源CRI项目可用于KubernetesDocker、CRI-O、Containerd、frakti基于Hypervisor的容器运行时​各CRI运行时的安装手册可参考官网https://kubernetes.io/docs/setup/cri/的说明。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑