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 生态中的一部分,特别适合云原生应用的管理。

二、命令对比

命令描述dockernerdctlctrcrictl
显示正在运行的容器docker psnerdctl psctr task ls
ctr containers ls
crictl ps
显示所有的容器(包含退出等)docker ps -anerdctl ps -a-crictl ps -a
仅显示容器iddocker ps -qnerdctl ps -qctr containers ls -qcrictl ps -q
启动容器docker runnerdctl runctr runcrictl run
进入容器docker execnerdctl exec-crictl exec
停止容器docker stopnerdctl stopctr pause-
删除容器docker rmnerdctl rmctr task rm -
强制删除docker rm -fnerdctl rm -fctr task rm -f-
删除退出状态的所有容器docker container prunenerdctl container prune--
copy 文件docker cpnerdctl cp--
查看日志docker logsnerdctl logs-crictl logs
查看容器/镜像元信息docker inspectnerdctl inspect-crictl inspect/inspecti
查看版本docker versionnerdctl versionctr versioncrictl version
查看系统级信息docker infonerdctl info-crictl info
下载镜像docker pullnerdctl pullctr images pullcrictl pull
删除镜像docker rminerdctl rmictr image rmcrictl rmi
查看镜像列表docker imagesnerdctl imagesctr image lscrictl images
镜像tagdocker tagnerdctl tagctr image tag-
镜像仓库登录docker loginnerdctl login--
镜像仓库登出docker logoutnerdctl logout--
包方式导入镜像docker load -i
docker import
nerdctl load -i
nerdctl import
-/ctr image import-
包方式导出镜像dcoker save -o
docker export
nerdctl save -octr image export-
镜像labeldocker label-ctr image label-
镜像pushdocker pushnerdctl pushctr image push-
镜像构建docker buildnerdctl build--

三、具体差异

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

docker

$ docker ps | wc -l
3     # 包含首行,实际为2

$ docker ps -a | wc -l
8

$ docker ps -q | wc -l
2

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

nerdctl

$ nerdctl ps | wc -l
29

$ nerdctl ps -a | wc -l
94

$ nerdctl ps  -q | wc -l
28

crictl

$ 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,例如:
  nerdctl --address /path/to/containerd.sock ps
Ctr
  • 定位:Ctr 是 Containerd 自带的低级别命令行工具,主要用于调试和直接管理 Containerd。它提供了更底层的控制能力。

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

    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地址。
    $ cat /etc/crictl.yaml 
    runtime-endpoint: unix:///run/containerd/containerd.sock
    image-endpoint: unix:///run/containerd/containerd.sock
    

3.3 run 命令参数差异

参数docker runnerdctl runctr runcrictl 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

$ cat /etc/shells
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

如下方式可以查看机器默认的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 来存储账号密码,示例如下:

   [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

// 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.youkuaiyun.com/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
8、https://blog.51cto.com/tommy1108/7524409

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值