资讯详情

containerd

文章目录

  • 容器运行时
    • Docker
    • CRI
  • Containerd
    • 架构
    • 安装
    • 配置
    • 使用(contianerd的CLI:ctr)
    • 镜像操作
      • 拉取镜像
      • 列出本地镜像
      • 检测本地镜像
      • 重新打标签
      • 删除镜像
      • 将镜像挂载到主机目录中
      • 从主机目录卸载镜像
      • 将镜像导出为压缩包
      • 从压缩包导入镜像
    • 容器操作
      • 创建容器
      • 列出容器
      • 检查容器的详细配置
      • 删除容器
    • 任务
      • 命名空间
  • 切换容器运行时
    • 维护节点
    • 切换 containerd
    • crictl
    • 安装
    • 用法
      • 获取 Pod 列表
      • 获取镜像列表
      • 获取容器列表
      • 在容器中执行命令
      • 输出容器日志
      • 资源统计
    • CLI 对比
      • 镜像相关
      • 容器相关
      • Pod 相关
    • 日志配置
  • nerdctl
    • 安装
    • 命令
      • Run&Exec
        • nerdctl run
        • nerdctl exec
      • 容器管理
        • nerdctl ps
        • nerdctl inspect
        • nerdctl logs
        • nerdctl stop
        • nerdctl rm
      • 镜像管理
        • nerdctl images
        • nerdctl pull
        • nerdctl push
        • nerdctl tag
        • nerdctl save
        • nerdctl rmi
        • nerdctl load
      • 镜像构建
  • 镜像构建
    • 使用 Docker 做镜像构建服务
        • 使用 DinD 作为 Pod 的 Sidecar
        • 使用 DaemonSet 在每个 containerd 节点上部署 Docker
    • Kaniko
    • Jib
当涉及到容器引擎时,有必要了解下容器运行

容器运行时

在学习 Containerd 以前是必要的 Docker 简单回顾一下发展历史,因为涉及的组件实战有点多,比如 libcontainer、runc、containerd、、OCI 等等。

Docker

从 Docker 1.11 版本开始,Docker 容器运行不是简单的 Docker Daemon 来启动了(C/S架构),而是通过 等待多个组件完成。 Docker Daemon 守护过程模块不断重构,但基本功能和定位变化不大,一直是 ,守护过程负责和 Docker Client 端交互,管理 Docker 镜像和容器。当前架构的组件 containerd 就会负责,并向上为 Docker Daemon 提供 接口。 在这里插入图片描述 当我们想创建一个容器时,现在 Docker Daemon 它不能直接帮助我们创建,而是要求 containerd 来创建一个容器(),containerd 收到请求后,不会直接操作容器,而是创建一个叫做 containerd-shim 让这个过程操作容器,我们指定容器过程需要一个父亲的过程来收集和维护状态 stdin 等 fd 打开和其他工作,如果父亲的过程是 containerd,那如果 containerd 如果挂断,整个宿主机上的所有容器都必须退出并引入 containerd-shim 这个垫片可以避免这个问题。()

然后创建容器需要做一些事情 namespaces 和 cgroups 配置及吊载 root 事实上,文件系统等操作已经有了标准规范,即 ,这个标准实际上是一个文档,主要规定了容器镜像的结构和容器需要接收的操作指令,如 create、start、stop、delete 等待这些命令。,既然是标准,肯定还有其他的。 OCI 实现,比如 Kata、gVisor 这些容器在运行时都是一致的 OCI 标准的。

所以真正启动容器是通过 containerd-shim 去调用 runc 启动容器,runc 启动容器后会直接退出,containerd-shim 它将成为容器过程的父进程, 负责收集容器过程的状态, 上报给 containerd, 并在容器中 pid 为 1 退出后,接管容器中的子后进行清理, 确保没有僵尸过程。

而 Docker 迁移所有容器操作 containerd 中去是因为现在做了 Swarm,想要进军 PaaS 市场,做了这个架构切分,让Docker Daemon 专门去负责上层的封装编排,当然后面的结果我们知道 Swarm 在 Kubernetes 面前惨败,然后Docker 公司就把 containerd 项目捐赠 CNCF 基金会,这也是现在的 Docker 架构。

CRI

我们知道 Kubernetes 提供了一个 CRI 的,那么这个 CRI 到底是什么?这其实是和谐的。 Docker 与发展密切相关。

在 Kubernetes 早期,当时 Docker 太火了,Kubernetes 当然,会先选择支持Docker,并通过硬编码直接调用 Docker API,后面随着 Docker 和 Google当更多的容器运行时,Kubernetes 为支持更精简的容器运行,Google 以红帽为主 CRI 用于将领的标准ubernetes 平台和特定的容器运行时(当然主要是为了干掉 Docker)解耦。

CRI(Container Runtime Interface 容器运行时接口)本质上就是 。不过 Kubernetes 推出 CRI 这套标准的时候还没有现在的统治地位,所以有一些容器运行时可能不会自身就去实现 CRI 接口,于是就有了 shim(垫片), 一个 shim 的职责就是作为适配器将各种容器运行时本身的接口适配到 Kubernetes 的 CRI 接口上,其中 dockershim 就是 Kubernetes 对接 Docker 到 CRI 接口上的一个垫片实现。

Kubelet 通过 ,其中 kubelet 作为客户端,CRI shim(也可能是容器运行时本身)作为服务器。()

CRI 定义的 API 主要包括两个 gRPC 服务,: 1.ImageService 服务主要是拉取镜像、查看和删除镜像等操作 2.RuntimeService 则是用来管理 Pod 和容器的生命周期,以及与容器交互的调用(exec/attach/port-forward)等操作 可以通过 kubelet 中的标志 --container-runtime-endpoint 和 --image-service-endpoint 来配置这两个服务的套接字。

不过这里同样也有一个例外,那就是 Docker,由于 Docker 当时的江湖地位很高,Kubernetes 是(旧版本kubernetes),所以如果你使用的是 Docker 这种容器运行时的话是不需要单独去安装配置适配器()之类的 现在如果我们使用的是 Docker 的话,当我们在 Kubernetes 中创建一个 Pod 的时候,首先就是 kubelet 通过 CRI 接口调用 dockershim,请求创建一个容器,kubelet 可以视作一个简单的 CRI Client, 而 dockershim 就是接收请求的 Server,不过他们都是在 kubelet 内置的。 dockershim 收到请求后, 转化成 Docker Daemon 能识别的请求, 发到 Docker Daemon 上请求创建一个容器,请求到了 Docker Daemon 后续就是 Docker 创建容器的流程了,去调用 containerd,然后创建 containerd-shim 进程,通过该进程去调用 runc 去真正创建容器。

其实我们仔细观察也不难发现使用 Docker 的话其实是调用链比较长的,真正容器相关的操作其实 containerd就完全足够了,Docker 太过于复杂笨重了,当然 Docker 深受欢迎的很大一个原因就是提供了很多对用户操作比较友好的功能,但是对于Kubernetes 来说压根不需要这些功能,因为都是通过接口去操作容器的,所以自然也就可以将容器运行时切换到 containerd 来。

切换到 containerd 可以消除掉中间环节,操作体验也和以前一样,但是由于直接用容器运行时调度容器,所以它们对 Docker 来说是不可见的。 因此,你以前用来检查这些容器的 Docker 工具就不能使用了 你不能再使用 docker ps 或 docker inspect 命令来获取容器信息。由于不能列出容器,因此也不能获取日志、停止容器,甚至不能通过 docker exec 在容器中执行命令。 当然我们仍然可以下载镜像,或者用 docker build 命令构建镜像,但用 Docker 构建、下载的镜像,对于容器运行时和 Kubernetes,均不可见。为了在 Kubernetes 中使用,需要把镜像推送到镜像仓库中去。

从上图可以看出在 中,对 CRI 的适配是通过一个单独的 CRI-Containerd 进程来完成的,这是因为最开始 containerd 还会去适配其他的系统(比如 swarm),所以没有直接实现 CRI,所以这个对接工作就交给 CRI-Containerd 这个 shim 了。

然后到了 containerd 1.1 版本后就去掉了 CRI-Containerd 这个 shim,直接把中,现在这样的调用就更加简洁了。

与此同时 Kubernetes 社区也做了一个专门用于 Kubernetes 的 CRI 运行时 ,直接兼容 CRI 和 OCI 规范。

这个方案和 containerd 的方案显然比默认的 dockershim 简洁很多,不过由于大部分用户都比较习惯使用 Docker,所以大家还是更喜欢使用 dockershim 方案。

但是随着 CRI 方案的发展,以及其他容器运行时对 CRI 的支持越来越完善,Kubernetes 社区在2020年7月份就开始着手移除dockershim 方案了:https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim,现在的移除计划是在1.20 版本中将 kubelet 中内置的 dockershim 代码分离,将内置的 dockershim 标记为维护模式,当然这个时候仍然还可以使用 dockershim,目标是在 1.23/1.24 版本发布没有 dockershim的版本(代码还在,但是要默认支持开箱即用的 docker 需要自己构建 kubelet,会在某个宽限期过后从 kubelet 中删除内置的dockershim 代码)。

那么这是否就意味这 Kubernetes 不再支持 Docker 了呢?当然不是的,这只是,如果我们还想直接使用 Docker 这种容器运行时应该怎么办呢?可以将 dockershim 的功能单独提取出来独立维护一个 cri-dockerd 即可,就类似于 containerd 1.0 版本中提供的 CRI-Containerd,当然还有一种办法就是 Docker 官方社区将 CRI 接口内置到 Dockerd 中去实现。

但是我们也清楚 Dockerd 也是去直接调用的 Containerd,而 containerd 1.1 版本后就内置实现了 CRI,所以 Docker 也没必要再去单独实现 CRI 了,当 Kubernetes 不再内置支持开箱即用的 Docker 的以后,,而且该容器运行时也已经经过了生产环境实践的,接下来我们就来学习下 Containerd 的使用。

Containerd

我们知道很早之前的 Docker Engine 中就有了 containerd,只不过现在是将 containerd 从 Docker Engine 里分离出来,作为一个独立的开源项目,目标是提供一个更加开放、稳定的容器运行基础设施。分离出来的 containerd 将具有更多的功能,涵盖整个容器运行时管理的所有需求,提供更强大的支持。

,它强调简单性、健壮性和可移植性,containerd 可以负责干下面这些事情:

1.管理容器的生命周期(从创建容器到销毁容器) 2.拉取/推送容器镜像 3.存储管理(管理镜像及容器数据的存储) 4.调用 runc 运行容器(与 runc 等容器运行时交互) 5.管理容器网络接口及网络

架构

containerd 可用作 Linux 和 Windows 的守护程序,它管理其主机系统完整的容器生命周期,从镜像传输和存储到容器执行和监测,再到底层存储到网络附件等等。 上图是 containerd 官方提供的架构图,可以看出 ,服务端通过 unix domain socket 暴露低层的 gRPC API 接口出去,客户端通过这些 API 管理节点上的容器,每个 containerd 只负责一台机器,Pull 镜像,对容器的操作(启动、停止等),网络,存储都是由 containerd 完成。具体运行容器由 runc 负责,实际上只要是符合 OCI 规范的容器都可以支持。

为了解耦,containerd 将系统划分成了不同的组件,每个组件都由一个或多个模块协作完成(Core 部分),每一种类型的模块都以插件的形式集成到 Containerd 中,而且插件之间是相互依赖的,例如,上图中的每一个长虚线的方框都表示一种类型的插件,包括 Service Plugin、Metadata Plugin、GC Plugin、Runtime Plugin 等,其中 Service Plugin 又会依赖 Metadata Plugin、GC Plugin 和 Runtime Plugin。每一个小方框都表示一个细分的插件,例如 Metadata Plugin 依赖 Containers Plugin、Content Plugin 等。比如:

Content Plugin: 提供对镜像中可寻址内容的访问,所有不可变的内容都被存储在这里。 Snapshot Plugin: 用来管理容器镜像的文件系统快照,镜像中的每一层都会被解压成文件系统快照,类似于 Docker 中的 graphdriver。 总体来看 containerd 可以分为三个大块:Storage、Metadata 和 Runtime。

安装

我这边采用的是centos8

yum update
yum install -y libeseccomp libseccomp-devel
rpm -qa | grep libeseccomp
注意版本得是2.4以上,有的系统用yum最新也是2.3,你可以考虑用源码安装的方式,centos8可以用2.5
如果版本是2.3,低了,后面使用task会报错,runc会用到libseccomp

比如centos7最新的就是2.3,没辙,你可以考虑源码安装高版本的libseccomp,也可以硬是安装centos8下的2.5版本,不过这样多少有点版本不对应的问题,恐怕有bug,不是个完美的方法(还是建议你升级到centos8或者源码安装):
#卸载原来的
[i4t@web01 ~]# rpm -qa | grep libseccomp
libseccomp-devel-2.3.1-4.el7.x86_64
libseccomp-2.3.1-4.el7.x86_64
[i4t@web01 ~]# rpm -e libseccomp-devel-2.3.1-4.el7.x86_64 --nodeps
[i4t@web01 ~]# rpm -e libseccomp-2.3.1-4.el7.x86_64 --nodeps
#下载高于2.4以上的包
[i4t@web01 ~]# wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
#安装
[i4t@web01 ~]# rpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm 
warning: libseccomp-2.5.1-1.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
Preparing...                          ################################# [100%]
Updating / installing...
   1:libseccomp-2.5.1-1.el8           ################################# [100%]
#查看当前版本
[root@web01 ~]# rpm -qa | grep libseccomp
libseccomp-2.5.1-1.el8.x86_64

完成
[root@www ~]# runc
NAME:
   runc - Open Container Initiative runtime

runc is a command line client for running applications packaged according to
the Open Container Initiative (OCI) format and is a compliant implementation of the
Open Container Initiative specification.

runc integrates well with existing process supervisors to provide a production
container runtime environment for applications. It can be used with your
existing process monitoring tools and the container will be spawned as a
direct child of the process supervisor.

Containers are configured using bundles. A bundle for a container is a directory
that includes a specification file named "config.json" and a root filesystem.
The root filesystem contains the contents of the container.

To start a new instance of a container:

    # runc run [ -b bundle ] <container-id>

Where "<container-id>" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on
your host. Providing the bundle directory using "-b" is optional. The default
value for "bundle" is the current directory.

USAGE:
   runc [global options] command [command options] [arguments...]

VERSION:
   1.0.3
commit: v1.0.3-0-gf46b6ba2
spec: 1.0.2-dev
go: go1.16.14
libseccomp: 2.5.1

COMMANDS:
   checkpoint  checkpoint a running container
   create      create a container
   delete      delete any resources held by the container often used with detached container
   events      display container events such as OOM notifications, cpu, memory, and IO usage statistics
   exec        execute new process inside the container
   init        initialize the namespaces and launch the process (do not call it outside of runc)
   kill        kill sends the specified signal (default: SIGTERM) to the container's init process list lists containers started by runc with the given root pause pause suspends all processes inside the container ps ps displays the processes running inside a container restore restore a container from a previous checkpoint resume resumes all processes that have been previously paused run create and run a container spec create a new specification file start executes the user defined process in a created container state output the state of a container update update container resource constraints help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --debug enable debug output for logging --log value set the log file path where internal debug information is written --log-format value set the format used by logs ('text' (default), or 'json') (default: "text") --root value root directory for storage of container state (this should be located in tmpfs) (default: "/run/runc") --criu value path to the criu binary used for checkpoint and restore (default: "criu") --systemd-cgroup enable systemd cgroup support, expects cgroupsPath to be of form "slice:prefix:name" for e.g. "system.slice:runc:434234" --rootless value ignore cgroup permission errors ('true', 'false', or 'auto') (default: "auto")
   --help, -h          show help
   --version, -v       print the version

由于 containerd 需要调用 ,所以我们也需要先安装 runc,不过 containerd 提供了一个包含相关依赖的压缩包 cri-containerd-cni- V E R S I O N . {VERSION}. VERSION.{OS}-${ARCH}.tar.gz,可以直接使用这个包来进行安装。首先从 release 页面下载对应版本的压缩包,当前为 1.5.10 版本:

wget https://github.com/containerd/containerd/releases/download/v1.5.10/cri-containerd-cni-1.5.10-linux-amd64.tar.gz
# 如果有限制,也可以替换成下面的 URL 加速下载
# wget https://download.fastgit.org/containerd/containerd/releases/download/v1.5.10/cri-containerd-cni-1.5.10-linux-amd64.tar.gz

解压前预览或者拿一个测试目录来解压是一个好习惯

-t:列出压缩包中的文件内容
-f:指定压缩包
这里并不是真正解压
[root@master1 ~]# tar -t -f cri-containerd-cni-1.5.10-linux-amd64.tar.gz
etc/
etc/cni/
etc/cni/net.d/
etc/cni/net.d/10-containerd-net.conflist
etc/systemd/
etc/systemd/system/
etc/systemd/system/containerd.service
etc/crictl.yaml
usr/
usr/local/
usr/local/sbin/
usr/local/sbin/runc
usr/local/bin/
usr/local/bin/containerd-shim-runc-v2
usr/local/bin/containerd-shim
usr/local/bin/containerd-shim-runc-v1
usr/local/bin/containerd
usr/local/bin/containerd-stress
usr/local/bin/critest
usr/local/bin/ctr
usr/local/bin/ctd-decoder
usr/local/bin/crictl
opt/
opt/cni/
opt/cni/bin/
opt/cni/bin/firewall
opt/cni/bin/static
opt/cni/bin/flannel
opt/cni/bin/vrf
opt/cni/bin/host-device
opt/cni/bin/host-local
opt/cni/bin/dhcp
opt/cni/bin/tuning
opt/cni/bin/ptp
opt/cni/bin/sbr
opt/cni/bin/ipvlan
opt/cni/bin/bandwidth
opt/cni/bin/macvlan
opt/cni/bin/bridge
opt/cni/bin/portmap
opt/cni/bin/loopback
opt/cni/bin/vlan
opt/containerd/
opt/containerd/cluster/
opt/containerd/cluster/version
opt/containerd/cluster/gce/
opt/containerd/cluster/gce/configure.sh
opt/containerd/cluster/gce/cni.template
opt/containerd/cluster/gce/env
opt/containerd/cluster/gce/cloud-init/
opt/containerd/cluster/gce/cloud-init/node.yaml
opt/containerd/cluster/gce/cloud-init/master.yaml

直接将压缩包解压到系统的各个目录中(直接到根目录中):

-C:改变解压的目标目录
[root@master1 ~]# tar -C / -xf cri-containerd-cni-1.5.10-linux-amd64.tar.gz

当然要记得将 /usr/local/bin 和 /usr/local/sbin 追加到 ~/.bashrc 文件的 PATH 环境变量中(或者/etc/profile):

export PATH=$PATH:/usr/local/bin:/usr/local/sbin

然后执行下面的命令使其立即生效:

[root@master1 ~]# source ~/.bashrc

containerd 的默认配置文件为 /etc/containerd/config.toml,我们可以通过如下所示的命令生成一个默认的配置:

[root@master1 ~]# mkdir -p /etc/containerd
[root@master1 ~]# containerd config default > /etc/containerd/config.toml

由于上面我们下载的 containerd 压缩包中包含一个 etc/systemd/system/containerd.service 的文件,这样我们就可以通过 systemd 来配置 containerd 作为运行了,内容如下所示:

➜  ~ cat /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd

Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target

这里有两个重要的参数:

: (授权,代表)这个选项允许 containerd 以及运行时自己管理自己创建容器的 cgroups。如果不设置这个选项,systemd 就会将进程移到自己的 cgroups 中,从而导致 containerd 无法正确获取容器的资源使用情况。 : 这个选项用来处理 containerd 进程被杀死的方式。默认情况下,systemd 会在进程的 cgroup 中查找并杀死 containerd 的所有子进程。KillMode 字段可以设置的值如下。 1.control-group(默认值):当前控制组里面的所有子进程,都会被杀掉 2.process:只杀主进程 3.mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号 4.none:没有进程会被杀掉,只是执行服务的 stop 命令

现在我们就可以启动 containerd 了,直接执行下面的命令即可:

[root@master1 ~]# systemctl enable containerd --now
Created symlink from /etc/systemd/system/multi-user.target.wants/containerd.service to /etc/systemd/system/containerd.service.

启动完成后就可以使用 containerd 的本地 CLI 工具 ctr 了,比如查看版本:

[root@master1 ~]# ctr version
Client:
  Version:  v1.5.10
  Revision: 2a1d4dbdb2a1030dc5b01e96fb110a9d9f150ecc
  Go version: go1.16.14

Server:
  Version:  v1.5.10
  Revision: 2a1d4dbdb2a1030dc5b01e96fb110a9d9f150ecc
  UUID: f5ec6760-fdf4-4ab4-b85a-50ad011693c9

配置

查看下上面默认生成的配置文件 /etc/containerd/config.toml:

disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
version = 2

[cgroup]
  path = ""

[debug]
  address = ""
  format = ""
  gid = 0
  level = ""
  uid = 0

[grpc]
  address = "/run/containerd/containerd.sock"
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216
  tcp_address = ""
  tcp_tls_cert = ""
  tcp_tls_key = ""
  uid = 0

[metrics]
  address = ""
  grpc_histogram = false

[plugins]

  [plugins."io.containerd.gc.v1.scheduler"]
    deletion_threshold = 0
    mutation_threshold = 100
    pause_threshold = 0.02
    schedule_delay = "0s"
    startup_delay = "100ms"

  [plugins."io.containerd.grpc.v1.cri"]
    disable_apparmor = false
    disable_cgroup = false
    disable_hugetlb_controller = true
    disable_proc_mount = false
    disable_tcp_service = true
    enable_selinux = false
    enable_tls_streaming = false
    ignore_image_defined_volumes = false
    max_concurrent_downloads = 3
    max_container_log_line_size = 16384
    netns_mounts_under_state_dir = false
    restrict_oom_score_adj = false
    sandbox_image = "k8s.gcr.io/pause:3.5"
    selinux_category_range = 1024
    stats_collect_period = 10
    stream_idle_timeout = "4h0m0s"
    stream_server_address = "127.0.0.1"
    stream_server_port = "0"
    systemd_cgroup = false
    tolerate_missing_hugetlb_controller = true
    unset_seccomp_profile = ""

    [plugins."io.containerd.grpc.v1.cri".cni]
      bin_dir = "/opt/cni/bin"
      conf_dir = "/etc/cni/net.d"
      conf_template = ""
      max_conf_num = 1

    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "runc"
      disable_snapshot_annotations = true
      discard_unpacked_layers = false
      no_pivot = false
      snapshotter = "overlayfs"

      [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
        base_runtime_spec = ""
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        runtime_engine = ""
        runtime_root = ""
        runtime_type = ""

        [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]

      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]

        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          base_runtime_spec = ""
          container_annotations = []
          pod_annotations = []
          privileged_without_host_devices = false
          runtime_engine = ""
          runtime_root = ""
          runtime_type = "io.containerd.runc.v2"

          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            BinaryName = ""
            CriuImagePath = ""
            CriuPath = ""
            CriuWorkPath = ""
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = ""
            ShimCgroup = ""
            SystemdCgroup = false

      [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
        base_runtime_spec = ""
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        runtime_engine = ""
        runtime_root = ""
        runtime_type = ""

        [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]

    [plugins."io.containerd.grpc.v1.cri".image_decryption]
      key_model = "node"

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = ""

      [plugins."io.containerd.grpc.v1.cri".registry.auths]

      [plugins."io.containerd.grpc.v1.cri".registry.configs]

      [plugins."io.containerd.grpc.v1.cri".registry.headers]

      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]

    [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
      tls_cert_file = ""
      tls_key_file = ""

  [plugins."io.containerd.internal.v1.opt"]
    path = "/opt/containerd"

  [plugins."io.containerd.internal.v1.restart"]
    interval = "10s"

  [plugins."io.containerd.metadata.v1.bolt"]
    content_sharing_policy = "shared"

  [plugins."io.containerd.monitor.v1.cgroups"]
    no_prometheus = false

  [plugins."io.containerd.runtime.v1.linux"]
    no_shim = false
    runtime = "runc"
    runtime_root = ""
    shim = "containerd-shim"
    shim_debug = false

  [plugins."io.containerd.runtime.v2.task"]
    platforms = ["linux/amd64"]

  [plugins."io.containerd.service.v1.diff-service"]
    default = ["walking"]

  [plugins."io.containerd.snapshotter.v1.aufs"]
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.btrfs"]
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.devmapper"]
    async_remove = false
    base_image_size = ""
    pool_name = ""
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.native"]
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.overlayfs"]
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.zfs"]
    root_path = ""

[proxy_plugins]

[stream_processors]

  [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
    accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
    args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
    env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
    path = "ctd-decoder"
    returns = "application/vnd.oci.image.layer.v1.tar"

  [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
    accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
    args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
    env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
    path = "ctd-decoder"
    returns = "application/vnd.oci.image.layer.v1.tar+gzip"

[timeouts]
  "io.containerd.timeout.shim.cleanup" = "5s"
  "io.containerd.timeout.shim.load" = "5s"
  "io.containerd.timeout.shim.shutdown" = "3s"
  "io.containerd.timeout.task.state" = "2s"

[ttrpc]
  address = ""
  gid = 0
  uid = 0

这个配置文件比较复杂,我们可以将重点放在其中的 plugins 配置上面,仔细观察我们可以发现每一个顶级配置块的命名都是 plugins.“io.containerd.xxx.vx.xxx” 这种形式,,其中 io.containerd.xxx.vx 表示插件的,vx 后面的 xxx 表示插件的 ,我们可以通过 ctr 查看插件列表:

[root@master1 ~]# ctr plugin ls
TYPE                            ID                       PLATFORMS      STATUS
io.containerd.content.v1        content                  -              ok
io.containerd.snapshotter.v1    aufs                     linux/amd64    skip
io.containerd.snapshotter.v1    btrfs                    linux/amd64    skip
io.containerd.snapshotter.v1    devmapper                linux/amd64    error
io.containerd.snapshotter.v1    native                   linux/amd64    ok
io.containerd.snapshotter.v1    overlayfs                linux/amd64    ok
io.containerd.snapshotter.v1    zfs                      linux/amd64    skip
io.containerd.metadata.v1       bolt                     -              ok
io.containerd.differ.v1         walking                  linux/amd64    ok
io.containerd.gc.v1             scheduler                -              ok
io.containerd.service.v1        introspection-service    -              ok
io.containerd.service.v1        containers-service       -              ok
io.containerd.service.v1        content-service          -              ok
io.containerd.service.v1        diff-service             -              ok
io.containerd.service.v1        images-service           -              ok
io.containerd.service.v1        leases-service           -              ok
io.containerd.service.v1        namespaces-service       -              ok
io.containerd.service.v1        snapshots-service        -              ok
io.containerd.runtime.v1        linux                    linux/amd64    ok
io.containerd.runtime.v2        task                     linux/amd64    ok
io.containerd.monitor.v1        cgroups                  linux/amd64    ok
io.containerd.service.v1        tasks-service            -              ok
io.containerd.internal.v1       restart                  -              ok
io.containerd.grpc.v1           containers               -              ok
io.containerd.grpc.v1           content                  -              ok
io.containerd.grpc.v1           diff                     -              ok
io.containerd.grpc.v1           events                   -              ok
io.containerd.grpc.v1           healthcheck              -              ok
io.containerd.grpc.v1           images                   -              ok
io.containerd.grpc.v1           leases                   -              ok
io.containerd.grpc.v1           namespaces               -              ok
io.containerd.internal.v1       opt                      -              ok
io.containerd.grpc.v1           snapshots                -              ok
io.containerd.grpc.v1           tasks                    -              ok
io.containerd.grpc.v1           version                  -              ok
io.containerd.grpc.v1           cri                      linux/amd64    ok

,比如 cri 插件下面就分为 containerd、cni 和 registry 的配置,而 containerd 下面又可以配置各种 runtime,还可以配置默认的 runtime。比如现在我们要为镜像配置一个加速器,那么就需要在 cri 配置块下面的 registry 配置块下面进行配置 registry.mirrors:

[plugins."io.containerd.grpc.v1.cri".registry]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
      endpoint = ["https://xxxxxxxxxx.mirror.aliyuncs.com"]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
      endpoint = ["https://registry.aliyuncs.com/k8sxio"]

registry.mirrors.“xxx”: 表示需要配置 mirror 的镜像仓库,例如 registry.mirrors.“docker.io” 表示配置 docker.io 的 mirror。 endpoint: 表示提供 mirror 的镜像加速服务,比如我们可以注册一个阿里云的镜像服务来作为 docker.io 的 mirror。

systemctl restart containerd

另外在默认配置中还有两个关于存储的配置路径:

root = "/var/lib/containerd"
state = "/run/containerd"

其中 root 是用来(比如docker的/var/lib/docker,不过这些存放数据的目录,建议那一块大的裸盘或者分区的目录来做,,或者使用ceph等存储集群来做存储,毕竟容器很容易产生大量数据,同一塞满这个/var/lib/containerd的目录所对应的文件系统甚至导致系统宕机),包括 Snapshots, Content, Metadata 以及各种插件的数据,每一个插件都有自己单独的目录,

而另外的 state 是用来保存运行时的的,包括 sockets、pid、挂载点、运行时状态以及不需要持久化的插件数据。

使用(contianerd的CLI:ctr)

我们知道 Docker CLI 工具提供了需要增强用户体验的功能,containerd 同样也提供一个对应的 CLI 工具:ctr,不过 ctr 的功能没有 docker 完善,但是关于镜像和容器的基本功能都是有的。接下来我们就先简单介绍下 ctr 的使用。

直接输入 ctr 命令即可获得所有相关的操作命令使用方式:

[root@master1 ~]# ctr
NAME:
   ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/

containerd CLI


USAGE:
   ctr [global options] command [command options] [arguments...]

VERSION:
   v1.5.10

DESCRIPTION:

ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.

COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
  

标签: 110a手摇带式电容截断机

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台