色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Kubernetes Operator最佳實(shí)踐介紹

馬哥Linux運(yùn)維 ? 來(lái)源:Java與go云原生 ? 2023-04-19 09:16 ? 次閱讀

介紹

kubernetes operator是通過(guò)連接主API并watch時(shí)間的一組進(jìn)程,一般會(huì)watch有限的資源類型。

當(dāng)相關(guān)(所watch的)event觸發(fā)的時(shí)候,operator做出響應(yīng)并執(zhí)行具體的動(dòng)作。這可能僅限于與主 API 交互,但通常會(huì)涉及在其他一些系統(tǒng)上執(zhí)行某些操作(可以是集群中或集群外資源)。

b7eac3da-de23-11ed-bfe3-dac502259ad0.png

Operators是控制器的集合,并且每個(gè)控制器watch了指定的資源類型。當(dāng)被watched的資源時(shí)間觸發(fā)的時(shí)候,reconcile cycle(直譯:調(diào)諧循環(huán),下文均使用reconcile cycle)也將隨之啟動(dòng)。

在執(zhí)行reconcile cycle期間,控制器有責(zé)任檢查當(dāng)前狀態(tài)是否與被watched資源描述的期望狀態(tài)相匹配。有趣的是,根據(jù)設(shè)計(jì),時(shí)間并不會(huì)傳遞到reconcile cycle中,這將會(huì)強(qiáng)制地讓你去考慮實(shí)例的整個(gè)狀態(tài)。這種方法被稱為基于水平觸發(fā)而不是基于邊緣觸發(fā)(level-based, as opposed to edge-based)。這源自于電子電路的設(shè)計(jì),水平觸發(fā)是接收event(例如中斷)并對(duì)狀態(tài)做出反應(yīng)的理念,而基于邊緣的觸發(fā)是接收event并對(duì)狀態(tài)變化做出反應(yīng)的理念。

水平觸發(fā)雖說(shuō)效率較低,因?yàn)樗鼜?qiáng)制重新評(píng)估完整的狀態(tài),而不是僅僅關(guān)注改變了什么,但在信號(hào)可能丟失或多次重復(fù)傳輸?shù)膹?fù)雜不可靠環(huán)境中,這種方式被認(rèn)為是更適用的。

這種設(shè)計(jì)的選擇會(huì)影響我們編寫控制器代碼的方式。

與此討論相關(guān)的還有對(duì) API 請(qǐng)求生命周期的理解。下圖提供了一個(gè)高層次的總結(jié):

b7f69994-de23-11ed-bfe3-dac502259ad0.png

當(dāng)向API服務(wù)器發(fā)送請(qǐng)求時(shí),特別是對(duì)于創(chuàng)建和刪除請(qǐng)求,它們會(huì)經(jīng)歷上圖所示的階段。需要注意的是,也可以指定webhook來(lái)執(zhí)行請(qǐng)求的更改和驗(yàn)證。如果operator引入了CRD(custom resource definition),我們可能還必須定義這些webhook。一般來(lái)說(shuō),operator進(jìn)程會(huì)開放一個(gè)端口來(lái)來(lái)實(shí)現(xiàn)webhook endpoint。

本文介紹了一系列在使用Operator SDK來(lái)設(shè)計(jì)和開發(fā)Operator時(shí)需要牢記的最佳實(shí)踐。

如果你的operator引入了一個(gè)新的CRD,Operator SDK將會(huì)協(xié)助你來(lái)搭建。為確保您的 CRD 符合 Kubernetes 擴(kuò)展 API 的最佳實(shí)踐,請(qǐng)遵循這些約定。

文中所提到的所有的最佳實(shí)踐都在operator-utils代碼庫(kù)中,并以可運(yùn)行的例子體現(xiàn)。在你的operator項(xiàng)目中,也可以將operator-utils以library的方式導(dǎo)入,以此提供給你一些有用的工具。

最后,這組編寫operator的最佳實(shí)踐僅代表我的個(gè)人觀點(diǎn),不應(yīng)被視為Red Hat的官方最佳實(shí)踐。

創(chuàng)建 watches

正如我們所說(shuō),控制器watch著資源events。

watch是一種接收某種類型(核心類型或CRD)的機(jī)制。一般通過(guò)指定以下內(nèi)容來(lái)創(chuàng)建watch機(jī)制:

想要watch的資源類型

handler。handler將被監(jiān)視類型上的events映射到一個(gè)或多個(gè)調(diào)用協(xié)調(diào)周期的實(shí)例。監(jiān)視類型和實(shí)例類型不必相同。

predicate。predicate是一組能夠過(guò)濾我們感興趣的events且可自定義的函數(shù)。

下圖記錄了以上提及的內(nèi)容:

b805376a-de23-11ed-bfe3-dac502259ad0.png

通常來(lái)說(shuō),同一類型(kind)開啟多個(gè)watch是可行的,因?yàn)閣atch是多路復(fù)用的。

你也應(yīng)該盡可能多地嘗試過(guò)濾event。這邊有個(gè)predicate例子,用來(lái)過(guò)濾secret資源上的event。這里你只對(duì)類型為TLS的secret資源event感興趣:

isAnnotatedSecret:=predicate.Funcs{
UpdateFunc:func(eevent.UpdateEvent)bool{
oldSecret,ok:=e.ObjectOld.(*corev1.Secret)
if!ok{
returnfalse
}
newSecret,ok:=e.ObjectNew.(*corev1.Secret)
if!ok{
returnfalse
}
ifnewSecret.Type!=util.TLSSecret{
returnfalse
}
oldValue,_:=e.MetaOld.GetAnnotations()[certInfoAnnotation]
newValue,_:=e.MetaNew.GetAnnotations()[certInfoAnnotation]
old:=oldValue=="true"
new:=newValue=="true"
//ifthecontenthaschangedwetriggeriftheannotationisthere
if!reflect.DeepEqual(newSecret.Data[util.Cert],oldSecret.Data[util.Cert])||
!reflect.DeepEqual(newSecret.Data[util.CA],oldSecret.Data[util.CA]){
returnnew
}
//otherwisewetriggeriftheannotationhaschanged
returnold!=new
},
CreateFunc:func(eevent.CreateEvent)bool{
secret,ok:=e.Object.(*corev1.Secret)
if!ok{
returnfalse
}
ifsecret.Type!=util.TLSSecret{
returnfalse
}
value,_:=e.Meta.GetAnnotations()[certInfoAnnotation]
returnvalue=="true"
},
}

一個(gè)非常常見的模式是觀察我們創(chuàng)建(和我們擁有)資源上的events,并且定期在擁有這些資源的CR上執(zhí)行reconcile cycle。為此,你可以使用EnqueueRequestForOwner handler,按照如下方式完成:

err=c.Watch(&source.Kind{Type:&examplev1alpha1.MyControlledType{}},&handler.EnqueueRequestForOwner{})

另一種不太常用的情況是將一個(gè)events傳播到多個(gè)資源上。考慮一種情況,一個(gè)控制器注入了TLS secret的路由。同一個(gè)命名空間中的多個(gè)路由可以指向同一個(gè)secret。如果secret發(fā)生了改變,我們需要更新所有路由。因此,我們需要在secret類型上創(chuàng)建一種watch機(jī)制,處理程序如下所示:

typeenqueueRequestForReferecingRoutesstruct{
client.Client
}

//triggerarouterreconcileeventforthoseroutesthatreferencethissecret
func(e*enqueueRequestForReferecingRoutes)Create(evtevent.CreateEvent,qworkqueue.RateLimitingInterface){
routes,_:=matchSecret(e.Client,types.NamespacedName{
Name:evt.Meta.GetName(),
Namespace:evt.Meta.GetNamespace(),
})
for_,route:=rangeroutes{
q.Add(reconcile.Request{NamespacedName:types.NamespacedName{
Namespace:route.GetNamespace(),
Name:route.GetName(),
}})
}
}

//UpdateimplementsEventHandler
//triggerarouterreconcileeventforthoseroutesthatreferencethissecret
func(e*enqueueRequestForReferecingRoutes)Update(evtevent.UpdateEvent,qworkqueue.RateLimitingInterface){
routes,_:=matchSecret(e.Client,types.NamespacedName{
Name:evt.MetaNew.GetName(),
Namespace:evt.MetaNew.GetNamespace(),
})
for_,route:=rangeroutes{
q.Add(reconcile.Request{NamespacedName:types.NamespacedName{
Namespace:route.GetNamespace(),
Name:route.GetName(),
}})
}
}

資源 Reconciliation Cycle

reconcile cycle是在被watch的event傳遞后框架將控制權(quán)轉(zhuǎn)交給我們地方。正如之前所解釋的,在該reconcile cycle中我們沒(méi)有獲得相關(guān)時(shí)間類型的信息,是因?yàn)槲覀兪腔谒接|發(fā)的方式來(lái)工作。

下面是一個(gè)管理CRD控制器的常見reconcile cycle的模型。和其他任何一個(gè)模型一樣,它不會(huì)反映任何特定用例,但我希望它將有助于解決你在編寫operator時(shí)遇到的問(wèn)題。

b80ed4fa-de23-11ed-bfe3-dac502259ad0.png

從圖中我們可以看到,主要步驟是:

檢索你感興趣的CR實(shí)例

確認(rèn)實(shí)例的有效性。我們不會(huì)在不合法實(shí)例上做任何事情。

初始化實(shí)例。如果實(shí)例的某些值沒(méi)有被初始化,我們會(huì)在這一步進(jìn)行處理。

判斷實(shí)例的deletion狀態(tài)。如果實(shí)例正在被刪除,我們也需要做一些特殊的清理。

管理控制器的業(yè)務(wù)邏輯。如果以上步驟均通過(guò),我們最終可以管理和執(zhí)行該實(shí)例的reconcile邏輯。這個(gè)邏輯每個(gè)控制器都不盡相同。

在本節(jié)的剩余部分,你可以找到有關(guān)每個(gè)步驟的更深入的注意事項(xiàng)。

資源驗(yàn)證

這里存在兩種類型的校驗(yàn):語(yǔ)法校驗(yàn)和語(yǔ)義校驗(yàn)。

語(yǔ)法校驗(yàn):通過(guò)定義OpenAPI規(guī)則來(lái)驗(yàn)證。

語(yǔ)義校驗(yàn):可以通過(guò)創(chuàng)建 ValidatingAdmissionConfiguration 來(lái)完成。

注意:在控制器中不能校驗(yàn)CR合法性。一旦CR被APIServer接受了,它就會(huì)存在Etcd中。CR存在Etcd之后,管理該CR資源的控制器就無(wú)法拒絕它,如果這個(gè)CR是不合法的,控制器在嘗試使用或處理它的時(shí)候?qū)?huì)發(fā)生錯(cuò)誤。

推薦:但是由于我們不能保證ValidatingAdmissionConfiguration被創(chuàng)建或正常工作,我們還是應(yīng)該在控制器內(nèi)部去驗(yàn)證CR,如果CR不合法,應(yīng)該避免創(chuàng)建無(wú)限錯(cuò)誤循環(huán)。

語(yǔ)法校驗(yàn)

可以按照這個(gè)鏈接的描述添加OpenAPI驗(yàn)證規(guī)則

推薦:盡可能多地為你的自定義資源模型進(jìn)行語(yǔ)法校驗(yàn)。你應(yīng)該盡量使用語(yǔ)法校驗(yàn),因?yàn)樗鄬?duì)簡(jiǎn)單,并且可以防止格式錯(cuò)誤的 CR 存儲(chǔ)在 etcd 中。

語(yǔ)義校驗(yàn)

語(yǔ)義校驗(yàn)是為了確保字段具有合理的值,從而使整個(gè)資源記錄是有意義的。語(yǔ)義驗(yàn)證業(yè)務(wù)邏輯取決于 CR 所代表的概念,并且必須由operator的開發(fā)人員進(jìn)行編碼實(shí)現(xiàn)。

如果給定的CR需要語(yǔ)義校驗(yàn),那么operator需要暴露一個(gè)webhook,作為operator deploymen的一部分,ValidatingAdmissionConfiguration也應(yīng)該被創(chuàng)建。

以下是目前存在的局限性:

在OpenShift 3.11中,ValidatingAdmissionConfigurations還處于技術(shù)預(yù)覽階段(將從4.1開始支持)

Operator SDK不支持腳手架形式的webhook。可以使用kubebuilder來(lái)進(jìn)行實(shí)現(xiàn):

kubebuilderwebhook--groupcrew--versionv1--kindFirstMate--type=mutating--operations=create,update

驗(yàn)證控制器中的資源

最好的方式是直接拒絕一個(gè)無(wú)效的CR,而不是接受并保存在Etcd中,然后對(duì)它進(jìn)行錯(cuò)誤條件處理。當(dāng)然也有可能的情況是,ValidatingAdmissionConfiguration并沒(méi)有被部署或者根本不可用。所以我認(rèn)為在控制器代碼中進(jìn)行語(yǔ)義校驗(yàn)仍然是一個(gè)很好的做法。你應(yīng)該做到的是,可以在ValidatingAdmissionConfiguration和控制器之間共享這部分結(jié)構(gòu)化的代碼。

控制器中調(diào)用驗(yàn)證方法的代碼如下所示:

ifok,err:=r.IsValid(instance);!ok{
returnr.ManageError(instance,err)
}

請(qǐng)注意,如果驗(yàn)證失敗,我們按照錯(cuò)誤管理部分中的描述來(lái)管理這個(gè)錯(cuò)誤。

IsValid函數(shù)如下:

func(r*ReconcileMyCRD)IsValid(objmetav1.Object)(bool,error){
mycrd,ok:=obj.(*examplev1alpha1.MyCRD)
//validationlogic
}

資源初始化

Kubernetes的一個(gè)很好的慣例是用戶只初始化他所需要的資源字段,其他的可以省略。以上是用戶的視點(diǎn),但從編碼人員和調(diào)試者的角度來(lái)說(shuō),實(shí)際上最好將所有的字段都初始化。這允許在編碼的時(shí)候不必總是去校驗(yàn)字段是否被定義了,并且可以輕松地排除錯(cuò)誤情況。為了初始化資源,這里有兩個(gè)選項(xiàng):

在控制器中定義初始化方法

定義一個(gè) MutatingAdmissionConfiguration(類似于ValidatingAdmissionConfiguration的程序)

建議:在控制器中定義一個(gè)初始化方法。代碼應(yīng)類似于此示例:

ifok:=r.IsInitialized(instance);!ok{
err:=r.GetClient().Update(context.TODO(),instance)
iferr!=nil{
log.Error(err,"unabletoupdateinstance","instance",instance)
returnr.ManageError(instance,err)
}
returnreconcile.Result{},nil
}

注意,如果IsInitialized方法的結(jié)果返回true,我們更新instance并return。這將會(huì)立即出發(fā)另一個(gè)reconcile cycle。第二次調(diào)用IsInitialized方法將會(huì)返回false,代碼邏輯將會(huì)執(zhí)行到下一部分。

資源 Finalization

如果資源不屬于您的操作員控制的 CR,但在刪除該 CR 時(shí)需要采取措施,您必須使用finalizer。

終結(jié)器提供了一種機(jī)制來(lái)通知 Kubernetes 控制平面,在執(zhí)行標(biāo)準(zhǔn) Kubernetes 垃圾收集邏輯之前需要執(zhí)行一個(gè)操作。

資源可以有一個(gè)或多個(gè)finalizers。每一個(gè)控制器應(yīng)該管理自己的finalizer并且忽略其他的。

這是管理finalizers的偽代碼算法

如果需要,在初始化方法中添加finalizer。

當(dāng)資源被刪除,檢查此控制器擁有的finalizer是否存在。

清理成功,移除finalizer并更新CR

如果失敗決定是重試還是放棄并可能留下垃圾(在某些情況下這是可以接受的)

如果不存在,直接return

如果存在,執(zhí)行如下清理邏輯:

如果你的清理邏輯需要添加額外的資源,需要記住的是,無(wú)法在正在刪除的命名空間中創(chuàng)建其他資源。刪除命名空間將會(huì)觸發(fā)finalizer并刪除其下所有資源。

看如下的代碼例子:

ifutil.IsBeingDeleted(instance){
if!util.HasFinalizer(instance,controllerName){
returnreconcile.Result{},nil
}
err:=r.manageCleanUpLogic(instance)
iferr!=nil{
log.Error(err,"unabletodeleteinstance","instance",instance)
returnr.ManageError(instance,err)
}
util.RemoveFinalizer(instance,controllerName)
err=r.GetClient().Update(context.TODO(),instance)
iferr!=nil{
log.Error(err,"unabletoupdateinstance","instance",instance)
returnr.ManageError(instance,err)
}
returnreconcile.Result{},nil
}

資源所有權(quán)

資源所有權(quán)是Kubernetes中的原生概念,它決定了資源如何被刪除。默認(rèn)情況下,當(dāng)一個(gè)資源被刪除的時(shí)候,它的子資源也也會(huì)被刪除(你可以設(shè)置cascade=false來(lái)關(guān)閉這種行為)

這種行為有助于確保資源的正確垃圾收集,尤其是當(dāng)資源控制多級(jí)層次結(jié)構(gòu)中的其他資源時(shí)(deployment-> repilcaset->pod)

建議:如果你的控制器創(chuàng)建資源并且它的生命周期與其他資源(kubernetes核心資源或其他CR)有關(guān)聯(lián),那么您應(yīng)該將此資源設(shè)置為其他資源的所有者,如下所示:

controllerutil.SetControllerReference(owner,obj,r.GetScheme())

有關(guān)所有權(quán)的其他規(guī)則如下:

父子資源必須位于同一命名空間中

命名空間資源可以擁有集群資源。但我們必須小心處理。一個(gè)對(duì)象可以有一個(gè)所有者列表。如果多個(gè)命名空間對(duì)象擁有相同的集群資源,則每個(gè)對(duì)象都應(yīng)聲明所有權(quán),而不會(huì)覆蓋其他對(duì)象的所有權(quán)

集群資源不能擁有命名空間資源

集群資源可以擁有另外一個(gè)集群資源

狀態(tài)管理

Status是資源的一個(gè)標(biāo)準(zhǔn)部分。Status被用于報(bào)告資源的狀態(tài)。在本文檔中,我們將使用 status 報(bào)告最后一次執(zhí)行協(xié)調(diào)循環(huán)的結(jié)果。你也可以在Status中添加更多的信息。

在正常情況下,如果我們每次執(zhí)行reconcile cycle的時(shí)候都要更新資源,這將觸發(fā)更新時(shí)間,進(jìn)而導(dǎo)致無(wú)限觸發(fā)reconcile cycle。

因此,正如上面描述的那樣,我們應(yīng)該把Status作為子資源。

使用這種方法,我們能夠不增加ResourceGeneration元數(shù)據(jù)域的情況下更新資源的狀態(tài)。使用如下命令更新狀態(tài):

err=r.Status().Update(context.Background(),instance)

現(xiàn)在我們需要為我們的watch機(jī)制寫一個(gè)predicate(有關(guān)這些概念的更多詳細(xì)信息,請(qǐng)參閱有關(guān)watches的部分)用來(lái)丟棄不增加ResourceGeneration的更新事件。可以使用GenerationChangePredicate來(lái)完成此功能。

如果你還記得的話,上文提到過(guò),在使用finalizer的時(shí)候,應(yīng)該在初始化的時(shí)候設(shè)置。如果finalizer是初始化的唯一項(xiàng),由于它是元數(shù)據(jù)項(xiàng)的一部分,所以ResourceGeneration不會(huì)遞增。為了說(shuō)明該用例,以下是predicate的修改版本:

typeresourceGenerationOrFinalizerChangedPredicatestruct{
predicate.Funcs
}

//UpdateimplementsdefaultUpdateEventfilterforvalidatingresourceversionchange
func(resourceGenerationOrFinalizerChangedPredicate)Update(eevent.UpdateEvent)bool{
ife.MetaNew.GetGeneration()==e.MetaOld.GetGeneration()&&reflect.DeepEqual(e.MetaNew.GetFinalizers(),e.MetaOld.GetFinalizers()){
returnfalse
}
returntrue
}

現(xiàn)在假設(shè)你的status如下所示:

typeMyCRStatusstruct{
//+kubebuilderEnum=Success,Failure
Statusstring`json:"status,omitempty"`
LastUpdatemetav1.Time`json:"lastUpdate,omitempty"`
Reasonstring`json:"reason,omitempty"`
}

你可以寫一個(gè)函數(shù)來(lái)管理并保證reconcile cycle成功執(zhí)行:

func(r*ReconcilerBase)ManageSuccess(objmetav1.Object)(reconcile.Result,error){
runtimeObj,ok:=(obj).(runtime.Object)
if!ok{
log.Error(errors.New("notaruntime.Object"),"passedobjectwasnotaruntime.Object","object",obj)
returnreconcile.Result{},nil
}
ifreconcileStatusAware,updateStatus:=(obj).(apis.ReconcileStatusAware);updateStatus{
status:=apis.ReconcileStatus{
LastUpdate:metav1.Now(),
Reason:"",
Status:"Success",
}
reconcileStatusAware.SetReconcileStatus(status)
err:=r.GetClient().Status().Update(context.Background(),runtimeObj)
iferr!=nil{
log.Error(err,"unabletoupdatestatus")
returnreconcile.Result{
RequeueAfter:time.Second,
Requeue:true,
},nil
}
}else{
log.Info("objectisnotRecocileStatusAware,notsettingstatus")
}
returnreconcile.Result{},nil
}

錯(cuò)誤管理

如果控制器進(jìn)入了一個(gè)錯(cuò)誤條件,并且在reconcile方法中返回了一個(gè)錯(cuò)誤。operator將會(huì)打印錯(cuò)誤日志到標(biāo)準(zhǔn)輸出,reconlie event將會(huì)立即再次調(diào)度(默認(rèn)的調(diào)度器實(shí)際上應(yīng)該檢測(cè)是否一遍又一遍地出現(xiàn)相同的錯(cuò)誤,并增加相應(yīng)的調(diào)度時(shí)間,但在我的經(jīng)驗(yàn)看來(lái),這并沒(méi)有發(fā)生)。如果錯(cuò)誤一直存在,那么也將永遠(yuǎn)存在錯(cuò)誤循環(huán)。而且,這個(gè)錯(cuò)誤條件對(duì)用戶來(lái)說(shuō)是不可見的。

有兩種方法可以通知用戶發(fā)生了錯(cuò)誤,它們可以同時(shí)使用:

在對(duì)象的status字段中返回錯(cuò)誤

生成一個(gè)event描述錯(cuò)誤

此外,如果你認(rèn)為錯(cuò)誤能夠自解決,你應(yīng)該在一段周期時(shí)間后重新調(diào)度reconcile cycle。通常來(lái)說(shuō),周期時(shí)間是呈指數(shù)增長(zhǎng)的,因此在每次迭代中,reconcile event周期會(huì)越來(lái)越長(zhǎng)(例如每次增長(zhǎng)時(shí)間量的兩倍)。

我們現(xiàn)在構(gòu)建狀態(tài)管理來(lái)處理錯(cuò)誤條件:

func(r*ReconcilerBase)ManageError(objmetav1.Object,issueerror)(reconcile.Result,error){
runtimeObj,ok:=(obj).(runtime.Object)
if!ok{
log.Error(errors.New("notaruntime.Object"),"passedobjectwasnotaruntime.Object","object",obj)
returnreconcile.Result{},nil
}

varretryIntervaltime.Duration
r.GetRecorder().Event(runtimeObj,"Warning","ProcessingError",issue.Error())
ifreconcileStatusAware,updateStatus:=(obj).(apis.ReconcileStatusAware);updateStatus{
lastUpdate:=reconcileStatusAware.GetReconcileStatus().LastUpdate.Time
lastStatus:=reconcileStatusAware.GetReconcileStatus().Status
status:=apis.ReconcileStatus{
LastUpdate:metav1.Now(),
Reason:issue.Error(),
Status:"Failure",
}

reconcileStatusAware.SetReconcileStatus(status)
err:=r.GetClient().Status().Update(context.Background(),runtimeObj)
iferr!=nil{
log.Error(err,"unabletoupdatestatus")
returnreconcile.Result{
RequeueAfter:time.Second,
Requeue:true,
},nil
}

iflastUpdate.IsZero()||lastStatus=="Success"{
retryInterval=time.Second
}else{
retryInterval=status.LastUpdate.Sub(lastUpdate).Round(time.Second)
}
}else{
log.Info("objectisnotRecocileStatusAware,notsettingstatus")
retryInterval=time.Second
}

returnreconcile.Result{
RequeueAfter:time.Duration(math.Min(float64(retryInterval.Nanoseconds()*2),float64(time.Hour.Nanoseconds()*6))),
Requeue:true,
},nil
}

注意,此函數(shù)會(huì)立即發(fā)送一個(gè)event,然后使用錯(cuò)誤條件更新狀態(tài)。最后,計(jì)算何時(shí)重新安排下一次reconcile。該算法嘗試將每個(gè)循環(huán)的時(shí)間加倍,最多到六個(gè)小時(shí)為止。

六個(gè)小時(shí)是一個(gè)很好的上限時(shí)間,因?yàn)閑vent大約持續(xù)6個(gè)小時(shí),所以這應(yīng)該確保始終有一個(gè)活動(dòng)event描述當(dāng)前的錯(cuò)誤情況。

總結(jié)

本博客中介紹的實(shí)踐涉及Kubernetes Operator時(shí)最常見的問(wèn)題,且讓你可以編寫一個(gè)有信心投入生產(chǎn)環(huán)境的operator。當(dāng)然很有可能,這僅僅是一個(gè)開始,我們很容易預(yù)見將會(huì)有更多的框架和工具的出現(xiàn)來(lái)幫助你編寫operator。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    16444

    瀏覽量

    179068
  • API接口
    +關(guān)注

    關(guān)注

    1

    文章

    84

    瀏覽量

    10479
  • CRD
    CRD
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    4024
  • TLS
    TLS
    +關(guān)注

    關(guān)注

    0

    文章

    44

    瀏覽量

    4267

原文標(biāo)題:Kubernetes Operator 最佳實(shí)踐

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    leader選舉在kubernetes controller中是如何實(shí)現(xiàn)的

    Kubernetes 的 kube-controller-manager , kube-scheduler, 以及使用 Operator 的底層實(shí)現(xiàn) controller-rumtime 都支持高可用系統(tǒng)中的 leader 選舉。
    的頭像 發(fā)表于 07-21 10:03 ?1777次閱讀

    C編程最佳實(shí)踐.doc

    C編程最佳實(shí)踐.doc
    發(fā)表于 08-17 14:37

    Kubernetes Ingress 高可靠部署最佳實(shí)踐

    摘要: 在Kubernetes集群中,Ingress作為集群流量接入層,Ingress的高可靠性顯得尤為重要,今天我們主要探討如何部署一套高性能高可靠的Ingress接入層。簡(jiǎn)介
    發(fā)表于 04-17 14:35

    Dockerfile的最佳實(shí)踐

    ”微服務(wù)一條龍“最佳指南-“最佳實(shí)踐”篇:Dockerfile
    發(fā)表于 07-11 16:22

    Kubernetes Dashboard實(shí)踐學(xué)習(xí)

    關(guān)于Kubernetes Dashboard的實(shí)踐學(xué)習(xí)
    發(fā)表于 04-10 14:09

    虛幻引擎的紋理最佳實(shí)踐

    紋理是游戲不可或缺的一部分。 這是一個(gè)藝術(shù)家可以直接控制的領(lǐng)域,以提高游戲的性能。 本最佳實(shí)踐指南介紹了幾種紋理優(yōu)化,這些優(yōu)化可以幫助您的游戲運(yùn)行得更流暢、看起來(lái)更好。 最佳
    發(fā)表于 08-28 06:39

    華為云在Kubernetes大規(guī)模場(chǎng)景下的Service性能優(yōu)化實(shí)踐

    本文檔的主要內(nèi)容詳細(xì)介紹的是華為云在Kubernetes大規(guī)模場(chǎng)景下的Service性能優(yōu)化實(shí)踐包括了:1.Kubernetes的Service機(jī)制 2.Iptables實(shí)現(xiàn)Servi
    發(fā)表于 06-21 08:00 ?0次下載
    華為云在<b class='flag-5'>Kubernetes</b>大規(guī)模場(chǎng)景下的Service性能優(yōu)化<b class='flag-5'>實(shí)踐</b>

    阿里巴巴 Kubernetes 應(yīng)用管理實(shí)踐中的經(jīng)驗(yàn)與教訓(xùn)

    產(chǎn)品,這些最佳實(shí)踐就可以信手拈來(lái)了。但是,在面對(duì)天然復(fù)雜的 Kubernetes 時(shí),很多開發(fā)者都無(wú)能為力。作為 Jira 和代碼庫(kù) Bitbucket 背后的公司,Atlassian
    發(fā)表于 11-14 23:06 ?317次閱讀

    教你們Kubernetes五層的安全的最佳實(shí)踐

    Kubernetes)也是黑客們的熱門目標(biāo),如果它們沒(méi)有得到有效的保護(hù),它們可能會(huì)使你的整個(gè)環(huán)境面臨風(fēng)險(xiǎn)。在本文中,我們將討論容器堆棧每一層安全的最佳實(shí)踐。 了解容器安全的含義很重要。作為依賴共享內(nèi)核的應(yīng)用程序?qū)訕?gòu)造,容器可以比
    的頭像 發(fā)表于 07-09 10:13 ?1308次閱讀

    最常用的11款Kubernetes工具

    我看來(lái),Kubernetes 最重要的是將最佳實(shí)踐整合到了一個(gè)系統(tǒng)中,這個(gè)系統(tǒng)可以從樹莓派(Raspberry Pi)擴(kuò)展到財(cái)富 500 強(qiáng)中最大的基礎(chǔ)設(shè)施
    的頭像 發(fā)表于 08-23 10:43 ?2194次閱讀

    Kubernetes是什么,一文了解Kubernetes

    香了。 這時(shí)候就需要我們的主角 Kubernetes 上場(chǎng)了,先來(lái)了解一下 Kubernetes 的基本概念,后面再介紹實(shí)踐,由淺入深步步為營(yíng)。 關(guān)于
    發(fā)表于 12-21 13:40 ?1829次閱讀
    <b class='flag-5'>Kubernetes</b>是什么,一文了解<b class='flag-5'>Kubernetes</b>

    如何從零開發(fā)Kubernetes Operator

    大多數(shù)人使用Kubernetes的方式是使用原生資源(如Pod、Deployment、Service等)部署應(yīng)用程序。但是,也可以擴(kuò)展Kubernetes的功能,從而添加滿足特定需求的新業(yè)務(wù)邏輯,這就是Operator的作用。
    的頭像 發(fā)表于 01-05 11:27 ?1390次閱讀

    Kubernetes上Java應(yīng)用的最佳實(shí)踐

    在本文中,您將了解在 Kubernetes 上運(yùn)行 Java 應(yīng)用程序的最佳實(shí)踐。大多數(shù)這些建議也適用于其他語(yǔ)言。但是,我正在考慮 Java 特性范圍內(nèi)的所有規(guī)則,并且還展示了可用于基于 JVM
    的頭像 發(fā)表于 03-14 17:47 ?715次閱讀

    SAN設(shè)計(jì)和最佳實(shí)踐指南

    電子發(fā)燒友網(wǎng)站提供《SAN設(shè)計(jì)和最佳實(shí)踐指南.pdf》資料免費(fèi)下載
    發(fā)表于 09-01 11:02 ?0次下載
    SAN設(shè)計(jì)和<b class='flag-5'>最佳</b><b class='flag-5'>實(shí)踐</b>指南

    什么是OperatorOperator是如何工作的?如何構(gòu)建Operator

    你也許能夠?qū)?yīng)用熟練的部署到 Kubernetes 上,但你知道什么是 Operator 嗎?Operator 是如何工作的?如何構(gòu)建 Operator?這是一個(gè)復(fù)雜的課題,但幸運(yùn)的是
    的頭像 發(fā)表于 09-01 15:35 ?1746次閱讀
    主站蜘蛛池模板: 谁有成人网站地址 | 甜性涩爱在线播放 | 三级貂蝉艳史 在线观看 | 欧美日韩高清一区二区三区 | 正在播放国产精品 | 亚洲中文字幕日本在线观看 | 麻豆啊传媒app黄版破解免费 | 国产免费人成在线看视频 | 国产真实露脸乱子伦 | 亚洲薄码区 | 成人精品在线视频 | 香蕉99久久久久成人麻豆 | 日本19禁啪啪吃奶大尺度 | 午夜伦yy44880影院 | 美女张开大腿 | 国产亚洲精品久久久久苍井松 | 啊好深啊别拔就射在里面 | 国产乱码精品一区二区三区四川 | 亚洲精品理论电影在线观看 | 国产99久久亚洲综合精品西瓜tv | 鸭子玩富婆流白浆视频 | 男男肉肉互插腐文 | yellow免费| 年轻的母亲4线在线观看完整 | 日本无码毛片久久久九色综合 | 日本高清在线一区二区三区 | 久久爽狠狠添AV激情五月 | 欧美黄色xxx | 在线欧美免费人成视频 | 亚洲高清视频在线观看 | 色婷婷AV99XX | 国产精品自在在线午夜蜜芽tv在线 | 伊人久久青草 | 久久99re2热在线播放7 | 九九热精品免费观看 | 沈阳熟女露脸对白视频 | 国产无遮挡又黄又爽在线视频 | 特级淫片大乳女子高清视频 | 国产欧美国日产在线播放 | 2018年免费三级av观看 | 胸大美女又黄的网站 |