背景描述我们在部署容器的过程中遇到了以下问题:对于随deployment部署的应用pod,由于频繁更改id和服务重启,监控变得难以维护。这里只是以监控为起点。其实有很多应用需要强绑定id。Statefulset可以解决上面的问题,但是引入了一个新的问题。为了维护有状态的应用程序,statefulset本身以严格的顺序启动所有应用程序Pod,即串行启动。对于大型应用pod,启动时间太长,难以忍受。为了解决以上问题,我们在容器平台中引入了openkruise。openkruise介绍项目地址:https://github.com/openkruise/kruise详细说明可以参考这篇文章:https://yq.aliyun.com/articles/706442从目前github上的文档来看,OpenKruise目前支持五个改进的控制器:CloneSet:CloneSet是一个主要专注于管理无状态应用程序的工作负载。它提供了更高效、确定性和受控部署的全部功能,例如就地更新、指定的Pod删除、可配置的优先级/分散更新、预更新/更新后挂钩。AdvancedStatefulSet:默认StatefulSet的增强版本,具有额外的功能,例如inplace-update、pause和MaxUnavailable。SidecarSet:一个控制器,它根据选择器将Sidecar容器注入Pod规范,并且还能够升级容器。UnitedDeployment:这个控制器通过使用多个工作负载来管理分布在多个故障域中的应用程序Pod。BroadcastJob:在集群中的所有节点上运行Pod直至完成的作业。UnitedDeployment是基于StatefulSet的更高层次的抽象。通过一个资源描述,可以管理多个StatefulSet实例组,实现多实例组灰度发布和滚动升级。BroadcastJob实际上以DaemonSetOne-timeJob的形式运行在所有节点上,SidercarSet用于Sidercar的注入和管理。而我们要用的就是它的AdvancedStatefulSet的特性。AdvancedStatefulSet更详细的描述如下:在kubernetes官方的statefulSet上进行了功能扩展,更新策略从只支持recreate扩展为同时支持recreate和rollingupdate。rollingupdate也支持两种策略,一种是InPlaceIfPossible,一种是InPlaceOnly。InPlaceIfPossible会尽可能保证应用就地升级(只支持镜像升级,如果修改了yaml中的其他配置项,不保证);InPlaceOnly会保证应用必须就地升级,但它也只支持镜像升级。如果修改了yaml中的其他配置项,会直接抛出异常。另外,nativeStatefulSet只能串行启动,而AdvancedStatefulSet可以并行启动。部署openkruise的官方安装文档可以直接参考这里:https://github.com/openkruise/kruise/tree/master/docs/tutorial我简单写下安装步骤:wgethttps://github.com/openkruise/kruise/releases/download/v0.4.0/kruise-chart.tgztarxfkruise-chart.tgzcdkruisehelminstallopenkruise./-nkube-system目前openkruise已经更新到v0.5.0。也可以直接通过阿里云的应用目录安装。说一下更详细的安装过程:1.获取helm包helmrepoaddincubatorhttp://aliacs-k8s-cn-beijing.oss-cn-beijing.aliyuncs.com/app/charts-incubator/helmsearchrepoack-kruisehelmfetchincubator/ack-kruisetarxfack-kruise-0.5.0.tgzcdack-kruise修改values.yml文件如下:#Defaultvaluesforkruise.revisionHistoryLimit:3manager:#settingsforlogprintlog:#loglevelforkruise-managerlevel:"4"#imagesettingsimage:#repositoryforkruise-managerimagerepository:hub.example。com/library/kruise-manager#tagforkruise-managerimagetag:v0.5.0#resourcesofkruise-managercontainerresources:limits:cpu:500mmemory:1Girequests:cpu:500mmemory:1Gimetrics:addr:localhostport:8080custom_resource_enable:StatefulSet其实这里改了两处:image:默认是dockerhub上的地址,我改成私有镜像仓库custom_resource_enable:用来指定开启哪些资源,不指定的话openkrui支持的全部五种资源se会被开启,我这里只使用StatefulSet,所以这里只开启安装这个资源后,执行安装操作:helminstallack-kruise-nkube-system./安装完成后会生成如下五个crd:#kubectlgetcrds|grepkruisebroadcastjobs。apps.kruise.io2020-04-26T10:29:28Zclonesets.apps.kruise.io2020-04-26T10:29:28Zsidecarsets.apps.kruise.io2020-04-26T10:29:28Zstatefulsets.apps.kruise.io2020-04-26T10:29:28Zuniteddeployments.apps.kruise.io2020-04-26T10:29:28Z还会创建一个kruise-system命名空间,并在其中生成一个pod:#kubectlgetpods-nkruise-systemNAMEREADYSTATUSRESTARTSAGEkruise-controller-manager-01/1Running055m验证statefulset资源的webhook是否正常创建:#kubectlgetmutatingwebhookconfiguration-oyamlapiVersion:v1items:-apiVersion:admissionregistration.k8s.io/v1kind:MutatingWebhookConfigurationmetadata:creationTimestamp:"2020-04-26T10:29:28Z"generation:3name:kruise-mutating-webhook-configurationresourceVersion:"622944921"selfLink:/apis/admissionregistrationk8s。io/v1/mutatingwebhookconfigurations/kruise-mutating-webhook-configurationuid:303a7b7f-3a62-49d7-8ef6-082ea288eeb2webhooks:-admissionReviewVersions:-v1beta1clientConfig:caBundle:systemxxxxxservice:name:kruise-webhook-server-namespacek服务:/mutating-create-update-有状态的放端口:443failurePolicy:FailmatchPolicy:确切名称:mutating-create-update-statefulset.kruise.ionamespaceSelector:matchExpressions:-key:control-planeoperator:DoesNotExistobjectSelector:{}reinvocationPolicy:Neverrules:-apiGroups:-apps.kruise.ioapiVersions1:操作:-v1-CREATE-UPDATEresources:-statefulsetsscope:'*'sideEffects:UnknowntimeoutSeconds:30...还要确保关闭其他未使用的相关mutatingwebhooks。在实际测试中,SidecarSet资源的mutatingwebhook可能会导致创建pod失败。这些webhooks本质上就是kubernetes的admissioncontrol。只要安装了,即使不使用,在进行相关操作时,也需要被所有的adminssioncontrol检测到。如果admissioncontrol本身有问题,就会导致请求无法响应的状态。同时,这些webhook类型的adminssioncontrol也会拖慢响应速度。使用示例下面是官方基于openkruise提供的statefulset资源的部署文件示例:apiVersion:apps.kruise.io/v1alpha1kind:StatefulSetmetadata:name:demo-v1-guestbook-kruiselabels:app.kubernetes.io/name:guestbook-kruiseapp.kubernetes.io/instance:demo-v1spec:replicas:3serviceName:demo-v1-guestbook-kruiseselector:matchLabels:app.kubernetes.io/name:guestbook-kruiseapp.kubernetes.io/instance:demo-v1template:metadata:labels:app.kubernetes.io/name:guestbook-kruiseapp.kubernetes.io/instance:demo-v1spec:readinessGates:#AnewconditionthatensuresthepodremainsatNotReadystatewhilethein-placeupdateisappening-conditionType:InPlaceUpdateReadycontainers:-name:guestbookPulllevesimage:openkruise/gulic:-名称:http-servercontainerPort:3000podManagementPolicy:Parallel#allowparallelupdates,workstogetherwithmaxUnavailableupdateStrategy:type:RollingUpdaterollingUpdate:#Doin-placeupdateifpossible,currentlyonlyimageupdateissupportedforin-placeupdatepod更新政策:英普拉IfPossible#Allowparallelupdateswithmaxnumberofunavailableinstancesequalsto2maxUnavailable:3执行部署后,启动pod如下:#kubectlgetpods|grepdemo-v1demo-v1-guestbook-kruise-01/1Running062sdemo-v1-guestbook-kruise-11Run/1Running062sdemo-v1-guestbook-ru1/也可以通过以下操作查看资源状态:#kubectlgetsts.apps.kruise.ioNAMEDESIREDCURRENTUPDATEDREADYAGEdemo-v1-guestbook-kruise333356sopenkruisesopenkruise提供的statefulset资源名称为sts.apps.kruise.io更详细的使用方法请参考to:AdvancedStatefulSet具体使用方法:https://github.com/openkruise/kruise/blob/master/docs/concepts/astatefulset/README.mdAdvancedStatefulSet示例文件:https://github.com/openkruise/kruise/blob/master/docs/tutorial/v1/guestbook-statefulset.yamlUnitedDeployment的具体用法:https://github.com/openkruise/kruise/blob/master/docs/tutorial/uniteddeployment.mdUnitedDeployment示例文件:https:///raw.githubusercontent.com/kruiseio/kruise/master/docs/tutorial/v1/uniteddeployment.yaml
