控制器視角看pod刪除過程
控制器收到的事件
client-go中的informer通過reflector watch到的事件對象,類型可以是:Add、Modify、Delete,分別代表對象的增加、更新和刪除事件
以刪除pod為例,當(dāng)用戶嘗試刪除一個pod時,外部控制器將能夠獲取到該pod的4個相關(guān)事件(force則是2個),如下:

-
用戶發(fā)出刪除pod請求,api收到該請求之后判斷出pod支持優(yōu)雅刪除,將更新etcd中該pod的DeletionTimestamp、DeletionGracePeriodSeconds字段,etcd中該pod的rv變化,此時控制器reflector收到一個Modify event
-
kubelet reflector watch到上述update事件,開始kill pod中的容器,完成后請求api更新pod的status信息,api將更新etcd中該pod 的condition和containerStatuses等字段,etcd中該pod的rv變化,此時控制器reflector收到一個Modify event
-
kubelet完成上述過程之后,會向api再次發(fā)送一個delete pod請求,希望api直接刪除該pod,api將更新etcd中該pod的DeletionGracePeriodSeconds字段為0, etcd中該pod的rv變化,此時控制器收到一個Modify event
-
api把etcd中的pod的記錄刪除,但etcd中仍然會記錄該pod并更新其rv,此時無法通過api獲取到該pod的信息,控制器此時可以收到一個Delete event
問題思考
如果controller發(fā)生故障,用戶在控制器恢復(fù)之前刪除資源,那么控制器可以獲取到刪除的相關(guān)事件嗎?
-
如果控制器因為網(wǎng)絡(luò)原因無法連接api,會嘗試re-watch,連接api正常之后通過較小的rv記錄可以watch到刪除資源的事件(etcd會緩存資源的歷史版本),因為watch關(guān)注的是資源的變化。給定的 Kubernetes 服務(wù)器只會保留一定的時間內(nèi)發(fā)生的歷史變更列表。 使用 etcd3 的集群默認(rèn)保存過去 5 分鐘內(nèi)發(fā)生的變更。
-
如果控制器掛了,則重啟之后會先進(jìn)行l(wèi)ist,此時拿到的是全量的當(dāng)前狀態(tài)的資源列表,通過list對象的objectMeta中的rv來進(jìn)行接下來的watch(list對象在查詢的時候生成https://kubernetes.io/docs/reference/using-api/api-concepts/#resourceversion-in-metadata,所以rv的值與當(dāng)前時間成正比),因此watch不到歷史pod的Delete事件,就可能導(dǎo)致丟失Delete事件,可以通過給控制器關(guān)注的資源增加Finalizer來保證資源不會立即從etcd中刪除,這樣控制器就能重新list到該資源做reconcile后再移除finalizer。
理解finalizer的作用
https://kubernetes.io/blog/2021/05/14/using-finalizers-to-control-deletion/
apiserver通過deletionGracePeriodSeconds表示資源是否需要優(yōu)雅的刪除(如果支持),如pod被刪除時因為deletionGracePeriodSeconds不為0,則通過配置deletionTimestamp字段將刪除動作轉(zhuǎn)換為更新,由kubelet watch到更新做具體的資源清理之后再設(shè)置deletionGracePeriodSeconds為0來確認(rèn)刪除pod。
如果資源上配置了finalizer,那么api收到請求之后都不會立即在etcd刪除資源,同樣是配置deletionTimestamp轉(zhuǎn)換為更新動作,即使deletionGracePeriodSeconds設(shè)置的是0。當(dāng)所有的finalizer都被移除之后,該資源會被自動刪除
理解ownerReferences作用
https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/
當(dāng)嘗試刪除一個owner資源對象如rs時,會檢查是否有其他資源對象如pod的owner是自己,可以配置刪除owner資源時是否級聯(lián)刪除關(guān)聯(lián)的dependent依賴對象
支持的級聯(lián)cascade策略有:background、foreground、orphaned
foreground:刪除owner對象時apiserver在對象上更新deletionTimestamp和foregroundDeletion finalizers字段,gc controller watch到更新之后把所有會阻塞owner對象刪除的依賴對象進(jìn)行刪除(配置了ownerReference.blockOwnerDeletion=true[admission controller自動配置]的依賴對象會阻塞owner對象),之后移除finalizer,gc controller再次觸發(fā)刪除owner對象
background:kubectl默認(rèn)策略,立即刪除owner對象,依賴對象由controller-manager的gc controller刪除
orphaned:刪除owner對象時不會刪除依賴對象,依賴對象會一直存在

浙公網(wǎng)安備 33010602011771號