Kubernetes 现场排障必备:crictl vs ctr 讲清楚

在 K8s 节点上排查容器问题时,你经常会看到两类命令:

  • crictl:看起来像 “docker”,但又不是 docker
  • ctr:containerd 自带的 CLI,很多命令很“底层”,还带 namespace

它们都能“看到容器”,但服务对象、抽象层级、适用场景完全不同。搞清楚这一点,你在生产排障会快很多。


目录


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 来源

  • ctrcontainerd 项目自带的命令行(官方 CLI)
  • 主要用途:开发/调试/底层管理 containerd 对象

3.2 意义(为什么存在)

containerd 内部管理的对象很多:imagescontentsnapshotscontainerstasksnamespaces……
ctr 提供的就是一把“直通 containerd 内核”的扳手。

3.3 职责边界(它能做什么)

ctr 能做的核心事情:

  • 直接操作 containerd 的 namespaces
  • 管理 images / content / snapshots / containers / tasks
  • 运行容器任务(task)并附着(但体验不如 docker)
  • 它看见的是 “containerd 语义”:task、snapshot、content、namespace

注意:在 K8s 节点上,你用 ctr 看 Pod,必须切到 k8s.io namespace,否则你会发现“啥也没有”。


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、看快照/内容存储
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐