文章目录

  • 前言
  • 一、准备一套使用Docker引擎的kubernetes集群
  • 二、配置先决条件
    • 1.启用Containerd依赖的overlay、br_netfilter内核模块
    • 2.设置必要的sysctl参数,这些参数在重新启动后仍然存在
  • 三、安装Containerd
  • 四、修改Containerd配置文件
  • 五、配置Kubelet使用Containerd
  • 六、使用Containerd管理容器
    • crictl查看本地镜像
    • crictl查看本地容器
    • crictl进入容器
    • crictl查看pod
  • crictl常用命令
  • 七、切换回Docker容器引擎
  • 总结

前言

 在未来的kubernetes版本会计划彻底放弃Docker支持,会弃用kubelet中的docker-shim组件;也就是k8s不能默认直接使用docker引擎了,所以在以后可能containerd可能会成为主流,很多大企业现在都已经换成containerd了,包括我之前在阿里云上创建ACK的时候,会出现让选择容器运行时的一个选项,上面就涵盖了containerd和docker两项;

docker-shim组件是k8s为了专门与docker适配的,能够与Docker Engine进行通信

 这篇文章我们来一起学习下将k8s集群下的容器引擎切换为Containerd以及Containerd如何去使用的;


一、准备一套使用Docker引擎的kubernetes集群

我直接用之前kubeadm部署的单master集群来进行操作;有需要k8s单集群部署的可以看下:kubeadm部署k8s集群手册

软件环境:

软件 版本
操作系统 Centos 7.9_x64
docker 20-ce
kubernetes v1.20.0
containerd v1.6.4

服务器规划:

角色 IP
k8s-master 192.168.1.1
k8s-node1 192.168.1.2
k8s-node2 192.168.1.3

我们用于测试修改容器引擎,只需要在其中一个节点测试下就可以了,我在node2节点上进行修改;

二、配置先决条件

1.启用Containerd依赖的overlay、br_netfilter内核模块

[root@k8s-node2 ~]# lsmod | grep overlay
overlay                91659  6
[root@k8s-node2 ~]# lsmod | grep netfilter
br_netfilter           22256  0
bridge                151336  1 br_netfilter

这两个内核模块在操作系统中是默认加载的,可以使用lsmod来进行查看

提示:如果这两个内核模块没有加载的话可以执行下面的命令进行加载:

[root@k8s-node2 ~]# sudo modprobe overlay
[root@k8s-node2 ~]# sudo modprobe br_netfilter

2.设置必要的sysctl参数,这些参数在重新启动后仍然存在

[root@k8s-node2 ~]# cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1 #启动路由转发功能
EOF
[root@k8s-node2 ~]# sysctl --system #进行加载配置

三、安装Containerd

我们前面说过,containerd之前是docker的一部分,所以我们切换docker容器引擎为containerd的话则不需要安装containerd了
此时使用containerd容器引擎的流程图是这样的
如图:

提示:下面这些安装containerd的命令是针对之前容器引擎不是docker的或者没有安装过docker的亲们:

[root@k8s-node2 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo
[root@k8s-node2 ~]# yum install -y containerd.io
[root@k8s-node2 ~]# mkdir -p /etc/containerd
[root@k8s-node2 ~]# containerd config default > /etc/containerd/config.toml
[root@k8s-node2 ~]# ps -ef |grep containerd  #查看containerd的守护进程
root       1051      1  0 19:00 ?        00:00:08 /usr/bin/containerd
root       1237      1  0 19:00 ?        00:00:15 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root       3425      1  0 19:03 ?        00:00:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 0f2011ed7771da01d3077e0286076a77b4376195028e6d5845b6069af5d7786f -address /run/containerd/containerd.sock
...

四、修改Containerd配置文件

  • pause镜像设置为阿里云镜像仓库地址(默认是k8s国外的仓库,可能会拉去超时);
  • cgroups驱动设置为systemd;

提示:默认的containerd配置文件(/etc/containerd/config.toml)里的内容只有一行,是默认禁用cri的,如下图


所以我们需要重新获取下配置文件

[root@k8s-node2 ~]# containerd config default > /etc/containerd/config.toml
[root@k8s-node2 ~]# vim /etc/containerd/config.toml
disabled_plugins = []#可以看到此时生成的配置文件已经没有禁用cri了
[plugins."io.containerd.grpc.v1.cri"]sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]SystemdCgroup = true...

sandbox_image = “registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2” #设置管理容器(负责网络)的镜像为阿里云的镜像;
SystemdCgroup = true #需要在[plugins.“io.containerd.grpc.v1.cri”.containerd.default_runtime.options]下添加 ;设置cgroup的驱动为systemd

五、配置Kubelet使用Containerd

编辑kubelet配置文件/etc/sysconfig/kubelet
提示:这个配置文件是kubelet可以向对外提供参数的地方,我们想加参数的时候可以在这里加;

[root@k8s-node2 ~]# vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=/run/containerd/containerd.sock --cgroup-driver=systemd

–container-runtime=remote #表示我们使用的不是docker引擎(只要不是docker引擎的话都是remote这个值);
–container-runtime-endpoint=/run/containerd/containerd.sock #指定containerd的容器引擎地址,这个sock文件就相当于是个api;
–cgroup-driver=systemd #设置cgroup的驱动为systemd;

加的kubelet这些启动参数可以通以下命令查看

[root@k8s-node2 ~]# kubelet --help | grep runtime
--container-runtime string                                 The container runtime to use. Possible values: 'docker', 'remote'. (default "docker")
#可以看到kubelet使用的容器引擎由两个只,一个是docker,还有一个值是只要使用的不是docker引擎 那么值为remote;
--container-runtime-endpoint string                        [Experimental] The endpoint of remote runtime service. Currently unix socket endpoint is supported on Linux, while npipe and tcp endpoints are supported on windows.  Examples:'unix:///var/run/dockershim.sock', 'npipe:./pipe/dockershim' (default "unix:///var/run/dockershim.sock")
#指定容器引擎的api的地址,sock文件的地址,可以看到默认使用的是docker-shim的sock;

最后再重启下Containerd的进程
提示:Containerd是可以独立的去管理的,例如做start,stop操作;

[root@k8s-node2 ~]# systemctl restart containerd
[root@k8s-node2 ~]# systemctl status containerd
● containerd.service - containerd container runtimeLoaded: loaded (/usr/lib/systemd/system/containerd.service; disabled; vendor preset: disabled)Active: active (running) since Wed 2022-06-15 22:40:30 CST; 16s agoDocs: https://containerd.ioProcess: 21876 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)Main PID: 21878 (containerd)Tasks: 71Memory: 133.4MCGroup: /system.slice/containerd.service...

这时我们去master节点查看下node2这个节点使用的容器引擎是什么
提示:现在应该还是默认的docker,因为需要重启一下node2节点上的kubelet才会变成containerd引擎

[root@k8s-master ~]# kubectl get node -o wide
NAME         STATUS   ROLES                  AGE   VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
k8s-master   Ready    control-plane,master   8d    v1.20.11   192.168.1.1   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16
k8s-node1    Ready    <none>                 8d    v1.20.11   192.168.1.2   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16
k8s-node2    Ready    <none>                 8d    v1.20.11   192.168.1.3   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16

注意看最后CONTAINER-RUNTIME这一列,这一列表示的就是节点使用的容器引擎,可以看到现在还是使用的默认的引擎docker 20.10版本;

重启**kubelet**,使容器引擎使用containerd

[root@k8s-node2 ~]# systemctl restart kubelet
[root@k8s-node2 ~]# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node AgentLoaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)Drop-In: /usr/lib/systemd/system/kubelet.service.d└─10-kubeadm.confActive: active (running) since Wed 2022-06-15 22:51:00 CST; 9min agoDocs: https://kubernetes.io/docs/Main PID: 29912 (kubelet)Tasks: 14Memory: 40.2MCGroup: /system.slice/kubelet.service└─29912 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --...
...

再次查看node2节点使用的容器引擎

[root@k8s-master ~]# kubectl get node -o wide
NAME         STATUS   ROLES                  AGE   VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
k8s-master   Ready    control-plane,master   8d    v1.20.11   192.168.1.1   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16
k8s-node1    Ready    <none>                 8d    v1.20.11   192.168.1.2   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16
k8s-node2    Ready    <none>                 8d    v1.20.11   192.168.1.3   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   containerd://1.6.4

可以看到node2的容器引擎已经变成了containerd 1.6.4版本;
这就已经顺利的将docker切换成了containerd,现在如果创建个容器分配到这个节点上的话,就是containerd负责创建这个容器,包括销毁这样的动作,就不会再调用docker了;
提示:与此同时,docker还是会运行在此节点上的,但是有关容器的动作不会去调用docker,而是直接使用containerd,所以完全可以把docker这个进程干掉;

六、使用Containerd管理容器

 containerd提供了ctr命令行工具管理容器,但功能比较简单,所以一般会用crictl工具检查和调试容器。
提示:crictl这个工具,不只是给containerd提供的,而是所有适配CRI的容器引擎都可以用这个工具进行调试;
项目地址:https://github.com/kubernetes-sigs/cri-tools/

crictl这个工具默认是已经装了的

crictl这个工具最大的好处就是它与docker命令的使用风格是一毛一样的;
例如:

crictl查看本地镜像

[root@k8s-node2 ~]# crictl images
WARN[0000] image connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock uni As the default settings are now deprecated, you should set the endpoint instead.
ERRO[0000] unable to determine image API version: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial uninect: connection refused"
IMAGE                                                TAG                 IMAGE ID            SIZE
docker.io/calico/cni                                 v3.23.1             90d97aa939bbf       111MB
docker.io/calico/node                                v3.23.1             fbfd04bbb7f47       76.6MB
docker.io/library/busybox                            latest              62aedd01bd852       778kB
docker.io/library/nginx                              latest              0e901e68141fd       56.7MB
registry.aliyuncs.com/google_containers/coredns      1.7.0               bfe3a36ebd252       14MB
registry.aliyuncs.com/google_containers/kube-proxy   v1.23.0             e03484a90585e       39.3MB
registry.aliyuncs.com/google_containers/pause        3.2                 80d28bedfe5de       300kB

噶,我们可以看到报错了,
  这个Warnning是因为默认的引擎是一个列表,会一个一个的去连接尝试一下;这个列表里面包含了dockershim.sockcontainerd.sockcri-dockerd.sock(红帽的容器引擎);但是现在已经弃用了,所以报Warnning;
 这个ERROR报的是连接不上docker导致的;但是结果最终还是给我们输出了镜像信息,还是因为那个默认引擎是个列表,docker连不上,就给我们连上了containerd这个引擎 列出了镜像;
提示:我们在上面的引擎列表里可以看到有个dockershim.sock,这可能是docker已经做出了向k8s CRI适配的一个动作喔;

下面写下这个错误的解决办法,否则他会一直尝试连接这个列表的

[root@k8s-node2 ~]# vim /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10 #超时时间
debug: false #debug是否输出debug信息

/etc/crictl.yaml是crictl这个工具默认的配置文件,需要创建;
然后需要指定下endpoint的为containerd的sock地址;

再次查看镜像就没有warnning和error信息了;

[root@k8s-node2 ~]# crictl images
IMAGE                       TAG                 IMAGE ID            SIZE
docker.io/library/busybox   latest              62aedd01bd852       778kB

crictl查看本地容器

[root@k8s-node2 ~]# crictl ps
CONTAINER           IMAGE               CREATED             STATE               NAME                ATTEMPT             POD ID              POD
ff073f3b0c45b       bfe3a36ebd252       3 minutes ago       Running             coredns             0                   220dcdcae5aff       coredns-5879556fbc-ghxfx
b16aa39b0554a       e03484a90585e       3 minutes ago       Running             kube-proxy          0                   64bccc538f5b4       kube-proxy-jhh5p
435bd9ba245eb       fbfd04bbb7f47       4 minutes ago       Running             calico-node         0                   4b01fffd2aea7       calico-node-gk86n
bd9d6caa5a8f9       0e901e68141fd       5 minutes ago       Running             my-nginx            0                   69f53f8f4e577       my-nginx-64cc7f8db7-b64gb
198c13cf5d94f       0e901e68141fd       5 minutes ago       Running             my-nginx            0                   cc4506ed4c87a       my-nginx-64cc7f8db7-2hcvb

crictl进入容器

[root@k8s-node2 ~]# crictl exec -it bd9d6caa5a8f9 bash
root@my-nginx-64cc7f8db7-b64gb:/# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@my-nginx-64cc7f8db7-b64gb:/#

crictl查看pod

[root@k8s-node2 ~]# crictl pods
POD ID              CREATED             STATE               NAME                        NAMESPACE           ATTEMPT             RUNTIME
220dcdcae5aff       9 minutes ago       Ready               coredns-5879556fbc-ghxfx    kube-system         0                   (default)
69f53f8f4e577       9 minutes ago       Ready               my-nginx-64cc7f8db7-b64gb   default             0                   (default)
cc4506ed4c87a       9 minutes ago       Ready               my-nginx-64cc7f8db7-2hcvb   default             0                   (default)
64bccc538f5b4       9 minutes ago       Ready               kube-proxy-jhh5p            kube-system         0                   (default)
4b01fffd2aea7       9 minutes ago       Ready               calico-node-gk86n           kube-system         0                   (default)

这里就先演示这几个crictl命令;更多的命令我会在下面列出来

crictl常用命令

镜像:

镜像相关功能 Docker Containerd
显示本地镜像列表 docker images crictl images
下载镜像 docker pull crictl pull
上传镜像 docker push 无,需要使用buildkit等工具构建并上传镜像
删除本地镜像 docker rmi crictl rmi
查看镜像详情 docker inspect crictl inspecti IMAGE-ID

容器:

容器相关功能 Docker Containerd
显示容器列表 docker ps crictl ps
创建容器 docker create crictl create
启动容器 docker start crictl start
停止容器 docker stop crictl stop
删除容器 docker rm crictl rm
查看容器详情 docker inspect crictl inspect
附加容器 docker attach crictl attach
进入容器/执行命令 docker exec crictl exec
查看日志 docker logs crictl logs
查看容器资源 docker stats crictl stats

Pod:

Pod相关功能 Docker Containerd
显示Pod列表 crictl pods
查看Pod详情 crictl inspectp
运行Pod crictl runp
停止Pod crictl stopp

七、切换回Docker容器引擎

提示:containerd只是作为测试练习,建议练习后还切回Docker引擎,就是把kubelet配置参数去掉并重启kubelet即可;

[root@k8s-node2 ~]# vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=
[root@k8s-node2 ~]# systemctl restart kubelet
然后去master节点上查看node2节点是否切换回了docker容器引擎
[root@k8s-master ~]# kubectl get nodes -o wide
NAME         STATUS   ROLES                  AGE   VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
k8s-master   Ready    control-plane,master   8d    v1.20.11   192.168.1.1   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16
k8s-node1    Ready    <none>                 8d    v1.20.11   192.168.1.2   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16
k8s-node2    Ready    <none>                 8d    v1.20.11   192.168.1.3   <none>        CentOS Linux 7 (Core)   3.10.0-1160.66.1.el7.x86_64   docker://20.10.16

总结

到这里,切换contained容器引擎就结束了;
 通过学习,总结了以下几个切换contianerd的相关问题:

  1. 正常情况下是所有节点都完成切换,前期测试建议docker与containerd共存;
  2. containerd完全兼容之前的容器镜像,应该说是只要是与CRI适配了的容器引擎它们之间的镜像都是兼容的,因为CRI也有一套容器镜像的标准;
  3. 学习containerd是先做技术储备,并不是立马就要用,还是用docker就行;

Kubernetes切换Docker容器引擎为Containerd相关推荐

  1. 技术选型之Docker容器引擎

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | huashiou 来源 | https://s ...

  2. docker文件过大,Docker容器引擎,迁移/var/lib/docker/到本机其它挂载分区或远程主机的某个分区。docker迁移

    docker文件过大,Docker容器引擎,迁移/var/lib/docker/到本机其它挂载分区或远程主机的某个分区.docker迁移. 0. 迁移前检查镜像和容器 docker images 和d ...

  3. Docker容器引擎

    文章目录 一.概述 1. Docker能解决的问题 2. Docker思想 3. Docker为什么这么火?(作用) 4. 底层 5. 官网和文档 6. 基本组成(图解) 7. 核心概念(名词) 10 ...

  4. Kubernetes 的CRI-O容器引擎中存在严重漏洞

     聚焦源代码安全,网罗国内外最新资讯! 编译:代码卫士 专栏·供应链安全 数字化时代,软件无处不在.软件如同社会中的"虚拟人",已经成为支撑社会正常运转的最基本元素之一,软件的安全 ...

  5. 陌陌基于Kubernetes和Docker容器管理平台的架构实践

    为什么选择使用Kubernetes? 在使用Kubernetes之前,陌陌在应用发布和运行环境方面遇到的具体问题,如下: 应用发布时间很长,主要是因为发布过程中需要做隔离.恢复等动作,还需要登录查看实 ...

  6. 【云原生 | 01】docker容器引擎

  7. 一文告诉你,如何在 Kubernetes 的容器引擎中运行 KVM 和 VMware VM!

    作者 | Gilson Melo 译者 | 天道酬勤 责编 | 徐威龙 封图| CSDN下载于视觉中国 随着微服务的出现,人们通常会问:"是否有可能通过Kubernetes上的微服务在基于内 ...

  8. Kubernetes弃用Docker?关于Kubernetes、Docker和containerd的那些事

    00 前情提要 作为后端研发工程师,之前的工作中还是涉及到一部分K8S的工作.在当时的工作场景下,我们通过使用Kubernetes(简称k8s)+docker编排部署的架构方案来提供云原生的在线服务. ...

  9. 探索学习:网红容器引擎Docker

    近两年容器技术成为开源社区中的网红,轻便易用,集开发.持续集成.交付和运行于一体.本文将按照如下结构与大家一起进行探索和学习. 1. Docker的起源 Docker容器引擎由Docker Inc(前 ...

最新文章

  1. php正则表达式函数 preg_replace用法
  2. (转载)IIS安装配置全过程
  3. 【转】关于MySQL权限
  4. 【poj3734】矩阵乘法求解
  5. 【Java面试题】41 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?...
  6. 117. Populating Next Right Pointers in Each Node II
  7. CodeForces - 796D Police Stations bfs
  8. 银联分账与银联代付_第三方分账系统到底有哪些作用?
  9. matlab 波前像差,波前像差原理及应用
  10. SQL Server中以独占的方式操作表
  11. 自媒体人本质是互联网公司内容运营的角色
  12. 性能翻倍!斯坦福Matei团队推出机器学习模型优化新方法
  13. 判断输入的字符与已知字符相等_你会输入带圈字符吗?
  14. 3D建模师是吃青春饭的吗?被高薪挖掘的建模人才,靠的是这个
  15. clonezilla的可启动U盘的制作及使用
  16. 升压型 串联LED 背光恒流输出的驱动芯片
  17. 微信团队分享:微信支付代码重构带来的移动端软件架构上的思考
  18. 演出遭遇枪击 前Pantera吉他手不幸身亡
  19. T 分布与高斯分布的差异
  20. 村庄规划工作底图制作

热门文章

  1. bcc服务器搭建网站,如何用云服务器bcc建站
  2. mt4量化交易接口:分享日常量化选股方法
  3. 我在哪?要到哪里去?怎么去?
  4. SQL零基础入门学习(一)
  5. 纺织ERP系统_纺织ERP软件_纺织面料系统
  6. macw资讯:MacOS如何隐藏、加密文件或文件夹
  7. zabbix报警方式,邮件报警和微信报警。
  8. 【2023团体程序设计天梯赛CCCC】GPLT2023,L1~L2部分(PTA,L1-089~L1-096,L2-045~L2-048)题解代码复盘
  9. 【Tools】抓包工具——Charles(中名:花瓶)
  10. linux进不去root,进不了root