关于云原生:如何基于-OpenKruise-打破原生-Kubernetes-中的容器运行时操作局限

34次阅读

共计 5874 个字符,预计需要花费 15 分钟才能阅读完成。

作者:王思宇,阿里云技术专家,OpenKruise 社区负责人

通常状况下,人们只能应用一般旧数据作为 Kubernetes 中最小的操作单元。一些公司在他们的集群中入侵了 Kubelet 的代码,以便他们能够对容器做更多的事件。然而,为运行时扩大操作的确是一种谬误的办法,因为它不利于开源和社区的单干。当初,云原生计算基金会沙箱我的项目之一 OpenKruise 提供了高级性能,能够在每个原始 Kubernetes 集群中操作容器运行时。在本次演讲中,咱们将介绍 OpenKruise 中一些性能的用法,以及它如何与 Kubelet 和 CRI 单干。

本次分享次要分为以下几个局部,首先咱们介绍在 Kubernetes 中,针对于对容器 runtime 的操作限度有哪些,也就是说咱们在 Kubernetes 中,它的机制限度了咱们哪些操作,其实是对 controller runtime 是做不到的;第二点是 OpenKruise 是怎么拓展对 controller runtime 的这些操作;第三点是咱们简略做一个 demo,咱们如何通过 OpenKruise 来实现这些操作的;第四点是简略介绍一下咱们后续的一些布局。

Kubernetes 中针对容器运行时的操作有哪些限度?

Kubernetes 中的容器运行时

如上图所示,这是一个 Kubernetes 的根本构造,它的构造在每个节点 (Node) 上,其实是 Kubelet 在 API server 外面收到它的。比方 Pod 的变动,当 Kubelet 收到一个 Pod 创立之后,通过 CRI(Container Runtime Interface), CNI 以及相似的公共接口(例如 CSI)来调用底层真正的接口实现者去实现操作。对于容器运行时来说,是通过 CRI 接口调用底层真正的 Runtime 运行时来实现对容器的创立和启动镜像拉取这些操作。

其中 CRI 是 Kubernetes1.5 之后退出的一个新性能,由协定缓冲区和 gRPC API 组成,提供了一个明确定义的形象层,它的目标是对于 Kubelet 能屏蔽底下 Runtime 实现的细节而只显示所需的接口。
(https://github.com/kubernetes…)

在 Kubernetes1.5 之前,Kubelet 与 Docker 是相耦合的,Kubelet 其实是引入了 Docker 的 client,由它们间接对 Docker 操作。有了 CRI,对于 Kubelet 来说就不必关怀底层真正的 Runtime 实现是什么,而只须要调用这层接口,接口背地的实现可能是 Containerd-d,可能是 CRI-O,也可能是 Docker。

CRI 的职责是对容器运行时以及对镜像做相干的治理,包含对容器的启停操作,对 Sandbox 容器的操作,容器 States 的数据采集,以及镜像的拉取和查问等操作。因而,CRI 提供了比较完善的容器接口,如下图。

Kubernetes 中容器运行时的操作限度

Kubernetes API 并没有提供对容器运行时的接口操作,它惟一提供的是对 v1 版本的 Pod 操作(Pod API CRUD,Pod Subresources API)。除了 Pod 创立和更新之外,惟一能跟 Runtime 做比拟绝对应操作的是 Exec subresource 和 Log subresource。

Kubernetes 的 API 层面限度了用户只能创立或删除 Pod,除此之外,外面的容器只能做 Exec,Log 这样的操作。在 Kubernetes 接口层面,用户无奈进行比方拉取镜像、重启容器等操作。

那有没有可能去拓展这个 API 呢?

咱们发现 Kubelet 目前没有提供任何 hook 解决 plugin 的这个操作,来让外层能去动静拓展 Kubelet 所做的事件。(Kubelet 的接口是不提供这样的插件机制的)那是否能够退出一个与 Kubelet 相似的新组件,能够连贯到 CRI API,来拓展 Kubernetes 容器进行时的操作呢?

咱们同样会调用 CRI 这一层,比方它能够拉镜像,能够重启容器,它的下层也能够接管一个对于 Kubernetes API 上定义的一个 CRD 资源,这个 CRD 资源定义了让用户可能申明对 CRI 接口做一些操作。比方它能够定义指定用户去拉镜像,去重启容器,能够做更多的事件。

这种形式是咱们能想到的,对于这个 Kubernetes 容器运行时 operations 的拓展思路。

OpenKruise 是什么?

OpenKruise 概念

Openkruise 是 Kubernetes 的一个拓展套件,它补救了 Kubernetes 很多性能有余,例如对于利用工作负载(利用部署公布相干性能)的有余,对于 container runtime 操作的有余等。它能够配合原生 Kubernetes 应用,并为治理利用容器、sidecar、镜像散发等方面提供更加弱小和高效的能力。

2020 年 11 月,OpenKruise 作为 Sandbox 我的项目退出 CNCF。

Openkruise 自身并不是一个 PasS 平台。但 PasS 平台能够通过利用 Openkruise 提供的拓展能力更好的治理,运维云原生的利用。感兴趣的敌人能够通过以下网址理解更多 OpenKruise 相干信息。

Github:
https://github.com/openkruise…

WebSite:
https://openkruise.io

OpenKruise 的性能

OpenKruise 是基于 CRD 的拓展,其性能大抵可分为五局部:
(1)利用工作负载:包含针对无状态利用,有状态利用的灰度公布、流量管制、它的原地降级等相干性能;
(2)Sidecar 容器治理:提供更多加强的独立定义以及独立部署;
(3)利用多分区治理(Multi-domain management):一个利用如果要部署在多个分区,会进行打散和分片的治理。
(4)利用可用性防护:爱护云原生利用在 Kubernetes 上运行时的高可用性;
(5)拓展加强操作:通过这种形式来实现对 container runtime(运行时)加强的操作能力。其中拓展加强操作是本文次要介绍的性能,后续咱们会具体开展。


OpenKruise 性能图

OpenKruise 的架构

如图所示,OpenKruise 次要分成核心端(Kruise-manager)和节点端(Node)两个组件。核心端的 Kruise-manager 蕴含 controllers 和 webhooks,通过 Kruise-manager 核心端的角色和每个节点上 kruise-daemon 性能联合,能够实现很多 Kubernetes 自身不提供的能力。Kruise-daemon 是用来防止对 Kubelet 做革新,通过拓展的形式对 CRI runtime 进行操作。

Runtime 的拓展性能

Runtime 有三个外围拓展性能。

原地降级性能

原地降级是一种能够防止删除、新建 Pod 的降级镜像能力。

如上图所示:第一局部并不是间接通过 kruise-daemon 拓展,而是利用 Kubelet 的原生机制,叫做原地降级。

如何了解原地降级?咱们举一个简略的例子:比方原来有一个 pod-a,此时的 pod-a 是通过 deployment 的或者 Openkruise 的 cloneset 扩容进去的。如果咱们想要降级 app 容器的镜像版本,比方从 Fv1 降级到 Fv2,失常状况下大家应用 development 部署是采纳 Recreatte Update 也就是重建 Pod 降级,重建实现后咱们会看到 Pod 的名字,Pod UID,(镜像也会降级为 V2)很大水平上都会产生扭转。

再看前面两者,前者 Pod 的名字和 UID 肯定会发生变化,因为它曾经不是同一个 Pod 的对象了。绝对于咱们这次介绍的原地降级,Pod 的对象其实还是原来的对象,Pod 的名字,Pod UID 都不变。其次,Pod 所在节点的 IP 也都不变,惟一变动的是镜像从 v1 级到了 v2,因为 Pod 节点没有产生任何变动,Pod 对象就不须要通过调度器从新调度,IP 调配,volume 调配,挂载这些耗时也都打消掉了,因而一个很显著益处就是节俭了调度的耗时。

大家都晓得,当利用镜像从 v1 升到 v2 的过程中,可能只是最顶上的 layers 产生了变动,底下绝大部分的这个 base 镜像,公共 layers 是没有发生变化的。

当咱们在同一个节点下面做原地降级的时候,能够复用原有 v1 镜像的大部分 layers,只用下载小局部的 layers 镜像。

在降级 app 容器的过程中,Pod 中的其余容器。如 sidecar 容器,是始终失常运行的,没有受到影响。反过来说,当咱们降级 sidecar 容器时,容器也是失常运行的。这样能够很大水平上防止在降级一个旁路(比方运维)容器的过程中,也要对业务能力造成影响。

1.1 劣势

• 节俭操作耗时,包含:Pod 调度、IP 调配、volume 调配、挂载等;
• 复用大部分镜像层;
• 当一个容器进行降级时,不会对 Pod 中的其它容器造成影响;

1.2 工作原理

原地降级的原理能够简略了解为 Kubelet 在创立每个容器时,会为容器计算一个 hash 值,当下层批改了比方 app 容器的 image 之后,Kubelet 就认为容器的 hash 值产生了变动。当 Kubelet 发现 Pod spec 中 app 容器的 hash 值和理论的,如 container d 对应的 hash 值不统一时,就会把旧的 app 容器停掉,用新的镜像再重建新的 app 容器,从而实现容器的原地降级的能力。

### 容器重启性能

容器重启的性能是很多业务,包含运维平台都很依赖的性能。大家可能会问,在 Kubernetes 中,一个 Pod 既然是无状态的,那么想重启时就间接删除 Pod,再新建一个 Pod 不就能够了吗?

这是当然能够的,但对于业务来说可能还存在很多 debug 场景,并不只是重建一个新的 Pod 就能够,而是要从原地把容器进行重启,相当于把外面的业务过程重启。比方想保留一些 volume 中的数据,一些网络、堆栈信息等,这些场景都导致业务须要有 Kubernetes Pod 的容器原地重启能力。

Kubernetes 原生是不具备容器重启能力的,对于 Kubernetes 来说,如果想要重启容器,只能手动进入容器,把容器里的利用过程杀掉,这时当容器退出,Kubernetes 会再把它拉起。当然这种形式其实都比拟 hack 的这么一种形式,Openkruise 所提供的容器重启能力对于 API 来说,只须要创立一个 CR。

CR 里写的货色很明确,name spacesl 只需定义跟 pod 在同一个 name spacesl 里,其中 name 是自定义的名字,通过指定须要重启的 Pod 是哪个,须要重启 pod 进去哪些 containers,当定义了这些信息之后,提交 CR,当 kruise 收到 CR,kruise – manager 会先通过 webhooks,对它注入一些信息,接下来 kruise-daemon 拿到 CR 会依据 CR 中定义的信息(比方会找到对应 Pod 的容器)执行 preStop hook,再通过 CRI 接口,通过 EXTC 执行 preStop,当 preStop 执行实现之后再调用这个 CRI 的 stop。

其实这个进行形式和自身 Kubelet 在删除 Pod 时对容器的进行形式是统一的。当 kruise-daemon 对旧容器,比方对零号的 app(app_0)容器停掉之后,Kubelet 感知到 app 容器停掉了,接着就会新建一个 F1 容器并把它拉起,通过这种形式来实现优雅的容器原地重启能力。

代码示例:

apiVersion: apps.kruise.io/v1alpha1
kind: ContainerRecreateRequest
metadata:
namespace: pod-namespace
name: xxx
spec:
podName: pod-name
containers:
- name: app
strategy:
# ...
activeDeadlineSeconds: 300
ttlSecondsAfterFinished: 1800
status:
containerRecreateStates:
- name: app
phase: Succeeded
phase: Completed
# ..

镜像预热性能

提前在节点上包含新建的 Node 上预热,就能够大幅度缩小后续 Pod 扩容的耗时。

从上图咱们能够看到,对于下层用户来说 Openkruise 提供了一个 CRD 叫 ImagePullJob,用户能够定义须要预热哪个镜像,也能够选择性的配置 selector(selector 能够是节点的标签选择器也能够依据 Pod 进行抉择),以上都能够在 Pod 所在节点上进行预热。

当用户建设 ImagePullJob 后,对于 kruise 外部逻辑来说,kruise 会把 ImagePullJob 拆分到每个 node 对应 node image 的 CR 上,当同步下来后,节点上的 kruise-daemon 会拿到这个节点所对应 node image 的 CR,在节点上预热 CR 中定义的多个镜像。

换句话说,每个节点所对应的 node image 中的镜像列表,其实就示意了下层所有 ImagePullJob 指定在这个节点上要拉取镜像选集。kruise-daemon 底层拿到 node image 后,相当于也是调用 CRI 的 Pod image 接口来实现镜像的预热。

代码示例:

apiVersion: apps.kruise.io/v1alpha1
kind: ImagePullJob
metadata:
name: test-job
spec:
image: nginx:latest
parallelism: 10
selector:
# ...
podSelector:
# ...
completionPolicy:
# ...

将来我的项目布局

2021 年 12 月,OpenKruise 实现了首个正式版本 v1.0 的公布,使云原生利用自动化达到新的顶峰。OpenKruise 从 2019 年公布 0.1 版本到当初曾经有 2 年多的工夫,已有超过 70 位贡献者参加奉献,star 数量曾经超过 3000。2022,咱们将推动 OpenKruise 成为 CNCF Incubation 我的项目,推动云原生利用自动化畛域进一步成熟。

应用用户:
• 阿里巴巴团体, 蚂蚁团体, 斗鱼 TV, 申通, Boss 直聘
• 杭银生产, 万翼科技, 多点, Bringg, 佐疆科技
• Lyft, 携程, 享住智慧, VIPKID, 掌门 1 对 1
• 小红书, 比心, 永辉科技核心, 跟谁学, 哈啰出行
• Spectro Cloud, 艾佳生存, Arkane Systems, 滴普科技, 火花思维
• OPPO, 苏宁, 欢聚时代, 汇量科技, 深圳凤凰木网络有限公司
• 小米, 网易, 美团金融, Shopee, LinkedIn

正文完
 0