docker-cli & nerdctl & ctr & crictl容器命令比较

一、docker-cli、nerdctl 和 ctr 以及 crictl 介绍

docker, nerdctlctrcrictl 都是用于容器管理的命令行工具,但它们在设计目的、使用场景和技术栈上有所不同。下面分别对这四个工具进行介绍,并指出它们之间的主要差异。

1.1、Docker CLI

Docker CLI(Command Line Interface) 是 Docker 项目提供的官方命令行工具,广泛应用于基于 Docker 技术的容器管理和操作。用户可以通过它来构建、运行、管理和分发 Docker 容器和镜像。Docker CLI 支持与 Docker daemon 通信,执行如创建容器、执行命令、管理网络、数据卷等操作。它的易用性和全面的功能集使其成为容器技术中最流行的工具之一。

  • 特点:用户友好、功能全面,支持广泛的容器管理操作。
  • 适用场景:通用的容器开发、部署和管理任务,特别是与 Docker 引擎集成的环境。

1.2、Nerdctl

nerdctl 是一个与 Docker CLI 风格和语义兼容的命令行工具,专为 Containerd 设计。它由 Rancher Labs 开发,旨在为那些熟悉 Docker CLI 使用方式的用户提供一种更加轻量级且与 Containerd 深度集成的管理工具。Nerdctl 使得从 Docker 迁移到 Containerd 成为一个平滑的过程,因为它支持大部分 Docker CLI 的命令和选项,同时利用了 Containerd 的高效和灵活性。

主要特点:

  • Docker CLI 兼容性:nerdctl 的命令和选项设计与 Docker CLI 高度相似,这意味着 Docker 用户可以几乎无缝地切换到使用 nerdctl,无需重新学习大量新命令。

  • 轻量级:相比于 Docker,nerdctl 直接与 Containerd 交互,避免了 Docker daemon 的额外资源消耗,适合追求更高性能和更小资源占用的场景。

  • Kubernetes 集成友好:由于 Containerd 是 Kubernetes 默认的容器运行时之一,nerdctl 自然非常适合在 Kubernetes 环境下使用,尤其是对于那些希望保持 CLI 统一性和简化管理流程的用户。

  • 增强功能:除了基本的 Docker CLI 兼容功能外,nerdctl 还提供了一些额外的特性和命令,以更好地利用 Containerd 的特性,比如对多平台镜像的支持等。

1.3、Ctr

Ctr 是 Containerd 项目提供的一个轻量级的命令行工具,旨在替代 Docker CLI 在与 Containerd 交互时的角色。Containerd 是一个容器运行时,提供了容器生命周期管理的基础能力,被设计为低层级的系统组件,常作为 Kubernetes 等更高级容器编排系统的底层技术。Ctr 提供了直接管理容器、镜像、沙箱等底层功能,相比 Docker CLI 更加面向底层和系统集成。

  • 特点:轻量、底层、面向系统集成,特别适合与 Containerd 配合使用。
  • 适用场景:在使用 Containerd 作为容器运行时的环境中,进行更底层的容器管理操作,或在 Kubernetes 等平台中作为后台服务的一部分。

1.4、Crictl

Crictl (CRI Control) 是 Kubernetes 项目的容器运行时接口 (CRI, Container Runtime Interface) 的一个命令行客户端工具。CRI 是 Kubernetes 为了支持多种容器运行时而引入的标准接口,允许 Kubernetes 与不同的容器运行时(如 Docker、Containerd、CRI-O 等)通信。Crictl 专门设计用来与实现了 CRI 接口的容器运行时进行交互,进行容器和 Pod 的管理。

  • 特点:专为 Kubernetes 设计,支持多种遵循 CRI 的容器运行时。
  • 适用场景:在 Kubernetes 集群中进行容器和 Pod 的调试、监控等操作,特别是在需要跨不同容器运行时标准化管理操作时。

差异总结

  • 目标用户和场景
    • Docker CLI 面向更广泛的用户群体,特别是那些直接与 Docker 引擎交互的开发者和运维人员;
    • Ctr 更适用于与 Containerd 集成的底层操作和系统级管理;
    • Crictl 则聚焦于 Kubernetes 环境下的容器管理,提供跨容器运行时的一致性操作。
  • 功能和深度
    • Docker CLI 功能最为全面,覆盖了从构建到部署的整个容器生命周期;
    • Ctr 和 Crictl 更专注于底层容器操作,其中 Crictl 通过 CRI 标准化了与容器运行时的交互。
  • 集成与生态系统
    • Docker CLI 与 Docker 生态紧密集成;
    • Ctr 与 Containerd(及背后的 CNCF 生态)相辅相成;
    • Crictl 是 Kubernetes 生态中的一部分,特别适合云原生应用的管理。

二、命令对比

命令描述 docker nerdctl ctr crictl
显示正在运行的容器 docker ps nerdctl ps ctr task ls ctr containers ls crictl ps
显示所有的容器(包含退出等) docker ps -a nerdctl ps -a - crictl ps -a
仅显示容器id docker ps -q nerdctl ps -q ctr containers ls -q crictl ps -q
启动容器 docker run nerdctl run ctr run crictl run
进入容器 docker exec nerdctl exec - crictl exec
停止容器 docker stop nerdctl stop ctr pause -
删除容器 docker rm nerdctl rm ctr task rm -
强制删除 docker rm -f nerdctl rm -f ctr task rm -f -
删除退出状态的所有容器 docker container prune nerdctl container prune - -
copy 文件 docker cp nerdctl cp - -
查看日志 docker logs nerdctl logs - crictl logs
查看容器/镜像元信息 docker inspect nerdctl inspect - crictl inspect/inspecti
查看版本 docker version nerdctl version ctr version crictl version
查看系统级信息 docker info nerdctl info - crictl info
下载镜像 docker pull nerdctl pull ctr images pull crictl pull
删除镜像 docker rmi nerdctl rmi ctr image rm crictl rmi
查看镜像列表 docker images nerdctl images ctr image ls crictl images
镜像tag docker tag nerdctl tag ctr image tag -
镜像仓库登录 docker login nerdctl login - -
镜像仓库登出 docker logout nerdctl logout - -
包方式导入镜像 docker load -i docker import nerdctl load -i nerdctl import -/ctr image import -
包方式导出镜像 dcoker save -o docker export nerdctl save -o ctr image export -
镜像label docker label - ctr image label -
镜像push docker push nerdctl push ctr image push -
镜像构建 docker build nerdctl build - -

三、具体差异

3.1、docker ps -q & nerdctl ps -q & ctr containers ls -q & crictl ps -q 显示的是所有容器的id,还是仅是正在运行容器的ID

docker

shell 复制代码
$ docker ps | wc -l
3     # 包含首行,实际为2

$ docker ps -a | wc -l
8

$ docker ps -q | wc -l
2

docker ps -q 显示的是正在运行的

nerdctl

shell 复制代码
$ nerdctl ps | wc -l
29

$ nerdctl ps -a | wc -l
94

$ nerdctl ps  -q | wc -l
28

crictl

shell 复制代码
$ crictl ps  | wc -l
15

$ crictl ps -a | wc -l
33

$ crictl ps -q | wc -l
14

综上:

docker、nerdctl 和crictl 均是显示正在运行的容器id,ctr 没有-a 命令

3.2 指定运行时 sock

docker, nerdctl, ctr, 和 crictl 这四个命令行工具在与容器运行时(如 Containerd)交互时,对于指定运行时socket(通常为containerd.sock)的方式存在一些差异,这主要是由于它们的设计目的、使用场景以及与底层容器运行时的集成方式不同所致。下面分别说明它们的差异:

Docker
  • 默认配置:Docker 有自己的守护进程(daemon),默认情况下,Docker 客户端会连接到本地的 Docker 守护进程,而不是直接与 Containerd 交互。Docker 守护进程自身负责与容器运行时(可能是 Docker 自带的或其他,如Containerd)的通信。
  • Socket配置 :Docker 守护进程的socket位置通常是固定的(例如,在Linux上通常是 /var/run/docker.sock),用户通常不需要直接指定socket地址。
Nerdctl
  • 设计目的:Nerdctl 是为了提供一个与 Docker CLI 风格和功能相匹配的工具,专为 Containerd 设计。它直接与 Containerd 交互,模仿 Docker CLI 的使用体验。
  • Socket配置 :默认情况下,nerdctl 会查找 Containerd 的默认 socket 位置(通常是 /run/containerd/containerd.sock)。如果修改了containerd.sock路径,可以通过环境变量或如下命令行参数指定不同的socket,例如:
shell 复制代码
  nerdctl --address /path/to/containerd.sock ps
Ctr
  • 定位:Ctr 是 Containerd 自带的低级别命令行工具,主要用于调试和直接管理 Containerd。它提供了更底层的控制能力。

  • Socket配置 :Ctr 也默认查找 /run/containerd/containerd.sock,但可以通过 -a--address 参数显式指定socket位置,例如:

    bash 复制代码
    ctr -a /path/to/containerd.sock containers ls
Crictl
  • Kubernetes集成:Crictl 是为 Kubernetes 与 CRI 兼容的容器运行时(包括 Containerd)设计的。它通过 CRI 接口与运行时通信,主要用于 Kubernetes 环境下的容器管理。

  • Socket配置 :Crictl 通常通过环境变量或配置文件(如 /etc/crictl.yaml)来指定运行时socket,而不是每次执行命令时都指定。例如,在配置文件中,你可以设置 runtime-endpoint 来指定 Containerd 的socket地址。

    shell 复制代码
    $ cat /etc/crictl.yaml 
    runtime-endpoint: unix:///run/containerd/containerd.sock
    image-endpoint: unix:///run/containerd/containerd.sock

3.3 run 命令参数差异

参数 docker run nerdctl run ctr run crictl run
-i
-t
-d
-it
-itd
--env
--network
--name

3.4 覆盖或指定 entrypoint 差异

docker run 允许你通过 --entrypoint 参数覆盖镜像中定义的 ENTRYPOINT。如果你提供了这个参数,指定的命令将会替代镜像中的 ENTRYPOINT,并且可以结合命令参数。例如,docker run --entrypoint "/bin/bash" myimage 将使用 /bin/bash 作为容器的入口点。

nerdctl run 设计上力求与 Docker CLI 兼容,因此它也支持 --entrypoint 参数来覆盖镜像的默认入口点。用法与 docker run 相似,允许你自定义容器启动时执行的第一个命令或脚本。

ctr run 的命令行参数较为基础,它没有直接提供一个等同于 --entrypoint 的参数 来轻松覆盖镜像的 ENTRYPOINT。通常,你需要通过直接指定命令来间接改变入口点行为,这意味着你输入的命令会替代镜像的默认 ENTRYPOINT 和 CMD

crictl 命令行工具并不直接提供 run 命令来启动独立容器,因为它主要针对 Kubernetes 环境下的容器管理。在 Kubernetes 中,容器的启动配置是通过 Pod 的定义(YAML 文件)来完成的,其中包括 commandargs 字段,它们分别对应于镜像的 ENTRYPOINTCMD。这意味着,++你不是通过 crictl 直接指定 entrypoint,而是通过修改 Pod 配置文件来达到目的。++

3.5 都各自支持哪些类型的shell?

支持哪些shell 不由命令行决定,由镜像决定

/etc/shells展示了系统支持哪些shell

shell 复制代码
$ cat /etc/shells
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

如下方式可以查看机器默认的shell

shell 复制代码
$ echo $SHELL
/bin/bash

$ cat /etc/passwd
username:x:UID:GID:User Info:/home/username:/bin/bash

3.6 ctr 和crictl 如何实现docker login 功能

ctr 和 crictl 并没有像docker login这样直接管理registry权限的命令;ctr 用containerd的配置文件 /etc/containerd/config.toml 来存储账号密码,示例如下:

shell 复制代码
   [plugins."io.containerd.grpc.v1.cri".registry.configs."https://index.docker.io/v1/"]
     auth = "YOUR_AUTH_TOKEN"
     username = "YOUR_USERNAME"

crictl 通常与 Kubernetes 集群一起使用,而 Kubernetes 集群的镜像拉取认证信息是通过集群内的服务账户(ServiceAccount)或 ImagePullSecrets 来管理的,而不是直接通过 crictl 登录。但如果你需要在没有 Kubernetes 环境下使用 crictl 与私有 registry 交互,可能需要通过相应 registry 的认证令牌或证书来配置,这与上面一致了。

另外。还可以通过创建secret来实现使用docker的配置文件~/.docker/config.json,如下:

https://kkgithub.com/containerd/containerd/blob/main/vendor/k8s.io/api/core/v1/types.go

go 复制代码
// SecretTypeDockerConfigJson contains a dockercfg file that follows the same format rules as ~/.docker/config.json
//
// Required fields:
// - Secret.Data[".dockerconfigjson"] - a serialized ~/.docker/config.json file
SecretTypeDockerConfigJson SecretType = "kubernetes.io/dockerconfigjson"

参考文档

1、https://kkgithub.com/containerd/containerd/blob/main/cmd/ctr/main.go

2、https://kkgithub.com/docker/cli/blob/master/README.md

3、https://kkgithub.com/containerd/nerdctl

4、https://blog.csdn.net/zfw_666666/article/details/136898245

5、https://www.cnblogs.com/liugp/p/16633732.html

6、https://kkgithub.com/containerd/containerd/blob/main/docs/cri/crictl.md

7、https://kkgithub.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md

相关推荐
城南vision1 分钟前
Docker学习—Docker核心概念总结
java·学习·docker
wclass-zhengge8 分钟前
Docker篇(Docker Compose)
运维·docker·容器
北漂IT民工_程序员_ZG44 分钟前
k8s集群安装(minikube)
云原生·容器·kubernetes
梦魇梦狸º4 小时前
腾讯轻量云服务器docker拉取不到镜像的问题:拉取超时
docker·容器·github
鬼才血脉4 小时前
docker+mysql配置
mysql·adb·docker
詹姆斯爱研究Java4 小时前
Docker 的基本概念和优势
docker
南猿北者6 小时前
docker镜像仓库常用命令
运维·docker·容器
杨浦老苏6 小时前
Docker可视化管理面板DPanel的安装
运维·docker·群晖
2301_806131367 小时前
Kubernetes的基本构建块和最小可调度单元pod-0
云原生·容器·kubernetes
SilentCodeY8 小时前
containerd配置私有仓库registry
容器·kubernetes·containerd·镜像·crictl