containerd的那些事

网友投稿 524 2022-09-09

containerd的那些事

从k8s v1.24.0默认就不使用docker开始的言论开始,我才关注containerd,但是我也一直未去深入研究,直到k8s v1.24.0发布了。

我们知道kubernetes最小单元是pod,pod里面跑的是容器,那么就需要容器运行时,kubernetes里面有个CRI的概念。只要遵循OCI的容器运行时,可以对接CRI,kubernetes就可以通过kubelet来使用这些来创建pod的容器

至于kubernetes默认使用containerd,而放弃docker的这里面的道道这里就不说了,可以搜一搜,都是江湖事。

containerd安装

首先先来说下如何安装containerd来运行我们的容器。

二进制包安装:containerd的github中提供了3个版本,

​​plugin

cri-container-cni包含runc,包含cni。需要解压到根目录下

​​plugin不是。

Q:所以如上如何选择安装的版本呢

这里说下我使用cintainerd的场景是代替docker作为k8s的cri的runtime。

所以不需要安装cni plugin这个,部署网络组件的时候会生成。所以不需要cri-container-cni这个版本的二进制包。

至于cri-container版本虽然包含了runc,包含了crictl但是它的目录需要直接解压到根目录,对于我来说不方便使用stow来管理。

所以我选择安装containerd版本,然后去安装runc

cni plugin

如果你要单机部署containerd运行容器,那么必然要选择安装cni plugin,给容器提供网络支持。

有以下个途径可以生成cni plugin.

/opt/cni/bin

1、自己从​​plugin,最新版本是v1.1.1

2、包管理安装kubelet自动依赖安装kubernetes-cni,kubelet v1.24.2对应kubernetes cni的版本是v0.8.7

如果先手动安装cni plugin,然后安装kubelet会覆盖/opt/cni/bin下的文件。

3、kubernetes集群部署calico网络组件的时候,会使用/opt/cni/bin,会覆盖bandwith等,单不包含bridge等

4、cri-containerd-cni中也会包含。cni plugin.

此处,nerdctl 版本是0.21.0

​​run的时候需要用bridge 驱动, ctr run的时候默认没有用到,calico网络组件也没有用到bridge。只有bandwith,portmap等,

shim

如上图,我们可以看到nerdctl-full的包里,只有containerd-shim-runc-v2

而containerd的包里有3个。

shim是什么,这么多个版本的区别是什么,之前看过一个文档,

​​Container Initiative)是一个项目的称呼,定义了2个规范,

runtime spec:定义了容器的生命周期管理

image spec:定义了镜像的生命周期管理,

runc(run container)是一个基于OCI标准实现的一个轻量级容器运行工具,用来创建和运行容器。而Containerd是用来维持通过runc创建的容器的运行状态。即runc用来创建和运行容器,containerd作为常驻进程用来管理容器。

runc包含libcontainer,包括对namespace和cgroup的调用操作。

runc本来是docker的,docker捐赠给了OCI,现在是在OCI下。

​​是 CRI 兼容的容器运行时命令行接口,可以使用它来检查和调试 k8s 节点上的容器运行时和应用程序。主要是用于kubernetes,​​默认操作的命名空间是k8s.io​​,而且看到的对象是pod。

如果是k8s环境的话,可以参考下方链接,在每个节点部署containerd的时候也部署下crictl工具。

​​kubernetes-sigs/cri-tools: CLI and validation tools for Kubelet Container Runtime Interface (CRI) . (github.com)​​

遇到的问题:

因为没有这个文件,导致crictl无法正常使用,如下图。

[root@master2 ~]# cat /etc/crictl.yaml runtime-endpoint: unix:///run/containerd/containerd.sockimage-endpoint: unix:///run/containerd/containerd.socktimeout: 2debug: falsepull-image-on-create: false

以上2个工具这里不做讨论,网上一堆,这里主要说下nerdctl

nerdctl

对于单机节点来说,我选择使用nerdctl,个人使用起来和docker类似,基本没学习成本,把docker换成nerdctl即可。对于普通用户来说,这个是比较友好的工具。但是对于api那些来说,可以选择其他。

​​配置

上面说了containerd的安装,下面我们来说下containerd的配置。有人一看containerd的配置文件都头大,说很复杂,其实你了解了contianerd的逻辑后,就会发现不复杂。

​​configuration还有Plugin configuration

主要是Plugin configuration的配置

​​下,有许多的组件,我们看到plugins后面引号内的内容,就是命令“ctr plugin ls”展示中的的type+id组合。

而我们常用的如上,主要是“io.containerd.grpc.v1.cri”下的内容,有registry,containerd(runtimes(等)),cni。

引号后,每间隔一个部分,就是一个缩进块。

如上可以看到type中的,格式是

io.containerd(固定)+<模块>+<模块的版本>

id的格式是,各个模块下各个组件的名称。

配置文件中,通过disabled_plugins和required_plugins来控制不启用的插件和必须的插件

镜像仓库配置

​​Containerd 配置镜像仓库的 ​​mirror​​。Containerd 的镜像仓库 mirror 与 Docker 相比有两个区别:

Containerd 只支持通过​​CRI​​​ 拉取镜像的 mirror,也就是说,只有通过​​crictl​​​,nerdctl 或者 Kubernetes 调用时 mirror 才会生效,ctr拉取要生效的话需要指定--hosts-dir

这里我们可以通过nerdctl debug pull 来观察

​​Docker​​​ 只支持为​​Docker Hub​​​ 配置 mirror,而​​Containerd​​ 支持为任意镜像仓库配置 mirror。

registry.aliyun.com/google_containers虽然有k8s.gcr.io的镜像,但不是加速站点。

就是配置[plugins."io.containerd.grpc.v1.cri".registry]下的内容

​​old CRI config pattern for specifying registry.mirrors and registry.configs has been DEPRECATED.

所以网上很多之前的registry下的mirrors和configs都是无效的了,配置后启动containerd会有如下提示

leve​l=warning msg="failed to load plugin io.containerd.grpc.v1.cri" error="invalid plugin config: ​​mirrors​​ cannot be set when ​​config_path​​ is provided"

以下所有操作都是containerd 1.6.x版本做的操作。

1、指定配置文件目录

[plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d/"

2、根据镜像仓库创建文件

cd /etc/containerd/certs.d/

翻译成人话就是,你pull的时候镜像名字前面是啥,这里就配啥,当然默认的都是从docker hub上去拉取,默认镜像名前不加的话会给你加上docker.io/library,这里的docker.io就是[registry_host_name|IP address][:port],/library就是/org_path部分。

3、配置加速

mkdir -p /etc/containerd/certs.d/docker.iocat >/etc/containerd/certs.d/docker.io/hosts.toml <

注意的是:

如果hosts.toml文件中的capabilities中不加resolve的话,无法加速镜像配置无需重启服务,即可生效。要配保底的加速站点,否则可能会导致下载失败

出现的问题:

无法加速k8s.gcr.io

可以看到我上面配置了k8s.gcr.io,但是registry.aliyuncs.com/google_containers 这个镜像仓库站点不是k8s.gcr.io的镜像,只是有k8s.gcr.io的镜像,这就是为什么k8s.gcr.io有些镜像在registry.aliyuncs.com/google_containers没有的原因。

结论:​

registry.aliyuncs.com/google_containers下有部分k8s.gcr.io下的镜像,但是不是镜像站点,所有不能配置加速器。

hub.docker.com中的镜像无法下载

如上图所示,nerdctl -n k8s.io  pull calico/pod2daemon-flexvol可以下载下来,默认下载的tag是latest,但是当至指定tag是v3.22.2下载不下来。

结论:

当配置了加速的时候,对应的server需要配置个保底的镜像站点,这里docker.io需要配置registry-1.docker.io个才行,否则国内站点里没有的话,nerdctl不像docker 那样,会自己去找docker.io的镜像站点去找。

4、测试

nerdctl --debug pull busybox

ctr --debug  image pull --hosts-dir "/etc/containerd/certs.d" docker.io/library/busybox:latest

注意的是:

ctr image pull的时候需要注意镜像名称需要完整,否则无法拉取,格式如下:[registry_host_name|IP address][:port][/org_path][:tag]以下是各种格式不对导致的报错提示信息。

1.6.x版本做的操作。

1、在配置的 config_path = "/etc/containerd/certs.d/"目录下创建私有镜像仓库目录

假设我们配置harbor的镜像仓库域名是 harbor.registry

mkdir harbor.registry

2、然后配置hosts.toml

我们以harbor搭建的私有仓库为例

[host." capabilities = ["pull", "resolve", "push"] ca = "registry.cert"

如果对客户端需要证书验证,那么这里可以再ca后添加client。

3、把证书放在/etc/containerd/certs.d/harbor.registry下。

4、测试(待补充)

nerdctl --debug pull harbor.registry/xxxx

crictl

ctr 就是用--skip-verfy跳过验证,或者--tlscacert --tlscert --tlskey来指定服务器ca证书或者client证书。

登录镜像仓库

如下图可以看出来,registry的configs的auth对于cri 有效。但是对于ctr和nerdctl都不生效。

注意的是:

当我们kubernetes使用containerd时候,containerd的cri plugin可以接受 kubernete配置的image pull secrets的信息,去登录对应镜像仓库。这样就不用每个节点都配置registry.configs.xxx.auth了。如果没有配置imagepullsecrets,当pod调度到某个节点上,可以用containerd配置的registry.configs.xxx.auth信息去登录对应的镜像仓库,如果存在的话。

ctr如何登陆呢,

ctr image pull --user

通过--user来配置用户名和密码登录

nerdctl

nerdctl就和docker很类似了,nerdctl login,会生成~/.docker/config.json

小结

以上对于crictl可以使用的方法,对于k8s来使用containerd的话也没用问题,kubelet用的就是cri的方法来调用containerd的。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:#云原生征文#自建高可用k8s集群前置概念与操作
下一篇:休克文案:520文案来了!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~