typeManagerinterface{// 通過 pod namespace 和 pod name 就能獲得相應的 kubernetes 物件
GetObject(namespace,namestring)(runtime.Object,error)// Register function 主要是我們給這個 function 一個 pod spec 實作的物件需要產生對應的 reflector
//以 pod 中用到 configmap 為例,RegisterPod 就需要產生 pod 內用到所得有的 configmap reflector
RegisterPod(pod*v1.Pod)// UnregisterPod function 定義了當給定一個 pod spec 實作的物件必須把 pod 物件所用到 reflector 都消滅掉
// 當 pod 被刪除時, pod 中用到 configmap 為例,UnregisterPod 就需要 pod 內用到所得有的 configmap reflector 都移除
UnregisterPod(pod*v1.Pod)}
這個實作的 function 比較複雜一點,需要透過 getReferencedObjects function 拆解 pod spec 取出對應的資料,這個 getReferencedObjects 可以抽換成 get configmap ReferencedObjects 的或是 secret ReferencedObjects 的。
// VisitPodSecretNames invokes the visitor function with the name of every secret
// referenced by the pod spec. If visitor returns false, visiting is short-circuited.
// Transitive references (e.g. pod -> pvc -> pv -> secret) are not visited.
// Returns true if visiting completed, false if visiting was short-circuited.
funcVisitPodSecretNames(pod*v1.Pod,visitorVisitor)bool{//透過 for range 遞迴 pod spec 中的 ImagePullSecrets 欄位
for_,reference:=rangepod.Spec.ImagePullSecrets{//把找到的名稱傳入 visitor function 中,還記得上面有提過的 visitor function 嗎?
//上面 visitor function 做的事情就是將 name 存入 set 回傳 true
if!visitor(reference.Name){returnfalse}}//下面會看到實作方式這裡就簡短的解釋一下,透過 for range 遞迴 pod spec 中的 continaer 的欄位中會出現 secret 的欄位
//若是欄位有數值就傳入 visitor function 將 name 存入 set 。
VisitContainers(&pod.Spec,AllContainers,func(c*v1.Container,containerTypeContainerType)bool{returnvisitContainerSecretNames(c,visitor)})//恩...我覺得在這裏定了這個沒有什麼特別的意義...就是等等用來承載 pod spec 中 VolumeSource 欄位的數值
//放到 for 迴圈裡面應該也行吧?xD
varsource*v1.VolumeSource// 透過for 迴圈遞迴 pod spec 中的 volumes欄位,這裡可以看到各式各樣的volume 例如 Ceph Cinder Flex
// 這些都有可能會用到 secret 我們需要一個一個檢視,若是有找到 secret 就要傳入 visitor function 儲存在 set 中。
fori:=rangepod.Spec.Volumes{source=&pod.Spec.Volumes[i].VolumeSource//由於 volume 種類眾多我這邊只挑幾個來說明
switch{// 如果VolumeSource的欄位是 Azure file 的話就需要進一步判斷
// 底下的 secret name 欄位,若是有這個欄位就把裡面的數值傳入 visitor function
// 透過 visitor function 儲存在 set 中。
casesource.AzureFile!=nil:iflen(source.AzureFile.SecretName)>0&&!visitor(source.AzureFile.SecretName){returnfalse}// 如果 VolumeSource 的欄位是 CephFS 的話就需要進一步判斷
// 底下的 secret name 欄位,若是有這個欄位就把裡面的數值傳入 visitor function
// 透過 visitor function 儲存在 set 中。
casesource.CephFS!=nil:ifsource.CephFS.SecretRef!=nil&&!visitor(source.CephFS.SecretRef.Name){returnfalse}...//其他實作方式都差不多,有興趣的小夥伴可以回 source code code base 看看
}}returntrue}funcVisitContainers(podSpec*v1.PodSpec,maskContainerType,visitorContainerVisitor)bool{ifmask&InitContainers!=0{fori:=rangepodSpec.InitContainers{if!visitor(&podSpec.InitContainers[i],InitContainers){returnfalse}}}ifmask&Containers!=0{fori:=rangepodSpec.Containers{if!visitor(&podSpec.Containers[i],Containers){returnfalse}}}ifmask&EphemeralContainers!=0{fori:=rangepodSpec.EphemeralContainers{if!visitor((*v1.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon),EphemeralContainers){returnfalse}}}returntrue}
UnregisterPod
顧名思意就是反註冊 pod ,那到底是反註冊什麼呢?在上面我們有提到 RegisterPod 就是遞迴 pod spec 的每個欄位( configmap / secret ),以及 pod spec 中的 namespace 與 pod name 作為 key 儲存在 registeredPods 的 map。
反過來說反註冊就是要遞迴 pod spec 的每個欄位( configmap / secret ),並且透過 pod spec 中的 namespace 與 pod name 作為 key 刪除 registeredPods map 中對應的資料,廢話就不多說了來 code 吧。