Kubernetes切换Docker容器引擎为Containerd


前言

 在未来的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
docker20-ce
kubernetesv1.20.0
containerdv1.6.4

服务器规划:

角色IP
k8s-master192.168.1.1
k8s-node1192.168.1.2
k8s-node2192.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 runtime
   Loaded: loaded (/usr/lib/systemd/system/containerd.service; disabled; vendor preset: disabled)
   Active: active (running) since Wed 2022-06-15 22:40:30 CST; 16s ago
     Docs: https://containerd.io
  Process: 21876 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
 Main PID: 21878 (containerd)
    Tasks: 71
   Memory: 133.4M
   CGroup: /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 Agent
   Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: active (running) since Wed 2022-06-15 22:51:00 CST; 9min ago
     Docs: https://kubernetes.io/docs/
 Main PID: 29912 (kubelet)
    Tasks: 14
   Memory: 40.2M
   CGroup: /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常用命令

镜像:

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

容器:

容器相关功能DockerContainerd
显示容器列表docker pscrictl ps
创建容器docker createcrictl create
启动容器docker startcrictl start
停止容器docker stopcrictl stop
删除容器docker rmcrictl rm
查看容器详情docker inspectcrictl inspect
附加容器docker attachcrictl attach
进入容器/执行命令docker execcrictl exec
查看日志docker logscrictl logs
查看容器资源docker statscrictl stats

Pod:

Pod相关功能DockerContainerd
显示Pod列表crictl pods
查看Pod详情crictl inspectp
运行Podcrictl runp
停止Podcrictl 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就行;
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PVE(Proxmox Virtual Environment)是一个开源的虚拟化平台,可以用于运行虚拟机和容器,同时支持多节点集群。Ceph 是一个分布式存储系统,可以提供高可用、可扩展的存储服务。Kubernetes 是一个容器编排平台,可以自动化地部署、扩展和管理容器化应用程序。Docker 是一个开源的容器引擎,可以将应用程序及其依赖项打包成容器,以便在任何地方进行部署。 将这些技术结合在一起,可以构建一个高度可扩展、高可用性的容器平台。以下是一些实现步骤: 1. 在多个物理节点上安装 PVE,并创建 PVE 集群。 2. 在 PVE 集群上安装 Ceph,并将其配置为多节点 Ceph 集群,以提供高可用的存储服务。 3. 在 Kubernetes 集群中使用 Ceph RBD 存储插件,以便将容器挂载到 Ceph 存储中。 4. 安装 DockerKubernetes,使用 kubeadm 初始化 Kubernetes 集群,并加入节点。 5. 在 Kubernetes 集群中安装容器平台,如 OpenShift 或 Rancher,以便管理和部署容器化应用程序。 6. 配置容器平台以使用 Ceph 存储和 Kubernetes 负载均衡服务。 7. 在容器平台上创建应用程序和服务,并部署到 Kubernetes 集群中,以实现高度可扩展、高可用性的容器化应用程序。 需要注意的是,这些技术的组合和部署非常复杂,需要深入了解每个技术的工作原理和实现方式,同时需要考虑安全性、性能和可维护性等因素。因此,在实现这样的容器平台之前,建议进行充分的规划和测试,以确保平台的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知名运维:

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值