包虫病

首页 » 常识 » 诊断 » 使用OpenKruise原地升级P
TUhjnbcbe - 2021/5/24 20:42:00

导读:

OpenKruise是阿里云开源的大规模应用自动化管理引擎,在功能上对标了Kubernetes原生的Deployment/StatefulSet等控制器,但OpenKruise提供了更多的增强功能如:优雅原地升级、发布优先级/打散策略、多可用区workload抽象管理、统一sidecar容器注入管理等,都是经历了阿里巴巴超大规模应用场景打磨出的核心能力。这些feature帮助我们应对更加多样化的部署环境和需求、为集群维护者和应用开发者带来更加灵活的部署发布组合策略。

目前,Kruise提供了以下workload控制器:

CloneSet:提供了更加高效、确定可控的应用管理和部署能力,支持优雅原地升级、指定删除、发布顺序可配置、并行/灰度发布等丰富的策略,可以满足更多样化的应用场景。

AdvancedStatefulSet:基于原生StatefulSet之上的增强版本,默认行为与原生完全一致,在此之外提供了原地升级、并行发布(最大不可用)、发布暂停等功能。

SidecarSet:对sidecar容器做统一管理,在满足selector条件的Pod中注入指定的sidecar容器。

UnitedDeployment:通过多个subsetworkload将应用部署到多个可用区。

BroadcastJob:配置一个job,在集群中所有满足条件的Node上都跑一个Pod任务。

AdvancedDaemonSet:基于原生DaemonSet之上的增强版本,默认行为与原生一致,在此之外提供了灰度分批、按Nodelabel选择、暂停、热升级等发布策略。

本文将使用OpenKruise的CloneSet原地升级功能来更新pod资源。

Deployment

使用Deployment部署时,那么升级过程中Deployment会触发新版本ReplicaSet创建Pod,并删除旧版本Pod。在本次升级过程中,原Pod对象被删除,一个新Pod对象被创建。新Pod被调度到另一个Node上,分配到一个新的IP,并把foo、bar两个容器在这个Node上重新拉取镜像、启动容器。

StatefulSet

使用StatefulSet部署,那么升级过程中StatefulSet会先删除旧Pod对象,等删除完成后用同样的名字在创建一个新的Pod对象。值得注意的是,尽管新旧两个Pod名字都叫pod-0,但其实是两个完全不同的Pod对象(uid也变了)。StatefulSet等到原先的pod-0对象完全从Kubernetes集群中被删除后,才会提交创建一个新的pod-0对象。而这个新的Pod也会被重新调度、分配IP、拉镜像、启动容器。

原地升级

所谓原地升级模式,就是在应用升级过程中避免将整个Pod对象删除、新建,而是基于原有的Pod对象升级其中某一个或多个容器的镜像版本。在原地升级的过程中,我们仅仅更新了原Pod对象中foo容器的image字段来触发foo容器升级到新版本。而不管是Pod对象,还是Node、IP都没有发生变化,甚至foo容器升级的过程中bar容器还一直处于运行状态。这种只更新Pod中某一个或多个容器版本、而不影响整个Pod对象、其余容器的升级方式,被我们称为Kubernetes中的原地升级。

原地升级的收益

首先,这种原地升级的模式极大地提升了应用发布的效率,根据非完全统计数据,在阿里环境下原地升级至少比完全重建升级提升了80%以上的发布速度。这其实很容易理解,原地升级为发布效率带来了以下优化点:

节省了调度的耗时,Pod的位置、资源都不发生变化;

节省了分配网络的耗时,Pod还使用原有的IP;

节省了分配、挂载远程盘的耗时,Pod还使用原有的PV(且都是已经在Node上挂载好的);

节省了大部分拉取镜像的耗时,因为Node上已经存在了应用的旧镜像,当拉取新版本镜像时只需要下载很少的几层layer。

其次,当我们升级Pod中一些sidecar容器(如采集日志、监控等)时,其实并不希望干扰到业务容器的运行。但面对这种场景,Deployment或StatefulSet的升级都会将整个Pod重建,势必会对业务造成一定的影响。而容器级别的原地升级变动的范围非常可控,只会将需要升级的容器做重建,其余容器包括网络、挂载盘都不会受到影响。

最后,原地升级也为我们带来了集群的稳定性和确定性。当一个Kubernetes集群中大量应用触发重建Pod升级时,可能造成大规模的Pod飘移,以及对Node上一些低优先级的任务Pod造成反复的抢占迁移。这些大规模的Pod重建,本身会对apiserver、scheduler、网络/磁盘分配等中心组件造成较大的压力,而这些组件的延迟也会给Pod重建带来恶性循环。而采用原地升级后,整个升级过程只会涉及到controller对Pod对象的更新操作和kubelet重建对应的容器。

安装OpenKruise

#kubectlgetnodeNAMESTATUSROLESAGEVERSIONk8s-master-node1Readymaster4h24mv1.19.3k8s-master-node2Readymaster4h23mv1.19.3k8s-master-node3Readymaster4h22mv1.19.3

k8s-worker-node1Readyworker4h22mv1.19.3

k8s-worker-node2Readyworker4h22mv1.19.3

helminstallkruise

1
查看完整版本: 使用OpenKruise原地升级P