Kubernetes原始碼分析之Pod的刪除

NeverMore_RC發表於2019-05-12

本文主要梳理刪除Pod時,Pod的執行流程

kube-apiserver的任務

我們通常使用kubectl命令刪除Pod,或者通過http協議直接呼叫apiserver暴露的介面去刪除Pod。所以,刪除Pod的起源肯定在apiserver這兒。
在之前分析kube-apiserver部分有分析到,kube-apiserver的http處理架構使用的是go-restful。其中,對於刪除,呼叫的自然是DELETE介面。方法如下(位於kubernetes/staging/src/k8s.io/apiserver/pkg/endpoints/install.go下的registerResourceHandlers方法

Kubernetes原始碼分析之Pod的刪除
該方法最終的處理handler為restfulDeleteResource
Kubernetes原始碼分析之Pod的刪除
restfulDeleteResource繼續封裝handler,呼叫了DeleteResource方法。DeleteResource方法很長,但最終呼叫的還是DELETE方法,如下
Kubernetes原始碼分析之Pod的刪除
DELETE方法位於staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go下。在DELETE方法中,最主要的是updateForGracefulDeletionAndFinalizers方法,該方法的主要作用就是用來改變Pod的一些內部資訊,其實就是改變Pod的兩個欄位:DeletionTimestamp以及DeletionGracePeriodSeconds,呼叫的是BeforeDelete方法
Kubernetes原始碼分析之Pod的刪除
通過比對工具也可以發現,主要的欄位改變如下
Kubernetes原始碼分析之Pod的刪除

kubelet的任務

通過之前分析過kubelet的程式碼得知,kubelet一直在通過listwatch監聽apiserver的變化

Kubernetes原始碼分析之Pod的刪除
如圖,監聽到相應的變化之後,呼叫相應的處理邏輯。同時,kubelet還啟動了一個goroutine:statusManager
Kubernetes原始碼分析之Pod的刪除
在syncLoop之前呼叫了statusManager的start方法啟動statusManager。
start方法如下:
Kubernetes原始碼分析之Pod的刪除
主要的任務就是通過監聽事件的變化,呼叫syncPod方法。在syncPod方法有下面一段程式碼
Kubernetes原始碼分析之Pod的刪除
我們發現,kubelet又去呼叫了一次DELETE介面,這是為什麼呢?不是已經刪除了嗎?別急,這才是我們要分析的DELETE操作最核心的部分。

深層分析

我們知道,Pod的刪除如果不去強制刪除,則其實是一個優雅的刪除,也就是一個graceful的刪除。預設情況下,這個優雅的時間是30s,也就是grace-period的時間。在kube-apiserver的任務中,通過updateForGracefulDeletionAndFinalizers方法為Pod設定了DeletionTimestampDeletionGracePeriodSeconds兩個欄位,此時Pod定義為graceful的狀態。回到程式碼處,呼叫完updateForGracefulDeletionAndFinalizers方法後,下面有一個判斷的語句

Kubernetes原始碼分析之Pod的刪除
很顯然,因為我們是優雅刪除,所以deleteImmediately欄位false,刪除到此結束。是不是與我們想象的完全不一樣?
沒錯,實際情況的確是這樣,每次刪除的時候,apiserver的處理邏輯到此就中斷了。接下來就要重新認識kubelet了。
Kubelet在呼叫apiserver的刪除介面的時候,提前會有一個判斷,呼叫鏈為canBeDeleted-->PodResourcesAreReclaimed。在PodResourcesAreReclaimed方法內,主要的任務就是判斷Pod內的資源是否已經完全關閉和清理,包括containersprocessesvolumes以及cgroup sandbox資源。
Kubernetes原始碼分析之Pod的刪除
當所有的資源都清理乾淨之後,此時canBeDeleted方法返回true,kubelet呼叫apiserver的delete介面再次刪除Pod。不過,與優雅刪除不同的是,這次呼叫,多了一個deleteOptions欄位
Kubernetes原始碼分析之Pod的刪除
意思很好理解,就是設定grace-period欄位為0,表示這次是強制刪除Pod。因此,apiserver會再次收到DELETE的請求,繼續執行DELETE handler的流程。與第一次不同的時,這次是強制刪除Pod,所以會執行完整的過程,apiserver去etcd刪除最終的Pod資訊。
Kubernetes原始碼分析之Pod的刪除
kubelet接收到事件變化之後,轉化為REMOVE事件,完成Pod的最終清理工作。至此,Pod刪除流程結束。

總結

優雅刪除Pod時:
1、apiserver handler執行了兩次,第一次主要是修改Pod資訊,設定DeletionTimestampDeletionGracePeriodSeconds資訊,第二次去資料庫etcd刪除Pod資訊;
2、kubelet通過檢測到Pod內的資源已經完全釋放之後,觸發了第二次刪除事件,且是強制刪除Pod;
3、kubelet的DELETE操作其實監聽到的是Pod的更新事件,Pod刪除之後,執行的是REMOVE操作;
4、處理流程為:客戶端請求刪除Pod-->apiserver更新Pod資訊-->kubelet優雅釋放Pod資源-->kubelet請求刪除Pod-->apiserver刪除etcd中Pod資訊-->kubelet完成最終Pod的資源清理

相關文章