OpenKruise v1.3:新增自定义 Pod Probe 探针能力与大规模集群性能显著提升
简介: 在版本 v1.3 中,OpenKruise 提供了新的 CRD 资源 PodProbeMarker,改善了大规模集群的一些性能问题,Advanced DaemonSet 支持镜像预热,以及 CloneSet、WorkloadSpread、Advanced CronJob、SidecarSet 一些新的特性。
作者:赵明山(立衡)
云原生应用自动化管理套件、CNCF Sandbox 项目——OpenKruise,近期发布了 v1.3 版本。
OpenKruise 是针对 Kubernetes 的增强能力套件,聚焦于云原生应用的部署、升级、运维、稳定性防护等领域。
所有的功能都通过 CRD 等标准方式扩展,可以适用于 1.16 以上版本的任意 Kubernetes 集群。单条 helm 命令即可完成 Kruise 的一键部署,无需更多配置。
版本解析
在版本 v1.3 中,OpenKruise 提供了新的 CRD 资源 PodProbeMarker,改善了大规模集群的一些性能问题,Advanced DaemonSet 支持镜像预热,以及 CloneSet、WorkloadSpread、Advanced CronJob、SidecarSet 一些新的特性。
新增 CRD 和 Controller:PodProbeMarker
Kubernetes 提供了三种默认的 Pod 生命周期管理:
- Readiness Probe:用来判断业务容器是否已经准备好响应用户请求,如果检查失败,会将该 Pod 从 Service Endpoints 中剔除。
- Liveness Probe:用来判断容器的健康状态,如果检查失败,kubelet 将会重启该容器。
- Startup Probe:用来判断容器是否启动完成,如果定义了该 Probe,那么 Readiness Probe 与 Liveness Probe 将会在它成功之后再执行。
所以 Kubernetes 中提供的 Probe 能力都已经限定了特定的语义以及相关的行为。除此之外,其实还是存在自定义 Probe 语义以及相关行为的需求,例如:
- GameServer 定义 Idle Probe 用来判断该 Pod 当前是否存在游戏对局,如果没有,从成本优化的角度,可以将该 Pod 缩容掉。
- K8s Operator 定义 main-secondary Probe 来判断当前 Pod 的角色(main or secondary),升级的时候,可以优先升级 secondary,进而达到升级过程只有一次选主的行为,降低升级过程中服务抖动时间。
OpenKruise 提供了自定义 Probe 的能力,并将结果返回到 Pod Status 中,用户可以根据该结果决定后续的行为。
PodProbeMarker 配置如下:
apiVersion: apps.kruise.io/v1alpha1
kind: PodProbeMarker
metadata:
name: game-server-probe
namespace: ns
spec:
selector:
matchLabels:
app: game-server
probes:
- name: Idle
containerName: game-server
probe:
exec: /home/game/idle.sh
initialDelaySeconds: 10
timeoutSeconds: 3
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
markerPolicy:
- state: Succeeded
labels:
gameserver-idle: 'true'
annotations:
controller.kubernetes.io/pod-deletion-cost: '-10'
- state: Failed
labels:
gameserver-idle: 'false'
annotations:
controller.kubernetes.io/pod-deletion-cost: '10'
podConditionType: game.io/idle
PodProbeMarker 结果可以通过 Pod 对象查看:
apiVersion: v1
kind: Pod
metadata:
labels:
app: game-server
gameserver-idle: 'true'
annotations:
controller.kubernetes.io/pod-deletion-cost: '-10'
name: game-server-58cb9f5688-7sbd8
namespace: ns
spec:
...
status:
conditions:
# podConditionType
- type: game.io/idle
# Probe State 'Succeeded' indicates 'True', and 'Failed' indicates 'False'
status: "True"
lastProbeTime: "2022-09-09T07:13:04Z"
lastTransitionTime: "2022-09-09T07:13:04Z"
# If the probe fails to execute, the message is stderr
message: ""
性能优化:大规模集群性能显著提升
- #1026[1] 引入了延迟入队机制,大幅优化了在大规模应用集群下 kruise-manager 拉起时的 CloneSet 控制器工作队列堆积问题,在理想情况下初始化时间减少了 80% 以上。
- #1027[2] 优化 PodUnavailableBudget 控制器 Event Handler 逻辑,减少无关 Pod 入队数量。
- #1011[3] 通过缓存机制,优化了大规模集群下 Advanced DaemonSet 重复模拟 Pod 调度计算的 CPU、Memory 消耗。
- #1015[4] , #1068[5]大幅降低了大规模集群下的运行时内存消耗。弥补了 v1.1 版本中 Disable DeepCopy 的一些疏漏点,减少 expressions 类型 label selector 的转换消耗。
SidecarSet 支持注入特定的历史版本
SidecarSet 通过 ControllerRevision 记录了关于 containers、volumes、initContainers、imagePullSecrets 和 patchPodMetadata 等字段的历史版本,并允许用户在 Pod 创建时选择特定的历史版本进行注入。
基于这一特性,用户可以规避在 SidecarSet 灰度发布时,因 Deployment 等 Workload 扩容、升级等操作带来的 SidecarSet 发布风险。如果不选择注入版本,SidecarSet 将对重建 Pod 默认全都注入最新版本 Sidecar。
SidecarSet 相关 ControllerRevision 资源被放置在了与 Kruise-Manager 相同的命名空间中,用户可以使用以下命令来查看:
kubectl get controllerrvisions -n kruise-system -l kruise.io/sidecarset-name=your-sidecarset-name
此外,用户还可以通过 SidecarSet 的 status.latestRevision 字段看到当前版本对应的 ControllerRevision 名称,以方便自行记录。
1. 通过 ControllerRevision 名称指定注入的 Sidecar 版本
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: sidecarset
spec:
...
injectionStrategy:
revisionName: specific-controllerRevision-name
2. 通过自定义版本标识指定注入的 Sidecar 版本
用户可以通过在发版时,同时给 SidecarSet 打上 apps.kruise.io/sidecarset-custom-version=your-version-id 来标记每一个历史版本,SidecarSet 会将这个 label 向下带入到对应的 ControllerRevision 对象,以便用户进行筛选,并且允许用户在选择注入历史版本时,使用改 your-version-id 来进行描述。
假设用户只想灰度 10% 的 Pods 到 version-2,并且对于新创建的 Pod 希望都注入更加稳定的 version-1 版本来控制灰度风险:
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: sidecarset
labels:
apps.kruise.io/sidecarset-custom-version: version-2
spec:
...
updateStrategy:
partition: 90%
injectionStrategy:
customVersion: version-1
SidecarSet 支持注入 Pod Annotations
SidecarSet 支持注入 Pod Annotations,配置如下:
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
spec:
containers:
...
patchPodMetadata:
- annotations:
oom-score: '{"log-agent": 1}'
custom.example.com/sidecar-configuration: '{"command": "/home/admin/bin/start.sh", "log-level": "3"}'
patchPolicy: MergePatchJson
- annotations:
apps.kruise.io/container-launch-priority: Ordered
patchPolicy: Overwrite | Retain
patchPolicy 为注入的策略,如下:
- Retain:默认策略,如果 Pod 中存在 annotation[key]=value ,则保留 Pod 原有的 value。只有当 Pod 中不存在 annotation[key] 时,才注入 annotations[key]=value。
- Overwrite:与 Retain 对应,当 Pod 中存在 annotation[key]=value,将被强制覆盖为 value2。
- MergePatchJson:与 Overwrite 对应,annotations value为 json 字符串。如果 Pod 不存在该 annotations[key],则直接注入。如果存在,则进行 json value 合并。例如:Pod 中存在 annotations[oom-score]='{"main": 2}',注入后将 value json 合并为 annotations[oom-score]='{"log-agent": 1, "main": 2}'。
注意:patchPolicy 为 Overwrite和MergePatchJson 时,SidecarSet 原地升级 Sidecar Container 时,能够同步更新该 annotations。但是,如果只修改 annotations 则不能生效,只能搭配 Sidecar 容器镜像一起原地升级。
patchPolicy 为 Retain 时,SidecarSet 原地升级 Sidecar Container 时,将不会同步更新该 annotations。
上述配置后,SidecarSet 在注入 Sidecar Container时,会注入 Pod annotations,如下:
apiVersion: v1
kind: Pod
metadata:
annotations:
apps.kruise.io/container-launch-priority: Ordered
oom-score: '{"log-agent": 1, "main": 2}'
custom.example.com/sidecar-configuration: '{"command": "/home/admin/bin/start.sh", "log-level": "3"}'
name: test-pod
spec:
containers:
...
注意:SidecarSet 从权限、安全的考虑不应该注入或修改除 Sidecar Container 之外的 Pod 字段,所以如果想要使用该能力,首先需要配置 SidecarSet_PatchPodMetadata_WhiteList 白名单或通过如下方式关闭白名单校验:
> helm install kruise https://... --set featureGates="SidecarSetPatchPodMetadataDefaultsAllowed =true"
Advanced DaemonSet 支持镜像预热
如果你在安装或升级 Kruise 的时候启用了 PreDownloadImageForDaemonSetUpdate feature-gate,DaemonSet 控制器会自动在所有旧版本 pod 所在 node 节点上预热你正在灰度发布的新版本镜像。这对于应用发布加速很有帮助。
默认情况下 DaemonSet 每个新镜像预热时的并发度都是 1,也就是一个个节点拉镜像。
如果需要调整,你可以通过 apps.kruise.io/image-predownload-parallelism annotation 来设置并发度。
apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
annotations:
apps.kruise.io/image-predownload-parallelism: "10"
CloneSet 扩缩容与 PreparingDelete
默认情况下,CloneSet 将处于 PreparingDelete 状态的 Pod 视为正常,意味着这些 Pod 仍然被计算在 replicas 数量中。
在这种情况下:
- 如果你将 replicas 从 N 改为 N-1,当一个要删除的 Pod 还在 PreparingDelete 状态中时,你重新将 replicas 改为 N,CloneSet 会将这个 Pod 重新置为 Normal 状态。
- 如果你将 replicas 从 N 改为 N-1 的同时在 podsToDelete 中设置了一个 Pod,当这个 Pod 还在 PreparingDelete 状态中时,你重新将 replicas 改为 N,CloneSet 会等到这个 Pod 真正进入 terminating 之后再扩容一个 Pod 出来。
- 如果你在不改变 replicas 的时候指定删除一个 Pod,当这个 Pod 还在 PreparingDelete 状态中时,CloneSet 会等到这个 Pod 真正进入 terminating 之后再扩容一个 Pod 出来。
从 Kruise v1.3.0 版本开始,你可以在 CloneSet 中设置一个 apps.kruise.io/cloneset-scaling-exclude-preparing-delete: "true" 标签,它标志着这个 CloneSet 不会将 PreparingDelete 状态的 Pod 计算在 replicas 数量中。
在这种情况下:
- 如果你将 replicas 从 N 改为 N-1,当一个要删除的 Pod 还在 PreparingDelete 状态中时,你重新将 replicas 改为 N,CloneSet 会将这个 Pod 重新置为 Normal 状态。
- 如果你将 replicas 从 N 改为 N-1 的同时在 podsToDelete 中设置了一个 Pod,当这个 Pod 还在 PreparingDelete 状态中时,你重新将 replicas 改为 N,CloneSet 会立即创建一个新 Pod。
- 如果你在不改变 replicas 的时候指定删除一个 Pod,当这个 Pod 还在 PreparingDelete 状态中时,CloneSet 会立即创建一个新 Pod。
Advanced CronJob Time zones
默认情况下,所有 AdvancedCronJob schedule 调度时,都是基于 kruise-controller-manager 容器本地的时区所计算的。
不过,在 v1.3.0 版本中我们引入了 spec.timeZone 字段,你可以将它设置为任意合法时区的名字。例如,设置 spec.timeZone: "Asia/Shanghai" 则 Kruise 会根据国内的时区计算 schedule 任务触发时间。
Go 标准库中内置了时区数据库,作为在容器的系统环境中没有外置数据库时的 fallback 选择。
其他改动
你可以通过 Github release[6] 页面,来查看更多的改动以及它们的作者与提交记录。
社区参与
非常欢迎你通过 Github/Slack/钉钉/微信 等方式加入我们来参与 OpenKruise 开源社区。
你是否已经有一些希望与我们社区交流的内容呢?
可以在我们的社区双周会上分享你的声音,或通过以下渠道参与讨论:
- 加入社区 Slack channel[7] (English)
- 加入社区钉钉群:搜索群号 23330762 (Chinese)
- 加入社区微信群(新):添加用户 openkruise 并让机器人拉你入群 (Chinese)
参考链接
[1] #1026
https://github.com/openkruise/kruise/pull/1026
[2] #1027
https://github.com/openkruise/kruise/pull/1027
[3] #1011
https://github.com/openkruise/kruise/pull/1011
[4] #1015
https://github.com/openkruise/kruise/pull/1015
[5] #1068
https://github.com/openkruise/kruise/pull/1068
[6] Github release:
https://github.com/openkruise/kruise/releases
[7] Slack channel:
https://kubernetes.slack.com/channels/openkruise
戳此处,查看 OpenKruise 项目官方主页与文档!
OpenKruise v1.3:新增自定义 Pod Probe 探针能力与大规模集群性能显著提升的更多相关文章
- Kubeadm搭建高可用(k8s)Kubernetes v1.24.0集群
文章转载自:https://i4t.com/5451.html 背景 Kubernetes 1.24新特性 从kubelet中移除dockershim,自1.20版本被弃用之后,dockershim组 ...
- Centos7部署k8s[v1.16]高可用[keepalived]集群
实验目的 一般情况下,k8s集群中只有一台master和多台node,当master故障时,引发的事故后果可想而知. 故本文目的在于体现集群的高可用,即当集群中的一台master宕机后,k8s集群通过 ...
- kubeadm安装kubernetes V1.11.1 集群
之前测试了离线环境下使用二进制方法安装配置Kubernetes集群的方法,安装的过程中听说 kubeadm 安装配置集群更加方便,因此试着折腾了一下.安装过程中,也有一些坑,相对来说操作上要比二进制方 ...
- kubernetes集群之Pod说能不能让我体面的消亡呀?
kubernetes集群之Pod说能不能让我体面的消亡呀? 由于 Pod 所代表的是在集群中节点上运行的进程,当不再需要这些进程时允许其体面地终止. 1.如果 preStop 回调所需要的时间长于默认 ...
- 案例分享 生产环境逐步迁移至k8s集群 - pod注册到consul
#案例分享 生产环境逐步迁移至k8s集群 - pod注册到consul #项目背景 多套业务系统, 所有节点注册到consul集群,方便统一管理 使用consul的dns功能, 所有节点hostnam ...
- CDH5.16.1集群新增节点
如果是全新安装集群的话,可以参考<Ubuntu 16.04上搭建CDH5.16.1集群> 下面是集群新增节点步骤: 1.已经存在一个集群,有两个节点 192.168.100.19 hado ...
- kubernetes排错系列:(二)、运行很久的kubernetes集群,创建出来的pod都是pending状态
1.查看pod信息 # 查看pod 报错信息kubectl get pods发现pod的ip没有 生成,也没有分配到某个node节点 # 查看pod详细时间kubectl describe pods发 ...
- k8s集群StatefulSets的Pod调度查询丢失问题?
k8s集群StatefulSets的Pod调度查询丢失问题? 考点之简单介绍下StatefulSets 和 Deployment 之间有什么本质区别?特定场景该如何做出选择呢? 考点之你能辩证的说说看 ...
- Kubernetes学习笔记(二):部署托管的Pod -- 存活探针、ReplicationController、ReplicaSet、DaemonSet、Job、CronJob
存活探针 Kubernetes可以通过存活探针(liveness probe)检查容器是否存活.如果探测失败,Kubernetes将定期执行探针并重新启动容器. 官方文档请见:https://kube ...
- 企业运维实践-还不会部署高可用的kubernetes集群?使用kubeadm方式安装高可用k8s集群v1.23.7
关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 文章目录: 0x00 前言简述 ...
随机推荐
- 17_详解YUV
本文的主角是多媒体领域非常重要的一个概念:YUV. 简介 YUV,是一种颜色编码方法,跟RGB是同一个级别的概念,广泛应用于多媒体领域中. 也就是说,图像中每1个像素的颜色信息,除了可以用RGB的方式 ...
- 5、Azure Devops之Azure Test Plans篇
1.什么是Azure Test Plans Azure Test Plans是提供给团队测试人员,管理测试计划.测试套件.测试用例的部件.管理测试计划.测试用例的定义,包括请求类型定义.参数定义,执行 ...
- 3DCAT实时云渲染助力广府庙会元宇宙焕新亮相,开启线上奇趣之旅!
超 400 万人次打卡,商圈营业额逾 3.6 亿元,2023 年广府庙会于2023年2月11日圆满落幕. 活动期间,佳境美如画,融合VR.AR.虚拟直播等技术的广府庙会元宇宙焕新亮相,群众只需点击一个 ...
- 记录--你知道Vue中的Scoped css原理么?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 追忆Scoped 偶然想起了一次面试,二面整体都聊完了,该做的算法题都做出来了,该背的八股文也背的差不多了,面试官频频点头,似乎对我的基础 ...
- axios中设置了response:blol后,如何处理json对象
axios中文件下载 上传文件后台校验,若失败则下载文件 let loading = this.$common.loading("正在上传"); let form = new Fo ...
- Linux基础操作一
开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 开启虚拟机→Username:root→Password:"(注册时所创建的密码,比如"123 ...
- KingbaseESV8R6等待事件之LWLock buffer_mapping
等待事件含义 当会话将数据块与共享缓冲池中的缓冲区关联时,会发生此等待事件. 类似Oracle cbc闩锁的是一种Kingbase的轻量级锁lwlock,这个锁的名字在不同数据库版本中可能有所不同,我 ...
- UE4Gameplay定时器
参考 定时器在全局定时器管理器(FTimerManager类)中管理,对于每个实例Uobject和场景都会有全局定时器管理器,一般来说通过SetTimer和SetTimerForNextTick来设置 ...
- CSS+HTML+flexible.js+rem实现屏幕缩放适配概念原理解释
首先理解几个概念: (1)屏幕尺寸:屏幕对角线的长度,一般用英寸表示,1英寸=2.54cm. (2)dp((或者叫dip):设备独立像素,也就是设备屏幕上多少个点. (3)dpi:印刷行业术语,像素密 ...
- C++ 线程安全的队列
无界队列 #include<queue> #include<mutex> #include<condition_variable> #include<opti ...