千家信息网

基于Kubernetes和OpenKruise的方法是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要讲解了"基于Kubernetes和OpenKruise的方法是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"基于Kubernetes和
千家信息网最后更新 2026年11月01日基于Kubernetes和OpenKruise的方法是什么

这篇文章主要讲解了"基于Kubernetes和OpenKruise的方法是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"基于Kubernetes和OpenKruise的方法是什么"吧!

1. 对于可变基础设施的思考

1.1 kubernetes中的可变与不可变基础设施

在云原生逐渐盛行的现在,不可变基础设施的理念已经逐渐深入人心。不可变基础设施最早是由Chad Fowler于2013年提出的,其核心思想为任何基础设施的实例一旦创建之后变成为只读状态,如需要修改和升级,则使用新的实例进行替换。这一理念的指导下,实现了运行实例的一致,因此在提升发布效率、弹性伸缩、升级回滚方面体现出了无与伦比的优势。

kubernetes是不可变基础设施理念的一个极佳实践平台。Pod作为k8s的最小单元,承担了应用实例这一角色。通过ReplicaSet从而对Pod的副本数进行控制,从而实现Pod的弹性伸缩。而进行更新时,Deployment通过控制两个ReplicaSet的副本数此消彼长,从而进行实例的整体替换,实现升级和回滚操作。

我们进一步思考,我们是否需要将Pod作为一个完全不可变的基础设施实例呢?其实在kubernetes本身,已经提供了一个替换image的功能,来实现Pod不变的情况下,通过更换image字段,实现Container的替换。这样的优势在于无需重新创建Pod,即可实现升级,直接的优势在于免去了重新调度等的时间,使得容器可以快速启动。

从这个思路延伸开来,那么我们其实可以将Pod和Container分为两层来看。将Container作为不可变的基础设施,确保应用实例的完整替换;而将Pod看为可变的基础设施,可以进行动态的改变,亦即可变层。

1.2 关于升级变化的分析

对于应用的升级变化种类,我们来进行一下分类讨论,将其分为以下几类:

升级变化类型说明
规格的变化cpu、内存等资源使用量的修改
配置的变化环境变量、配置文件等的修改
镜像的变化代码修改后镜像更新
健康检查的变化readinessProbe、livenessProbe配置的修改
其他变化调度域、标签修改等其他修改

(滑动查看完整表格)

针对不同的变化类型,我们做过一次抽样调查统计,可以看到下图的一个统计结果。

在一次升级变化中如果含有多个变化,则统计为多次。

可以看到支持镜像的替换可以覆盖一半左右的的升级变化,但是仍然有相当多的情况下导致不得不重新创建Pod。这点来说,不是特别友好。所以我们做了一个设计,将对于Pod的变化分为了三种Dynamic,Rebuild,Static三种。

修改类型修改类型说明修改举例对应变化类型
Dynamic 动态修改Pod不变,容器无需重建修改了健康检查端口健康检查的变化
Rebuild 原地更新Pod不变,容器需要重新创建更新了镜像、配置文件或者环境变量镜像的变化,配置的变化
Static 静态修改Pod需要重新创建修改了容器规格规格的变化

(滑动查看完整表格)

这样动态修改和原地更新的方式可以覆盖90%以上的升级变化。在Pod不变的情况下带来的收益也是显而易见的。

  1. 减少了调度、网络创建等的时间。

  2. 由于同一个应用的镜像大部分层都是复用的,大大缩短了镜像拉取的时间。

  3. 资源锁定,防止在集群资源紧缺时由于出让资源重新创建进入调度后,导致资源被其他业务抢占而无法运行。

  4. IP不变,对于很多有状态的服务十分友好。

2. Kubernetes与OpenKruise的定制

2.1 kubernetes的定制

那么如何来实现Dynamic和Rebuild更新呢?这里需要对kubernetes进行一下定制。

动态修改定制

liveness和readiness的动态修改支持相对来说较为简单,主要修改点在与prober_manager中增加了UpdatePod函数,用以判断当liveness或者readiness的配置改变时,停止原先的worker,重新启动新的worker。而后将UpdatePod嵌入到kubelet的HandlePodUpdates的流程中即可。

func (m *manager) UpdatePod(pod *v1.Pod) {  m.workerLock.Lock()  defer m.workerLock.Unlock()
key := probeKey{podUID: pod.UID} for _, c := range pod.Spec.Containers { key.containerName = c.Name { key.probeType = readiness worker, ok := m.workers[key] if ok { if c.ReadinessProbe == nil { //readiness置空了,原worker停止 worker.stop() } else if !reflect.DeepEqual(*worker.spec, *c.ReadinessProbe) { //readiness配置改变了,原worker停止 worker.stop() } } if c.ReadinessProbe != nil { if !ok || (ok && !reflect.DeepEqual(*worker.spec, *c.ReadinessProbe)) { //readiness配置改变了,启动新的worker w := newWorker(m, readiness, pod, c) m.workers[key] = w go w.run() } } } { //liveness与readiness相似 ...... } }}

原地更新定制

kubernetes原生支持了image的修改,对于env和volume的修改是未做支持的。因此我们对env和volume也支持了修改功能,以便其可以进行环境变量和配置文件的替换。这里利用了一个小技巧,就是我们在增加了一个ExcludedHash,用于计算Container内,包含env,volume在内的各项配置。

func HashContainerExcluded(container *v1.Container) uint64 {  copyContainer := container.DeepCopy()  copyContainer.Resources = v1.ResourceRequirements{}  copyContainer.LivenessProbe = &v1.Probe{}  copyContainer.ReadinessProbe = &v1.Probe{}  hash := fnv.New32a()  hashutil.DeepHashObject(hash, copyContainer)  return uint64(hash.Sum32())}

这样当env,volume或者image发生变化时,就可以直接感知到。在SyncPod时,用于在计算computePodActions时,发现容器的相关配置发生了变化,则将该容器进行Rebuild。

func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *kubecontainer.PodStatus) podActions {  ......  for idx, container := range pod.Spec.Containers {    ......    if expectedHash, actualHash, changed := containerExcludedChanged(&container, containerStatus); changed {        // 当env,volume或者image更换时,则重建该容器。      reason = fmt.Sprintf("Container spec exclude resources hash changed (%d vs %d).", actualHash, expectedHash)            restart = true    }    ......    message := reason    if restart {      //将该容器加入到重建的列表中      message = fmt.Sprintf("%s. Container will be killed and recreated.", message)      changes.ContainersToStart = append(changes.ContainersToStart, idx)    }......  return changes}

Pod的生命周期

在Pod从调度完成到创建Running中,会有一个ContaienrCreating的状态用以标识容器在创建中。而原生中当image替换时,先前的一个容器销毁,后一个容器创建过程中,Pod状态会一直处于Running,容易有错误流量导入,用户也无法识别此时容器的状态。

因此我们为原地更新,在ContainerStatus里增加了ContaienrRebuilding的状态,同时在容器创建成功前Pod的Ready Condition置为False,以便表达容器整在重建中,应用在此期间不可用。利用此标识,可以在此期间方便识别Pod状态、隔断流量。

2.2 OpenKruise的定制

OpenKruise是阿里开源的一个项目,提供了一套在Kubernetes核心控制器之外的扩展 workload 管理和实现。其中Advanced StatefulSet,基于原生 StatefulSet 之上的增强版本,默认行为与原生完全一致,在此之外提供了原地升级、并行发布(最大不可用)、发布暂停等功能。

Advanced StatefulSet中的原地升级即与本文中的Rebuild一致,但是原生只支持替换镜像。因此我们在OpenKruise的基础上进行了定制,使其不仅可以支持image的原地更新,也可以支持当env、volume的原地更新以及livenessProbe、readinessProbe的动态更新。这个主要在shouldDoInPlaceUpdate函数中进行一下判断即可。这里就不再做代码展示了。

另外,还有个小坑,就是在pod里为了标识不同的版本,加入了controller-revision-hash值。

[root@xxx ~]# kubectl get pod -n predictor  -o yaml predictor-0 apiVersion: v1kind: Podmetadata:  labels:    controller-revision-hash: predictor-85f9455f6...

一般来说,该值应该只使用hash值作为value就可以了,但是OpenKruise中采用了{sts-name}+{hash}的方式,这带来的一个小问题就是sts-name就要因为label value的长度受到限制了。

感谢各位的阅读,以上就是"基于Kubernetes和OpenKruise的方法是什么"的内容了,经过本文的学习后,相信大家对基于Kubernetes和OpenKruise的方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

变化 容器 升级 更新 配置 基础 可变 基础设施 设施 原地 镜像 支持 实例 状态 动态 类型 资源 应用 调度 方法 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网和科技创新 金融科技创新监管互联网金融 互联网络科技有限公司 互联网科技论文 苏州大垚互联网科技 海南购全球互联网科技 科技大学互联网专业好不好 蓝色互联网科技 小米互联网科技园设置 互联网科技公司营业执照怎么办理 山东有哪些互联网科技公司 山东子淼互联网科技有限公司 皮皮虾互联网科技有限公司 杭州披云加互联网科技有限公司 全球科技与互联网公司市值变化 互联网时代科技型公司的机会 杭州科技互联网公司有哪些 河南商务圈互联网科技有限公司 现代科技的标志之一的互联网 科技发展第三阶段互联网时代 宜安科技 互联网金融 善班互联网科技有限公司 美国互联网黑科技 蓝色互联网科技 互联网为啥属于高科技 智腾互联网科技有限公司 互联网科技公司实习生 洛阳昕诺飞互联网科技有限公司 中国新注册互联网科技 杭州科技互联网公司有哪些
0