Kubernetes 现场排障必备:crictl vs ctr 讲清楚
crictl:K8s 节点排障首选工具,因为它和 kubelet 看的世界一致(CRI 视角)ctr:containerd 底层工具,用于更深层的 runtime/镜像/快照/内容存储/namespace 排障在 K8s 节点上用 ctr 时,永远先确认-n k8s.io。
Kubernetes 现场排障必备:crictl vs ctr 讲清楚
在 K8s 节点上排查容器问题时,你经常会看到两类命令:
- crictl:看起来像 “docker”,但又不是 docker
- ctr:containerd 自带的 CLI,很多命令很“底层”,还带 namespace
它们都能“看到容器”,但服务对象、抽象层级、适用场景完全不同。搞清楚这一点,你在生产排障会快很多。
目录
- 1. 关系地图:K8s、CRI、containerd、runc
- 2. crictl 是什么(来源/意义/职责)
- 3. ctr 是什么(来源/意义/职责)
- 4. 一句话讲透核心区别
- 5. crictl 详细用法(排障高频)
- 6. ctr 详细用法(重点:namespace)
- 7. 对比表:crictl vs ctr
- 8. 典型场景:到底用哪个
- 9. 易混概念:ctr ≠ nerdctl
- 10. 建议收藏:节点排障标准动作
- 11. 总结(可写进团队规范)
1. 关系地图:K8s、CRI、containerd、runc
Kubernetes 并不直接管容器,它通过 CRI(Container Runtime Interface) 去管容器运行时(Runtime)。
以 containerd 为例,典型链路如下:
- kubelet
→ 通过 CRI
→ 调用 containerd 的 CRI 插件(cri)
→ containerd 再调用 runc(或其他 OCI runtime)
→ 最终在 Linux 上跑起来(namespaces/cgroups)
因此:
- crictl = “CRI 客户端”(站在 kubelet 的同一层看世界)
- ctr = “containerd 客户端”(直接操纵 containerd 内部对象,更底层)
2. crictl 是什么(来源/意义/职责)
2.1 来源
- crictl 来自 Kubernetes 社区(cri-tools 项目)
- 目标是提供一个 CLI,对任何符合 CRI 的 runtime 都通用
- containerd(最常见)
- CRI-O
- 其他实现 CRI 的 runtime
2.2 意义(为什么需要它)
当节点不再使用 Docker(尤其是 K8s 1.24+ 去掉 dockershim 之后),你不能再用 docker ps 看 Pod 了。
此时你需要一个“站在 kubelet/CRI 视角”的工具 —— crictl。
2.3 职责边界(它能做什么)
crictl 能做的核心事情:
- 查看 PodSandbox / Container(CRI 概念)
- 查看/拉取/删除 镜像(CRI image service)
- 查看容器日志、执行命令、查看状态与事件(偏排障)
- 它看见的是 “K8s 语义”:Pod、Sandbox、容器与其生命周期
3. ctr 是什么(来源/意义/职责)
3.1 来源
- ctr 是 containerd 项目自带的命令行(官方 CLI)
- 主要用途:开发/调试/底层管理 containerd 对象
3.2 意义(为什么存在)
containerd 内部管理的对象很多:images、content、snapshots、containers、tasks、namespaces……
ctr 提供的就是一把“直通 containerd 内核”的扳手。
3.3 职责边界(它能做什么)
ctr 能做的核心事情:
- 直接操作 containerd 的 namespaces
- 管理 images / content / snapshots / containers / tasks
- 运行容器任务(task)并附着(但体验不如 docker)
- 它看见的是 “containerd 语义”:task、snapshot、content、namespace
注意:在 K8s 节点上,你用 ctr 看 Pod,必须切到
k8s.ionamespace,否则你会发现“啥也没有”。
4. 一句话讲透核心区别
- crictl:面向 CRI(面向 kubelet / K8s Pod 语义)
- ctr:面向 containerd(面向 containerd 内部对象与 namespace)
实战建议:
- 排查 “为什么 Pod 起不来/CrashLoop/镜像拉不下来/容器状态异常”
→ 优先 crictl - 排查 “containerd 内部镜像/快照/内容存储/namespace/任务层面的异常”
→ 再用 ctr
5. crictl 详细用法(排障高频)
5.1 配置端点(非常关键)
crictl 需要知道 CRI 的 socket 在哪。
常见(containerd):
unix:///run/containerd/containerd.sock注:不同发行版可能有所差异,请以实际环境为准
建议写配置文件:/etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
检查是否连通:
crictl info
5.2 Pod / 容器查看
列出 PodSandbox(K8s 的 Pod 沙箱):
crictl pods
crictl pods -a
列出容器:
crictl ps
crictl ps -a
查看某个容器详情:
crictl inspect <container_id>
查看某个 PodSandbox 详情:
crictl inspectp <pod_id>
5.3 日志与进入容器
看日志:
crictl logs <container_id>
crictl logs -f <container_id>
crictl logs --tail=200 <container_id>
进容器执行命令(类似 docker exec):
crictl exec -it <container_id> /bin/sh
crictl exec -it <container_id> bash
5.4 镜像管理
列镜像:
crictl images
拉镜像:
crictl pull registry.example.com/ns/app:tag
删镜像:
crictl rmi <image_id_or_ref>
清理不用的镜像(谨慎):
crictl rmi --prune
5.5 生命周期操作(慎用)
停止容器:
crictl stop <container_id>
删除容器:
crictl rm <container_id>
停止 PodSandbox:
crictl stopp <pod_id>
删除 PodSandbox:
crictl rmp <pod_id>
生产上一般不推荐手动“强行删”,除非 kubelet 卡住/垃圾对象清不掉。
6. ctr 详细用法(重点:namespace)
6.1 先看 namespace
ctr namespaces list
在 K8s 节点上,Pod 通常在:
k8s.io
后续命令基本都要加 -n k8s.io:
ctr -n k8s.io containers list
ctr -n k8s.io tasks list
ctr -n k8s.io images list
6.2 镜像相关
列镜像:
ctr -n k8s.io images ls
拉镜像:
ctr -n k8s.io images pull registry.example.com/ns/app:tag
查看镜像详细信息:
ctr -n k8s.io images info registry.example.com/ns/app:tag
删除镜像(注意可能有引用/快照占用):
ctr -n k8s.io images rm registry.example.com/ns/app:tag
6.3 容器与 task
在 containerd 里:
- container 是“配置 + 快照引用”
- task 才是“正在跑的进程”
列容器:
ctr -n k8s.io containers ls
列任务(运行态):
ctr -n k8s.io tasks ls
查看 task 详细:
ctr -n k8s.io tasks info <task_id>
杀 task(慎用):
ctr -n k8s.io tasks kill -s SIGKILL <task_id>
6.4 快照/内容存储(更底层)
列快照(取决于 snapshotter,比如 overlayfs):
ctr -n k8s.io snapshots ls
看内容(content store):
ctr -n k8s.io content ls
这些通常用于排查:
- 镜像层损坏
- content store 占用异常
- snapshot 残留导致磁盘满
7. 对比表:crictl vs ctr
| 维度 | crictl | ctr |
|---|---|---|
| 面向对象 | CRI(PodSandbox/Container/Image) | containerd 内部对象(namespace/task/snapshot/content) |
| 抽象层级 | 更贴近 kubelet / K8s 语义 | 更底层,直通 containerd |
| 默认是否“看得见 K8s Pod” | 是 | 否(需要 -n k8s.io) |
| 常见用途 | 节点排障首选:容器状态、日志、exec、镜像拉取 | 深度排障:namespace、镜像层/快照/内容存储、task 异常 |
| 易用性 | 高(更像 docker) | 低(更像内部调试工具) |
| 是否建议日常使用 | 建议(排障必备) | 不建议日常,必要时用 |
| 替代 docker 的程度 | 很高(节点排障层面) | 很低(概念不同) |
8. 典型场景:到底用哪个
场景 A:Pod 起不来 / ImagePullBackOff
优先:
crictl pods -a
crictl ps -a
crictl logs <cid> --tail=200
crictl pull <image>
怀疑 containerd 镜像层/namespace 再用:
ctr namespaces list
ctr -n k8s.io images ls
场景 B:节点磁盘满(/var/lib/containerd 爆了)
需要 ctr 的“底层视角”:
ctr -n k8s.io snapshots ls
ctr -n k8s.io content ls
ctr -n k8s.io images ls
场景 C:你用 ctr 看不到 Pod,以为“没跑”
99% 原因:忘了 namespace:
ctr -n k8s.io tasks ls
场景 D:容器里临时执行命令确认文件/环境变量
crictl 一步到位:
crictl exec -it <cid> /bin/sh
9. 易混概念:ctr ≠ nerdctl
很多人用 ctr 觉得“太难用”,很正常:
- ctr:官方低层 CLI(偏调试/底层)
- nerdctl:更像 docker 的 containerd CLI(更适合日常人类操作)
如果你想要接近 docker 的体验,通常会装 nerdctl:
nerdctl ps
nerdctl images
本文聚焦 crictl vs ctr,所以 nerdctl 仅作补充认知。
10. 建议收藏:节点排障标准动作
10.1 先用 crictl(K8s 语义)
crictl info
crictl pods -a
crictl ps -a
crictl logs <cid> --tail=200
crictl exec -it <cid> /bin/sh
crictl images
10.2 再用 ctr(containerd 内部语义)
ctr namespaces list
ctr -n k8s.io images ls
ctr -n k8s.io containers ls
ctr -n k8s.io tasks ls
ctr -n k8s.io snapshots ls
ctr -n k8s.io content ls
11. 总结(可写进团队规范)
- crictl:K8s 节点排障首选工具,因为它和 kubelet 看的世界一致(CRI 视角)
- ctr:containerd 底层工具,用于更深层的 runtime/镜像/快照/内容存储/namespace 排障
- 在 K8s 节点上用 ctr 时,永远先确认
-n k8s.io
附:快速记忆口诀
- crictl:看 Pod、看日志、进容器
- ctr:看 namespace、看 task、看快照/内容存储
更多推荐
所有评论(0)