侧边栏壁纸
博主头像
lance

不为失败找借口,只为成功找方法。

  • 累计撰写 28 篇文章
  • 累计创建 0 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

上手Containerd.md

lance
2025-05-11 / 0 评论 / 0 点赞 / 45 阅读 / 3,801 字
温馨提示:
本文最后更新于 2025-05-11,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Containerd上手

一、容器发展史

1.1初始阶段
1.2发展阶段
1.3CRI的诞生
1.4弃用阶段
1.5CRI-O

二、Contained

2.1安装
2.2镜像管理
2.3容器管理
2.4私有镜像
2.5Nerdctl

一、容器发展史

在2020 年底,Kubernetes 宣布不再推荐使⽤ Docker 作为容器运⾏时,并在后续的版本中停⽌⽀持 Docker。这个决定肯定会对原有的 Kubernetes ⽤户产⽣⼀定的影响,同时也引发了⼀系列问题:

如果不使用Docker,使用什么替代品?Kubernetes为什么要停止支持Docker?

为了回答这些问题,我们需要简要回顾一下容器发展史。

1.1初始阶段

Docker的发展经历了一系列的变革,Docker最初使用的架构是Container+libContainer:在这个阶段,Docker主要分为两个部分:Docker Daemon(守护进程)和Docker Client(客户端)。

*Docker Daemon 负责处理 Docker Client 发送的请求,并对请求进⾏相应的操作(如:镜像、容器的管理)

*在管理 Linux 容器时,Docker Daemon 依赖 libContainer 这个库来完成底层的容器操作

libContainer提供了一系列接口和功能,用于创建、启动、停止和销毁容器,以及配置容器的资源限制、网络、存储等。通过libContainer,Docker Daemon可以实现对容器的完整管理。
pEOvTE9.png
Docker 为了推动容器技术的标准化和通用性,将libContainer赠送给了Open Container lnitiative(OCI)并将其重命名为runc。OCI是一个专门制定容器技术标准的组织,目的是让容器技术变得更加开放、透明和互相兼容。

*镜像标准:定义了容器镜像的结构和内容,保活镜像文件的组织方式、文件和目录类型等。以及如何创建符合标准的镜像文件。

*运行时标准:规定了如何从运行时文件系统启动容器程序,包括容器接受的指令类型、指令行为、生命周期管理,以及如何配置名称空间、Cgroup和文件系统挂载等

runc是一个独立的可执行的程序,根据OCI标准启动和管理容器进程。这样一来,Docker容器运行时的核心组件(即容器的创建和管理)不再紧密依赖于Docker守护进程。意味着Docker容器运行时的核心组件(runc)和Docker守护进程之间的关联变得更加松散。Docker守护进程可以直接调用runc来管理容器,而不再需要依赖于内部的libContainer库。这使得其他容器运行时(如containerd或CRI-O)也可以采用相同的OCI标准,实现与Docker更好的兼容性。

1.2发展阶段

从Docker1.11版本开始,Docker容器的运行和管理不再仅依赖于Docker Daemon。他通过整合Contained、runc和container-shim等组件共同完成。Docker Daemon 仍然负责与Docker Client交互,以及管理Docker镜像。而将容器的底层运行时操作交给了containerd和runc。容器的的生命周期变得更加模块化,Docker Daemon 和Containerd通过gRPC接口进行通信。Containerd进一步调用runc来实际启动和管理容器进程。为了解决容器进程和runc之间的依赖,Docker引入了container-shim。container-shim是一个轻量级的进程,用于在容器和runc之间进行通信,使容器在runc推出后能够继续运行。

pE4halj.png

当我们要创建一个容器的时候,现在Docker Daemon并不能直接帮我们创建了

*Docker Daemon 请求containerd进行容器的创建

*containerd不直接创建容器,因为containerd如果故障,所有容器都会故障,因此引用了containerd-shim,来进行容器的创建

*containerd-shim调用runc(符合OCI标准)来创建容器

*run创建容器后推出,containerd-shim成为容器进程的父进程,负责状态收集和清理工作

*通过引入containerd和containerd-shim,Docker 架构变得更加模块化,各个组件之间的职责分工更加明确,从而有助于提高整体的稳定性和可维护性。

为了提高稳定性引入containerd-shim,containerd-shim也会出现故障有什么本质区别呢?

一、故障影响范围不同

1.如果containerd直接创建容器且出现故障,由于它是中心的容器运行时管理组件,负责与Kubernetes等容器编排系统交互以及管理众多容器的生命周期,其故障很可能会导致所有容器的管理出现问题,因为它是而哦容器管理的核心枢纽。

2.而当containerd-shim出现故障时,通常只会影响它所管理的单个容器实例或一小部分容器。containerd-shim是为每个容器或一组容器创建独立的进程,即使一个shim进程出现故障,其他容器的shim进行仍然可以正常运行,从而降低了故障的影响范围。

二、恢复机制不同

1.如果containerd出现故障,恢复过程可能比较复杂,需要从新启动整个容器运行时管理系统,这可能会导致所有容器的状态丢失或需要较长时间的恢复过程。

2.对于containerd-shim的故障,通常可以更快速地进行恢复。由于shim是轻量级的进程,并且可以独力地进行监控和恢复。例如,通过重新启动故障的shim进程来恢复受影响的容器,而不会影响其他正常运行的容器。

综上所述,引入containerd-shim虽然不能完全消除容器故障的风险,但可以在一定程度上降低故障的影响范围,并提供更灵活的恢复机制。

1.3CRI的诞生

在容器技术飞速发展的背景下,Docker将重心转向到了编排工具的开发上,进而将containerd捐赠给CNCF。这一举措即推动了容器技术的发展,还吸引了更多社区成员的参与,使得Docker能够集中精力开发Swarm等工具。此举还能降低Docker面临的市场竞争风险。然而,在Kubernetes编排工具诞生之后,他为了保持中立性,同时支持多种容器运行时与Kubernetes对接,以避免对特定技术的依赖和Docker公司一家独大的局面,因此Kubernetes在1.5版本引入了CRI。由Google和红帽共同推动CRI标准的产生。

CRI(Container Runtime Interface,容器运行时接口)是Kubernetes设计的一组接口,用于与容器运行时互动。简单来说,只要容器运行时实现了CRI接口,就可以与Kubernetes平台集成。然而,并非所有的容器运行时都会直接实现CRI接口,因此出现了“shim(垫片)”这个概念。shim的作用类似与适配器(USB转Type-c),将各种不同的容器运行时的接口适配到Kubernetes的CRI接口上。如,dockershim就是Kubernetes为了将Docker接口适配到CRI接口上,而设计的一种实现。

当然,由于Docker在容器领域的地位举足轻重,Kubernetes便直接将dockershim嵌入到kubelet中。因此,对于使用Docker容器运行的用户而言,无需额外安装配置适配器,如下图所示。

pE4hYtS.png

当时,由于Docker在容器领域的地位举足轻重,Kubernetes便将dockershim嵌入到kubelet中。因此,对于使用Docker容器运行时的用户而言,无需额外安装配置适配器,如下图所示。

pE4hd6s.png

1.4弃用阶段

实际上,在使用Kubernetes与Docker结合的情况下,整个调用链相当长。然而,对于真正的容器相关操作,Containerd已经完全足够。尽管Docker的调用链很长,但这并不影响其受欢迎程度。但对于Kubernetes来说,这些功能并不重要,因为它不仅通过接口操作容器。所以Kubernetes可以自然地将容器运行时切换到Containerd。

其次为了支持Docker,Kubernetes开发了一个名为dockershim的垫片。随着时间的推移,Kubernetes受众不断扩大,同时Containerd也成功从CNCF毕业,其健壮性得到了显著提升。在这种去情况下,Kubernetes终于可以考虑摒弃dockershim垫片。因为在维护dockershim时,Kubernetes遇到了许多问题。首先Kubernetes需要处理很多与其核心功能无关的内容。此外,随着Docker版本的升级,dockershim不得不进行相应的适配,并经行兼容性测试,这为维护工作带来了额外的复杂性。

pE4hUpQ.png

containerd1.0版本开始,通过一个独立的CRI-Containerd进程来适配CRI,原因时containerd最初也需要适配其它系统(swarm),因此没有直接实现CRI,这个对接工作由CRI-Containerd shim完成。随后,在containerd1.1版本中,移除了CRI-Containerd shim,并将适配逻辑以插件形式集中到containerd主进程中。如今,调用过程变得更加简洁。

pE4htfg.png

1.5CRI-O

Kubernetes社区也开发了一个专门用于Kubernetes的CRI,名为CRI-O,CRI-O直接兼容CRI和OCI规范,为Kubernetes提供了更加高效的容器运行时支持。https://cri-o.io/

pE4hwXn.png

二、Containerd

2.1安装

1.安装libseccomp依赖,但默认的libeccomp版本为2.3版本无法版本containerd1.6版本,需要安装2.4版本以上;(如果是RockyLinux9.3不需要更新,rmp -qa|grep libseccomp=libseccomp-2.5.2-2.el9.x86_64)

# wget https://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Pakages?libseccomp-2.5.1-1.e18.x86_64.rmp

#rmp -ich libseccopm-2.5.1-1.el8.x86_64.rmp --force

2.下载containerd1.6,而后解压

#wget http://file.oldxu.net/cri-containerd-1.6.18-linux-amd64.tar.gz

#tar tf cri-containerd-1.6.18-linux-amd64.tar.gz

#tar xf cri-containerd-1.6.18-linux-amd64.tar.gz -C /

3.创建Containerd配置

#mkdir -p /etc/containerd

#containerd config default >  /etc/containerd/config.toml

4.运行containerd

#systemctl start containerd

#systemctl status containerd

5.检查

#ctr version

Client:

   Version:v1.6.18

   Revision:2456e983eb9e37e47538f59ea18f2043c9a73640

   Go version :go1.19.6

Server :

   Version :1.6.21

   Revison:3dce8eb055cbb6872793272b4f20ed16117344f8

   UUID: b4734440-e529-4598-a06f-2615ad6d96c3

[root@docker-node ~]# runc --version

runc version 1.1.4

commit:v1.1.4-0-g5fd4c4d1

spec:1.0.2-dev

go: go1.19.6

libseccomp: 2.5.1
2.2镜像管理

1.拉取镜像

#语法:ctr images pull <image_name>

#实例:ctr images pull docker.io/library/alpine:Latest

2.查看镜像

[root@name ~]# ctr images list -q

docker.io/library/alpine:lastest

3.删除镜像

#语法 ctr images remove <image_name>

#示例 ctr images remove docker.io/librery/alpine:Latest
  1. 由于containerd和docker存储数据目录不一致,因此互相之间的镜像无法查看,那么docker构建的镜像如何提供给containerd
   #1、dockerfile构建镜像

   #2、docker push推送私有仓库

   #3、containerd通过私有仓库获取镜像即可

   #4、如果私有仓库存在用户密码认证 ctr images pull  --user admin:Harbor12345 harbor.oldxu.net/nginx:1.20
2.3容器管理

1、启动容器

#语法:ctr containers run <image_name> <container_name>

示例:

[root@name ~]# ctr run -d docker.io/library/alpine:Latest mytest1 /bin/sh # 后台运行

[root@name ~]# ctr run -t docker.io/library/alpine:Latest mytest2 /bin/sh3 #前台运行

2、进入容器(-exec-id 可以指定字符串)

[root@name ~]# ctr task exec -t --exec-id sh mytest2 /bin/sh 

3.查看容器

[root@name ~]# ctr c list 

​    CONTAINER IMAGE RUNTIME

​    mytest docker.io/library/alpine:latest io.containerd.runc.v2

​    mytest2 docker .io/library/alpine:latest io.containerd.runc .v2

​    mytest3 docker .io/library/alpine:latest io.containerd.runc.v2

[root@name ~]# ctr task list

​    TASK PID STATUS 

  mytest2 20153 RUNNING

  mytest3 20268 RUNNING
  1. 删除容器
   #语法: ctr  containers delete  <container_name>

   #示范: ctr containers delete mytest2
2.4私有镜像

默认ctr拉取公开镜像无需输入用户名和密码,但是私有仓库镜像则无法正常获取

1、方式一,需要使用–user 指定明确指定用户名和密码

[root@name ~]# ctr images pull --user admin:Harbor12345 harbor.oldxu.net/infra.nginx:1.20

[root@name ~]# ctr images list -q

​    docker.io/library/alpine:latest

​    docker.io/library/nginx:1.18
​    harbor.oldxu.net/infra/nginx:1.20

2、方式二,通过crictl下载镜像,在配置文件中定义对应的私有仓库信息,以及用户名和密码

#vim /etc/containerd/config.toml

[plugins]

...

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

...

#私有镜像仓库认证信息

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

#4、如果https不受信任,可以通过以下参数跳过

[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.oldxu.net".tls]

insecure_skip_verify = true

#3、私有仓库认证的用户名及密码

[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.oldxu.net".auth]

username = "admin"

password = "Harbor12345"

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



#定制镜像仓库

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

#1、镜像加速

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

endpoint = ["https://q2gr04ke.mirror.aliyuncs.com","https://docker.mirrors.ustc.edu.cn]

#2、私有仓库(需要继续添加私有仓库的用户名和密码,否则通过crictl无法正常拉取镜像)

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

endpoint = ["https://habor.oldxu,net"]


2.5Neerdctl

containerd使用ctr管理containerd镜像容器,但是大家已经习惯了使用docker,ctr使用起来还是不太顺手,为了能够让大家更好的转到containerd上面来,社区提供了一个新的命令行工具:nerdctl。nerdctl是一个与docker cli风格兼容的containerd客户端工具,而且直接兼容docker compose 的语法的,这就大大提高了直接将containerd作为本地开发、测试或者单机容器部署使用的效率。

1、下载安装nerdctl

[rootname ~]# wget https://github.com/containerd/nerdctl/releases/download/v1.4.0/nerdctl-full-1.4.0-linux-amd64.tar.gz

[rootname ~]# tar xf nerdctl-full-1.4.0-linux.amd64.tar.gz

[rootname ~]#cp bin/nerdctl bin/buildctl bin/buildkitd /usr/local/bin/

#添加命令补全

echo 'source<(nerdctl completion bash)' >> /etc/profile

source /etc/profile

2.测试nerdctl命令

#nerdctl pull nginx:1.18

#nerdctl images 

​    REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZ
​    E BLOB SIZE
​    nginx 1.18 e90ac5331fe0 37 seconds ago linux/amd64 139.
​    4 MiB 51.1 MiB
0

评论区