终于有人说清楚 docker containerd

背景

随着Kubernetes的兴起,Docker在K8s中的地位逐渐受到挑战。一方面,Docker作为一个完整的容器平台,包含了许多K8s并不需要的功能,导致资源浪费。另一方面,K8s本身提供了容器编排和调度的功能,与Docker重叠,造成了一定程度上的冲突。Kubernetes早在1.20版本中变更日志描述如下: "Docker support in the kubelet is now deprecated and will be removed in a future release. "。Kubernetes弃用Docker,其实也不用过分紧张,在文章: 别慌: Kubernetes 和 Docker中 , 作者简介清晰的表达了观点:弃用 Docker 这个底层运行时,转而支持符合为 Kubernetes 创建的容器运行接口 Container Runtime Interface (CRI) 的运行时(常见的选择 containerd 和 CRI-O)。 但使用 Docker 构建的镜像,仍然可以在你的集群的所有运行时中继续工作。因为docker构建的镜像是符合OCI(Open Container Initiative)标准的。

那么Kubernetes为什么要移除Docker?主要原因还是Docker长期以来不支持Kubernetes主推的CRI容器运行时标准,Kubernetes需要长期维护着dockershim组件来专门适配Docker。dockershim是出现在Kubernetes发展初期、Docker如日中天阶段的产物,但是随着containerd等容器运行时的发展,Kubernetes也有了足够的理由不再维护dockershim了。

kubernetes Docker完整调用链

在这里插入图片描述

kubernetes Containerd完整调用链

docker

Docker作为一种早期的容器技术,它的出现颠覆了传统虚拟化方式,通过轻量级容器化的方式实现了应用的打包、交付和运行。Docker在容器技术的普及过程中发挥了关键作用,其用户友好的命令行工具和图形化界面让容器技术对广大开发者变得更加友好和易用。一度,Docker几乎成为容器化的代名词。为了防止docker一家独大,docker当年的实现被拆分出了几个标准化的模块,标准化的目的是模块是可被其他实现替换的,不由任何一个厂商控制。 Docker 由

  • docker-client
  • dockerd
  • containerd
  • docker-shim
  • runc

组成,所以containerd是docker的基础组件之一,docker 对容器的管理和操作基本都是通过 containerd 完成的。 那么,containerd 是什么呢?

docker完整调用链

在这里插入图片描述

containerd

Containerd是由Docker团队开源的容器运行时,它专注于提供轻量级、高性能的容器运行环境。作为一个纯粹的容器运行时,Containerd被设计为更加符合K8s的架构和需求。它具有更小的资源占用,更快的启动时间,以及更好的性能表现。 K8s社区认可了Containerd的优势,并将其作为K8s生态系统的标配容器运行时。 Containerd 可以在宿主机中管理完整的容器生命周期:容器镜像的传输和存储、容器的执行和管理、存储和网络等。详细点说,Containerd 负责干下面这些事情:

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

Containerd 和 Docker 组件常用命令是什么

Containerd 不支持 docker API 和 docker CLI,但是可以通过 cri-tool 命令实现类似的功能。

镜像相关

镜像相关功能DockerContainerd
显示本地镜像列表docker imagescrictl images
下载镜像docker pullcrictl pull
上传镜像docker push
删除本地镜像docker rmicrictl rmi
查看镜像详情docker inspect IMAGE-IDcrictl inspect IMAGE-ID

容器相关

容器相关功能DockerContainerd
显示容器列表docker pscrictl ps
创建容器docker createcrictl create
启动容器docker startcrictl start
停止容器docker stopcrictl stop
删除容器docker rmcrictl rm
查看容器详情docker inspectcrictl inspect
attachdocker attachcrictl attach
execdocker execcrictl exec
logsdocker logscrictl logs
statsdocker statscrictl stats

容器相关

POD 相关功能DockerContainerd
显示 POD 列表crictl pods
查看 POD 详情crictl inspectp
运行 PODcrictl runp
停止 PODcrictl stopp

安装crictl工具

下载crictl需和kubernetes版本对应

Kubernetes Versioncri-tools Versioncri-tools branch
≥ 1.27.x≥ 1.27.xmaster
≥ 1.16.x ≤ 1.26.x≥ 1.16.x ≤ 1.26.xmaster
1.15.Xv1.15.0release-1.15
1.14.Xv1.14.0release-1.14
1.13.Xv1.13.0release-1.13
1.12.Xv1.12.0release-1.12
1.11.Xv1.11.1release-1.11
1.10.Xv1.0.0-beta.2release-1.10
1.9.Xv1.0.0-alpha.1release-1.9
1.8.Xv0.2release-1.8
1.7.Xv0.1release-1.7
VERSION="v1.22.0"  #下载与你的 kubernetes 版本相对应的版本
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz


# 解压crictl
tar zxvf crictl-$VERSION-linux-amd64.tar.gz
chown root.root crictl
mv crictl /usr/bin/

创建crictl 配置

cat <<EOF | tee /etc/crictl.yaml
runtime-endpoint: "unix:///var/run/containerd/containerd.sock"
image-endpoint: "unix:///var/run/containerd/containerd.sock"
timeout: 10
debug: false
pull-image-on-create: true
disable-pull-on-run: false
EOF

安装containerd

yum -y install  containerd.io
# 创建containerd配置目录
mkdir -p /etc/containerd

# 生成containerd默认配置文件
containerd config default | sudo tee /etc/containerd/config.toml

启用 IPv4 数据包转发

手动启用 IPv4 数据包转发:

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

使用以下命令验证 net.ipv4.ip_forward 是否设置为 1:

sysctl net.ipv4.ip_forward

需要修改 /etc/containerd/config.toml 为如下内容

# 修改 pause 容器的下载地址,改成国内地址
sandbox_image = "registry.aliyuncs.com/k8sxio/pause:3.6"

# 结合 runc 使用 systemd cgroup 驱动
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

如果你使用 cgroup v2,则推荐 systemd cgroup 驱动。

Kubernetes集群容器引擎切换

环境

  • OS: CentOS 7.6(当前最新版kernel)
  • Container runtime: Docker CE 20.10.11
  • Kubernetes: v1.22.4
[root@k8s-master-01 ~]# kubectl get nodes -o wide
NAME            STATUS   ROLES                  AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
k8s-master-01   Ready    control-plane,master   11m   v1.22.4   172.16.50.200   <none>        CentOS Linux 7 (Core)   5.4.163-1.el7.elrepo.x86_64   docker://20.10.11
k8s-node-01     Ready    <none>                 10m   v1.22.4   172.16.50.203   <none>        CentOS Linux 7 (Core)   5.4.163-1.el7.elrepo.x86_64   docker://20.10.11
k8s-node-02     Ready    <none>                 10m   v1.22.4   172.16.50.204   <none>        CentOS Linux 7 (Core)   5.4.163-1.el7.elrepo.x86_64   docker://20.10.11

将该node标记为不可被调度,并且驱逐该node上的pod资源

[root@k8s-master-01 ~]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE          NOMINATED NODE   READINESS GATES
busybox                  1/1     Running   0          14m   10.244.1.2   k8s-node-01   <none>           <none>
nginx-7fb7fd49b4-pzqm6   1/1     Running   0          14m   10.244.2.2   k8s-node-02   <none>           <none>

驱逐该node节点上的pod资源到集群中的其它节点上去

kubectl drain k8s-node-02 --delete-local-data --force --ignore-daemonsets

查看之前运行在该node上的pod被调度到了集群中的哪个节点

kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP           NODE          NOMINATED NODE   READINESS GATES
busybox                  1/1     Running   0          23m     10.244.1.2   k8s-node-01   <none>           <none>
nginx-7fb7fd49b4-bg5pn   1/1     Running   0          3m18s   10.244.1.3   k8s-node-01   <none>           <none>

查看Kubernetes集群中的node资源信息

[root@k8s-master-01 ~]# kubectl get nodes
NAME            STATUS                     ROLES                  AGE   VERSION
k8s-master-01   Ready                      control-plane,master   33m   v1.22.4
k8s-node-01     Ready                      <none>                 32m   v1.22.4
k8s-node-02     Ready,SchedulingDisabled   <none>                 32m   v1.22.4

# 如上信息,k8s-node-02节点已经不可被调度了,接下来开始切换容器引擎

卸载原有docker

rpm -qa | grep docker
rpm -e docker-ce-20.10.11-3.el7.x86_64 docker-ce-cli-20.10.11-3.el7.x86_64 docker-ce-rootless-extras-20.10.11-3.el7.x86_64 docker-scan-plugin-0.9.0-3.el7.x86_64 

安装containerd部分请参考本文章上面部分,这里我就不在写一遍了,安装方法都是一样的。
配置kubelet使用containerd

vim /var/lib/kubelet/kubeadm-flags.env 
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock"

重启kubelet

systemctl daemon-reload
systemctl restart kubelet

验证容器引擎是否成功切换为containerd

[root@k8s-master-01 ~]# kubectl get nodes -o wide
NAME            STATUS                     ROLES                  AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
k8s-master-01   Ready                      control-plane,master   51m   v1.22.4   172.16.50.200   <none>        CentOS Linux 7 (Core)   5.4.163-1.el7.elrepo.x86_64   docker://20.10.11
k8s-node-01     Ready                      <none>                 51m   v1.22.4   172.16.50.203   <none>        CentOS Linux 7 (Core)   5.4.163-1.el7.elrepo.x86_64   docker://20.10.11
k8s-node-02     Ready,SchedulingDisabled   <none>                 51m   v1.22.4   172.16.50.204   <none>        CentOS Linux 7 (Core)   5.4.163-1.el7.elrepo.x86_64   containerd://1.4.12

通过将节点标记为可调度,让节点重新上线

# 将 <node-to-drain> 替换为当前节点的名称
kubectl uncordon <node-to-drain>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值