CRI(Container Runtime Interface,容器运行时接口)是 kubelet 与容器运行时之间的标准接口,也是 CKA 考试的重要知识点。它对应官方课程 Cluster Architecture(集群架构,权重 25%)中的 “Understand extension interfaces (CNI, CSI, CRI)” 主题,属于扩展接口里必考的一项。考试不只考概念,更常以节点排障的形式考察 ctr、nerdctl、crictl 三个命令行工具的实际用法。
本篇把 CRI 的原理、容器运行时的演进以及三个工具与 docker 的语法对照整理成一份可直接背诵的备考笔记。先搞懂 CRI 是什么,再记住每个工具的命令对照,最后用高频检查命令清单收尾,考场上遇到运行时相关的题目就不会慌。
适用对象:CKA 考生
考察范围:CRI 原理、容器运行时演进、ctr/nerdctl/crictl命令行工具
核心对照:三个工具与docker命令语法对照
1. CRI:概念与演进
CRI 定义:CRI 是 kubelet 与容器运行时之间约定的 gRPC 接口,kubelet 不关心运行时具体实现,只要满足 CRI 规范就能接入。它由两个 gRPC 服务组成:RuntimeService 负责 Pod 沙箱(PodSandbox)与容器的创建、启停、删除;ImageService 负责镜像的拉取、列表与删除。
OCI 规范:CRI 之上还有 OCI(Open Container Initiative)约束运行时行为。runtime-spec 定义了容器运行时的标准,runc 是最常见的实现;image-spec 定义了镜像格式标准。完整的调用链是 kubelet → CRI → containerd / CRI-O → OCI → runc,每一层只关心自己的职责。
dockershim 历史:Docker 出现早于 Kubernetes,早期 kubelet 通过内置的 dockershim 组件把 CRI 调用翻译成 Docker API。由于维护成本高,k8s 在 1.24(2022 年 4 月)正式移除 dockershim,containerd 成为 kubeadm 默认的 CRI 运行时。有意思的是,Docker 引擎底层本来就在用 containerd,移除后只是少了一层 Docker 自己的 API。
| 演进阶段 | 说明 |
|---|---|
| Docker 引擎 | Docker CLI / API 之上运行 containerd + runc,kubelet 无法直接使用 |
dockershim | kubelet 内置的适配层,把 CRI 调用翻译成 Docker API,维护成本高 |
| CRI 标准化 | 引入 containerd / CRI-O 直接实现 CRI,去掉中间翻译层 |
移除 dockershim | k8s 1.24 移除,containerd 成为默认 CRI 运行时 |
2. ctr:containerd 原生底层命令
ctr 是 containerd 自带的命令行客户端,定位低层,命令风格与 Docker 不兼容,主要用于调试和运维 containerd 本身。它默认使用 default namespace,而 Kubernetes 的资源放在 k8s.io namespace 下,因此查看 k8s 相关容器与镜像必须加 -n k8s.io。
| |
-n / --namespace 标志用于指定命名空间,也可以用环境变量 CONTAINERD_NAMESPACE 设置默认值,设置后后续命令可以省略 -n。注意 ctr tasks exec 对应 docker exec;ctr run 隐含了创建与启动两步,而 ctr containers create + ctr containers start 是拆开的两步操作。
containerd 2.x 的主要变化:
- 移除 CRI
v1alpha2,只保留v1 - 移除
aufssnapshotter,只剩overlayfs等主流实现 - schema1 旧格式镜像默认无法拉取,需要设置
CONTAINERD_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE=1并配合--local参数 - 新增
ctr deprecations list查看弃用项清单 - 新增
ctr sandboxes命令管理沙箱 - 当前版本为 v2.3.4,属于 2.3 LTS 线
| docker | ctr(k8s 场景加 -n k8s.io) |
|---|---|
docker images | ctr images ls |
docker pull | ctr images pull |
docker ps | ctr containers ls |
docker run -d | ctr run -d |
docker exec | ctr tasks exec |
3. nerdctl:Docker 兼容的 containerd CLI
nerdctl 是 containerd 生态中的类 Docker CLI,命令名与 docker 几乎一一对应,目标是让 containerd 用起来和 Docker 一样顺手。它依赖 containerd daemon 提供容器能力、CNI 插件提供网络、BuildKit 提供镜像构建;nerdctl-full 捆绑包一次装齐全部依赖,是免去逐个安装的省心选择。
常用全局 flag:
--namespace:指定命名空间,默认default,k8s 资源用k8s.io-H/--host:指定 containerd 服务地址--snapshotter:指定快照器,如overlayfs--cgroup-manager:cgroup 管理器,如systemd--insecure-registry:允许非 HTTPS 镜像仓库--data-root:数据目录--cni-path:CNI 插件路径
| |
| docker | nerdctl |
|---|---|
docker run | nerdctl run |
docker build | nerdctl build |
docker compose | nerdctl compose |
docker network | nerdctl network |
docker ps | nerdctl ps |
4. crictl:CRI 调试客户端(CKA 核心)
crictl 是 cri-tools 项目提供的 CRI 调试客户端,直接与 CRI 运行时通信,不经过 kubelet。它是 Kubernetes 节点排障的专用工具,killer.sh 和 KodeKloud 模拟环境都经常考,是三个工具里 CKA 备考价值最高的一个。
配置文件默认位于 /etc/crictl.yaml,也可以放到用户级路径 $XDG_CONFIG_HOME/crictl/crictl.yaml。执行 crictl config 可以交互式生成配置,crictl config --set runtime-endpoint=unix:///var/run/containerd/containerd.sock 可以单独修改某项。
| |
常用命令与 flag(已对照 cri-tools 源码验证):
crictl ps:列出容器;-a/--all包含已退出容器,-p/--pod按 Pod 过滤,--image按镜像过滤,-s/--state按状态过滤,--name按容器名正则过滤,--namespace按 Pod 命名空间正则过滤,--label按标签过滤,-o json|yaml|table控制输出格式,-l/--latest只显示最近一个,-n/--last显示最近 N 个,--no-trunc不截断输出crictl pods:列出 Pod 沙箱,--namespace按命名空间正则过滤crictl images/crictl pull/crictl rmi:镜像管理crictl inspect/crictl inspectp/crictl inspecti:分别查看容器、Pod 沙箱、镜像详情crictl logs:查看容器日志;-f/--follow持续输出,-p/--previous查看上一次实例,--tail指定行数,-t/--timestamps显示时间戳crictl exec:进入容器,-i/-t语义与docker exec一致,--pod指定所属 Pod,--name按名称选中容器crictl stats:查看容器资源占用crictl runp/create/start/stop/rm/stopp/rmp:手动管理 Pod 沙箱与容器crictl info:查看运行时信息crictl version:查看客户端与运行时版本
| docker | crictl |
|---|---|
docker ps | crictl ps -a |
docker images | crictl images |
docker pull | crictl pull |
docker exec -it | crictl exec -it |
docker logs | crictl logs |
考题场景:Pod 状态异常是 CKA 节点排障的常考题型,典型的排查链如下。
k get pods显示ContainerCreating、CrashLoopBackOff或ImagePullBackOff,先k describe pod看事件。- SSH 到 Pod 所在节点,用
crictl ps -a查看容器实际状态(含已退出容器)。- 用
crictl logs <container-id>看应用日志,判断是启动崩溃还是配置错误。- 用
crictl inspect <container-id>看容器配置、挂载与退出码。- 镜像拉取失败时,先
crictl images确认本地是否有镜像,再手动crictl pull <image>验证仓库连通性。
| |
5. Docker 与三工具总对照
| 操作 | docker | nerdctl | ctr | crictl |
|---|---|---|---|---|
| 查看容器 | docker ps | nerdctl ps | ctr containers ls | crictl ps -a |
| 查看镜像 | docker images | nerdctl images | ctr images ls | crictl images |
| 拉取镜像 | docker pull | nerdctl pull | ctr images pull | crictl pull |
| 运行容器 | docker run -d | nerdctl run -d | ctr run -d | crictl runp + create + start |
| 进入容器 | docker exec -it | nerdctl exec -it | ctr tasks exec | crictl exec -it |
| 查看日志 | docker logs | nerdctl logs | 不支持(直接读文件) | crictl logs |
| 构建镜像 | docker build | nerdctl build | 不支持 | 不支持 |
| 编排 | docker compose | nerdctl compose | 不支持 | 不支持 |
| 网络 | docker network | nerdctl network | 不支持 | 不支持 |
关键差异:
ctr不能构建镜像,也没有 compose 与网络管理能力,它的职责就是调试 containerd 本身crictl与ctr都不管理 CNI 网络docker build对应nerdctl build,依赖 BuildKitdocker compose对应nerdctl composecrictl的runp+create+start面向 Pod 沙箱与容器,而不是单容器
一句话定位:
ctr是底层调试工具,nerdctl是类 Docker 的日常操作工具,crictl是 CKA 节点排障的首选。
6. crictl 配置与常见易错点
/etc/crictl.yaml 完整示例:
| |
如果节点运行的是 CRI-O,把两个 endpoint 改成 unix:///var/run/crio/crio.sock 即可。
版本对应关系:
crictl/ cri-tools v1.36.0,跟随 Kubernetes 小版本发布,k8s 当前稳定版为 1.37containerdv2.3.4,位于 2.3 LTS 线nerdctlv2.3.5
常见易错点:
ctr默认 namespace 是default,不是k8s.io,不加-n k8s.io就看不到 k8s 资源crictl ps不带-a看不到已退出的容器,排查崩溃重启必须加-acrictl通过 CRI 直接与运行时通信,绕过 kubelet,所以它看到的容器名是 sandbox 名称,而不是kubectl里的 Pod 名runtime-endpoint配错会导致crictl连不上运行时,报连接失败错误,先检查/etc/crictl.yaml
高频检查命令
| |
考场压缩记忆
- dockershim:k8s 1.24 已移除,containerd 成为默认 CRI 运行时。
- CRI:kubelet 与运行时之间的 gRPC 接口,含
RuntimeService与ImageService两个服务。 - ctr 命名空间:默认
default,k8s 资源在k8s.io,查看必须加-n k8s.io。 - crictl 配置:默认读取
/etc/crictl.yaml,也可用用户级$XDG_CONFIG_HOME/crictl/crictl.yaml。 - 三工具定位:
ctr底层调试,nerdctl类 Docker 日常操作,crictl节点排障首选。 - crictl ps -a:排查崩溃重启必加
-a,否则看不到已退出容器。 - crictl 视角:看到的容器名是 sandbox 名称,不是
kubectl里的 Pod 名。