转载自:https://www.51cto.com/article/710688.html

前段时间,kubernetes推出了1.24版本,曾经轰动一时的docker弃用也正式实装了,这意味着1.24版本之后,docker将不能作为k8s的容器运行时。docker作为云原生的基础技术底座,如果kubernetes不再支持docker,这在互联网IT业界都会引发不大不小的恐慌,这到底该怎么办?

作者 | 刘启伟,广东公司网络管理中心网管系统室平台团队核心专家。近年来,网管系统室一方面大力推进OSS应用建设,为“三零三自”的自智网络赋能;另一方面,积极推动微服务、容器化、PaaS、DevOps等云原生技术的实践落地。在团队中负责DevOps平台和容器云的建设运营工作,拥有丰富的Kubernetes、Istio、DevOps工具链落地实践经验,致力于克服技术落地难题,用云原生技术赋能应用。

导读

​Kubernetes是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。Kubernetes拥有一个庞大且快速增长的生态系统,其服务、支持和工具的使用范围广泛。

1前言

前段时间,kubernetes推出了1.24版本,曾经轰动一时的docker弃用也正式实装了,这意味着1.24版本之后,docker将不能作为k8s的容器运行时。docker作为云原生的基础技术底座,如果kubernetes不再支持docker,这在互联网IT业界都会引发不大不小的恐慌,这到底该怎么办?是不是docker完全不能使用了?

2技术的真相

其实kubernetes只是弃用了dockershim,并不是弃用了docker的全部。docker体系中的containerd是符合CRI标准的,可以继续作为kubernetes的容器运行时。而OCI标准的实现者runC也是docker体系的。

另一方面,docker构建的镜像符合OCI标准,可以运行在kubernetes集群中,所以仍然可以在本地使用docker进行开发和测试。

2.1 OCI和CRI标准分别是什么?

OCI(Open Container Initiative)是一组围绕容器技术的开放标准和规范,主要定义了容器的生命周期管理规范。OCI的实现者通常被称为“低级容器运行时”,例如runC。低级运行时的主要功能是按照给定的容器文件系统和JSON配置文件,创建容器,并管理容器的生命周期。

CRI(Container Runtime Interface)是一组插件接口,定义了kubernetes(kubelet)与容器运行时的接口规范,实现两者之间的解耦。通过CRI与kubernetes交互的运行时通常被称为“高级容器运行时”。高级运行时的功能是为容器准备必要的运行环境,比如拉取镜像、解压镜像并创建容器文件系统、创建容器网络等,然后调用低级容器运行时,创建和运行容器。

2.2 kubernetes支持哪些容器运行时?

kubernetes支持任何符合CRI标准的容器运行时。在1.23版本之前,常用的容器运行时有三种:docker、containerd、cri-o.

docker

docker守护进程是不符合CRI标准的。为了支持docker作为容器运行时,kubelet内置了一个dockershim模块,kubelet通过CRI调用dockershim,再由它转换请求,调用docker守护进程,而1.24版本将要移除的就是这个模块。此模式下创建容器时的调用过程如下:

  • kubelet通过CRI调用dockershim;
  • dockershim转换请求,调用docker守护进程;
  • docker调用containerd;
  • containerd创建containerd-shim进程,再由containerd-shim调用runC完成容器创建。最终容器由containerd-shim管理,容器内所有进程都是containerd-shim的子进程。

containerd

containerd是从docker守护进程中独立出来的容器运行时,最终也要通过runC运行容器。

在CRI标准被提出后,为了兼容CRI,减少调用开销,containerd开发了一个守护进程,叫CRI-containerd。原先调用链kubelet -> dockershim -> dockerd -> containerd 被简化成为 kubelet -> CRI-containerd -> containerd。后来,containerd干脆将CRI-containerd以CRI插件形式内建在项目中,直接通过方法调用,进一步将调用链简化为 kubelet -> containerd。

cri-o

CRI标准被提出后,红帽按照CRI开发的一个轻量级容器运行时,是CRI标准的最小实现。此模式下kubelet直接调用cri-o,再由cri-o调用runC完成容器创建和管理,调用链比较简洁。

将容器运行时从docker迁移至cri-o,并验证下kubernetes 1.23 -> 1.24版本升级方案,以下是迁移的部分注意事项及详细步骤。

3迁移注意事项和详细步骤

注意事项:

  1. 对于使用docker in docker的pod,如果是挂载宿主机的docker.sock守护进程,迁移后将不能运行,如果是在容器中安装独立的docker守护进程,迁移后仍然可以正常运行。
  2. /etc/docker/daemon.json中的配置需要同步到新的运行时,比如仓库的镜像站点。
  3. 检查各种运维脚本,如果包含docker命令需要修改。
  4. 容器stdout/stderr日志形式变更,如果使用Fluentd或者Filebeat收集日志,需要修改配置。

① 日志目录:使用docker时,日志通过/var/log/containers链接到/var/log/pods/目录,最后链接到/var/lib/docker/containers/xxx/目录,如果使用其他运行时,一般是通过/var/log/containers链接到/var/log/pods/目录,由kubelet管理。

② 日志格式:使用docker时,很多人习惯设置json格式,而切换到其他运行时,默认格式是text,格式为“time stream log-info”。日志解析配置需要修改。

③ 日志回滚:使用docker时,在daemon.json配置,切换运行时后,通过kubelet的配置项containerLogMaxSize、containerLogMaxFiles设置。

怎么将kubernetes的容器运行时从docker迁移至cri-o?

  • 操作系统:centOS 7.9
  • 内核版本:5.4.178
  • kubernetes版本:1.23.3
  • cri-o:1.22.3

1. 迁移按节点进行,先驱逐pod并隔离节点

kubectl drain --delete-emptydir-data --force --ignore-daemonsets <NODE_NAME>

2. 卸载docker

systemctl stop kubelet
systemctl stop docker
systemctl disable docker
yum remove -y docker-ce
# docker数据目录先保留一段时间,运行没异常再删除
rm -rf /var/lib/docker

3. 内核设置

这些设置一般在k8s安装前都会设置,这里再确认一次,已经设置好的忽略这一步。

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sysctl --system
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter

4. 安装cri-o

# 设置yum源
export OS=CentOS_7
export VERSION=1.22
curl -L -o
/etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/devel:kubic:libcontainers:stable.repo
curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo
# 安装cri-o
yum install -y cri-o

5. 修改cri-o配置

# 查看conmon路径
which conmon
# 修改cri-o配置文件
vi /etc/crio/crio.conf
# 修改crio.runtime表,加上conmon路径配置
[crio.runtime]
conmon = "/usr/bin/conmon"
# 修改crio.image表,加上pause镜像设置。xxx需要换成你的私有镜像库
[crio.image]
insecure_registries = ["xxx"]
pause_image = "xxx/k8s/pause:3.6"
# 修改registry配置
vi /etc/containers/registries.conf
# 添加私有镜像库,xxx需要替换成你的私有镜像库,这里设置了insecure,可按实现情况修改
# 因为我用的是私有仓库,不需要设置镜像站点
[[registry]]
prefix = "xxx"
insecure = true
blocked = false
location = "xxx"

6. 启动cri-o服务

systemctl enable crio
systemctl start crio
systemctl status crio

7. 修改kubelet配置

设置kubelet命令行启动参数,指定使用cri-o运行时。

vi /etc/sysconfig/kubelet
# 修改内容,加上以下两个参数
KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint='unix:///var/run/crio/crio.sock'

修改 /var/lib/kubelet/kubeadm-flags.env 文件,文件中如果有以下3个参数,请删除。

  • --cgroup-driver k8s建议在配置文件设置,不要在命令行。
  • --cni-plugin 1.24版本后会和docker-shim一起被移除。
  • --pod-infra-container-image 当使用cri-o运行时,kubelet忽略这个参数,需要在cri-o配置中指定。

修改kubelet的配置文件 /var/lib/kubelet/config.yaml,修改以下4个参数,如果参数不存在则添加上去。

设置kubelet的cgroup驱动为systemd,因为cri-o默认驱动是systemd,必须保持一致。旧版本kubelet默认驱动是cgroupfs,1.22以上才是默认systemd。

cgroupDriver: systemd

设置运行时请求超时:

runtimeRequestTimeout: 5m

容器stdout/stderr日志文件的回滚设置,按实际需求修改。

containerLogMaxSize: 100Mi
containerLogMaxFiles: 3

修改了 /var/lib/kubelet/config.yaml 文件后,建议同步修改内容到kubelet-config-1.xx configmap,1.xx是kubernetes的版本。因为集群扩容时,新节点使用这个configmap生成配置文件,这样可以保证新旧节点配置文件一致。

kubectl edit cm -n kube-system kubelet-config-1.23

8. 启动kubelet,查看kubelet状态、节点状态、pod状态是否正常。

systemctl start kubelet
systemctl status kubelet

9. 更新kubeadm使用的cri运行时

kubeadm使用的cri运行时在node annotations中定义,需要单独修改,否则下次使用kubeadm时会出错,比如升级k8s版本的时候。

# 查看当前节点的kubeadm使用的cri运行时
kubectl get node <NODE_NAME> -o jsonpath='{.metadata.annotations.kubeadm\.alpha\.kubernetes\.io/cri-socket}'
# 将dokcershim修改为cri-o
kubectl annotate node <NODE_NAME> --overwrite kubeadm.alpha.kubernetes.io/cri-socket=/var/run/crio/crio.sock

10. 安装podman

podman是一个开源的容器管理工具,命令几乎与docker一致,可以用于替换docker。相较于docker,它不存在守护进程,因此podman避免了docker daemon引入的问题。另一方面,cri-o专注于CRI实现,没有提供build、tag镜像等功能,而podman和cri-o的镜像是共享的,可以为cri-o补充镜像管理功能。

yum install -y podman
podman info

11. 重启服务器

docker卸载后可能还有一些配置遗留,例如iptables规则,建议重启服务器,防止被影响。

12. 将节点重新加入集群调度。

kubectl uncordon <NODE_NAME>

到这里,第一个节点的容器运行时迁移就完成了,可以按照相同的方法再迁移其他节点。

迁移完成后就能愉快地把k8s版本升到1.24.0了。

4后记

虽然k8s已经正式移除了dockershim,但是docker+kubernetes的方案经过多年发展已经成熟,被广泛地应用,短期内地位仍然不可撼动。开发、测试环境可以按照需求折腾,迁移容器运行时,积累实践经验。生产环境的话建议保持稳定,等时机成熟再迁移。

kubernetes弃用dockershim的更多相关文章

  1. Kubernetes弃用Docker后怎么办?

    本文转自Rancher Labs 近期,Kubernetes在其最新的Changelog中宣布,自Kubernetes 1.20之后将弃用Docker作为容器运行时.这一消息在云原生领域激起了不小的水 ...

  2. 系列好文 | Kubernetes 弃用 Docker,我们该何去何从?

    作者 | 张攀(豫哲) 来源 | 尔达 Erda 公众号 导读:Erda 作为一站式云原生 PaaS 平台,现已面向广大开发者完成 70w+ 核心代码全部开源!**在 Erda 开源的同时,我们计划编 ...

  3. 实操|如何将 Containerd 用作 Kubernetes runtime

    日前专为开发者提供技术分享的又拍云 OpenTalk 公开课邀请了网易有道资深运维开发工程师张晋涛,直播分享<Containerd 上手实践 >,详细介绍 Containerd 的发展历程 ...

  4. kind:Kubernetes in Docker,单机测试 Kubernetes 群集的最佳方案

    请访问原文发布链接:https://sysin.org/article/kind/,查看最新版. 作者:gc(at)sysin.org,主页:www.sysin.org 2021.04.28 更新,k ...

  5. runc hang 导致 Kubernetes 节点 NotReady

    Kubernetes 1.19.3 OS: CentOS 7.9.2009 Kernel: 5.4.94-1.el7.elrepo.x86_64 Docker: 20.10.6 先说结论,runc v ...

  6. 将 Docker Engine 节点从 dockershim 迁移到 cri-dockerd

    官网地址:https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/migrating-from-dockershim/migrate-doc ...

  7. K8s 终将废弃 docker,TKE 早已支持 containerd

    近日 K8s 官方称最早将在 1.23版本弃用 docker 作为容器运行时,并在博客中强调可以使用如 containerd 等 CRI 运行时来代替 docker.本文会做详细解读,并介绍 dock ...

  8. 基于containerd二进制部署k8s-v1.23.3

    文章目录 前言 k8s 组件 环境准备 创建目录 关闭防火墙 关闭selinux 关闭swap 开启内核模块 分发到所有节点 启用systemd自动加载模块服务 配置系统参数 分发到所有节点 加载系统 ...

  9. 如何使用 Kind 快速创建 K8s 集群?

    作者|段超 来源|尔达 Erda 公众号 ​ 导读:Erda 作为一站式云原生 PaaS 平台,现已面向广大开发者完成 70w+ 核心代码全部开源!在 Erda 开源的同时,我们计划编写<基于 ...

  10. 无需依赖Docker环境制作镜像

    随着高版本的Kubernetes弃用Docker,企业也可以不依赖Docker环境了,但是DevOps通过Kubernetes部署的话,仍然需要制作镜像,那么在没有Docker环境的情况下如何制作呢? ...

随机推荐

  1. Spring Boot整合JSP --CRUD

    Springboot整合JSP spring boot与视图层次的整合: JSP 效率低 Thymeleaf java Server page 是Java提供的一种动态的网页技术,低层是Servlet ...

  2. 微信小程序 添加域名

    1.不校验合法域名.web-view (业务域名).TLS版本以及 HTTPS证书 2.小程序上的请求=>服务器的根地址=>都需要添加微信公众平台(否则会无法发送请求,导致代码报错)

  3. CCRD_TOC_2007_EULAR专辑_1

    中信国健临床通讯 EULAR 2007专辑I 目 录 类风湿关节炎 1 TEMPO 研究第一年影像学数据显示:骨侵蚀修复 (repair) 几乎只出现在无关节肿胀或肿胀改善组 van der Heij ...

  4. Gridea,一个小而美的博客梦想桥梁

    欢迎到我自己搭建的博客查看最新最全的这篇文章,效果更佳- 备注:本文叙述操作过程非常详细,会稍现冗长,可以适当的跳读. 引子 相信大家应该已经非常了解GitHub pages了,他是一个基于githu ...

  5. oculus 安装其他盘方法

    把安装文件OculusSetup.exe安装到D盘(默认直接按C盘) D:\softbackup\OculusSetup.exe /drive=D

  6. js-解决安卓手机软键盘弹出后,固定定位布局被顶上移问题

    分析:软键盘弹出后,导致页面高度变化 解决方案:软键盘弹出后,修复页面高度 // 监听窗口变化 resizeScreen(){ if (!this.state.isIOS && thi ...

  7. ASP.net EF动态映射实体

    1.配置EF与建立实体模型这里不做过多介绍.主要介绍如何动态映射实体模型 1.1.实现过程有很多种方式我们这里使用接口.然后扫描所有继承了该接口的实体类然后映射(也可以自行扩展使用特性) 首先我们新建 ...

  8. CentOS 7.6 部署zabbix 6.0 支持Kubernetes

    # 基础信息 系统版本: CentOS Linux release 7.6.1810 (Core) 内核版本: 4.19.0-9.el7.ucloud.x86_64 # 听说最新版的zabbix6.0 ...

  9. 面向对象继承---复习:包含继承关系,里氏转换,ArrayList与Hashtable集合,文件处理

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  10. vue框架4

    购物车案例 v-model进阶 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...