詳解 Kubernetes 中的垃圾回收機(jī)制
設(shè)想這么一個(gè)場(chǎng)景:我們?cè)?K8s 上創(chuàng)建了一個(gè)對(duì)象,它根據(jù)需要生成副本集和 Pod。在檢查時(shí),我們遺漏了容器某個(gè)屬性的設(shè)置,因此又重新編輯了 Deployment。新的 Deployment 就產(chǎn)生了新的副本集對(duì)象和新的 Pod。這里就出現(xiàn)了一個(gè)問(wèn)題,舊的副本集和 Pop 去哪了?另外,如果直接刪除 Deployment,那副本集和 Pod 又會(huì)如何?事實(shí)就是,在刪除 Deployment 后,副本集和 Pod 也會(huì)一起被刪除,要不然集群早就亂套了。
什么是垃圾回收?
一般來(lái)說(shuō),垃圾回收(GC)就是從系統(tǒng)中刪除未使用的對(duì)象,并釋放分配給它們的計(jì)算資源。GC 存在于所有的高級(jí)編程語(yǔ)言中,較低級(jí)的編程語(yǔ)言通過(guò)系統(tǒng)庫(kù)實(shí)現(xiàn) GC。
GC 最常見的算法之一是 mark-and-sweep,這個(gè)算法會(huì)標(biāo)記將刪除的對(duì)象,再進(jìn)行刪除,如下圖所示:

OwnerRefernce
在面向?qū)ο蟮恼Z(yǔ)言中,一些對(duì)象會(huì)引用其他對(duì)象或者直接由其他對(duì)象組成,k8s 也有類似形式,例如副本集管理一組 Pod,而 Deployment 又管理著副本集。
metadata.ownerReferences 用于確定關(guān)系。metadata.ownerReferences 的值。k get deployment -n kube-system -o wideNAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGEScoredns 2/2 2 2 44d coredns k8s.gcr.io/coredns:1.6.7k get rs -n kube-system -o json | jq ".items[0].metadata.name, .items[0].metadata.ownerReferences""coredns-66bff467f8"[{"apiVersion": "apps/v1","blockOwnerDeletion": true,"controller": true,"kind": "Deployment","name": "coredns","uid": "d8f29b78-439c-497e-9a45-7c33bd626a9f"}]k get pods coredns-66bff467f8-rsnmg -n kube-system -o json | jq ".metadata.name, .metadata.ownerReferences""coredns-66bff467f8-rsnmg"[{"apiVersion": "apps/v1","blockOwnerDeletion": true,"controller": true,"kind": "ReplicaSet","name": "coredns-66bff467f8","uid": "085d5398-1358-43e2-918e-2e03da18c7bd"}]
認(rèn)真觀察上述命令的輸出,其實(shí)它和其他對(duì)象 GC 之間是有些許差別的。對(duì)象關(guān)聯(lián)參考金字塔是顛倒的:

K8s 的垃圾回收策略
如前面所講,在 Kubernetes v1.8 之前,依賴對(duì)象邏輯刪除的實(shí)現(xiàn)是在客戶端,對(duì)于某些資源而言則是在控制器端。有時(shí),客戶端會(huì)中途失敗,導(dǎo)致集群狀態(tài)混亂,需要手動(dòng)清理。后來(lái)為了解決這個(gè)問(wèn)題,K8s 社區(qū)引入并實(shí)現(xiàn)了 Garbage Collector Controller(垃圾回收器),用更好用且更簡(jiǎn)單的方式實(shí)現(xiàn) GC。在 K8s 中,有兩大類 GC:
級(jí)聯(lián)(Cascading):在級(jí)聯(lián)刪除中,所有者被刪除,那集群中的從屬對(duì)象也會(huì)被刪除。 孤兒(Orphan):這種情況下,對(duì)所有者的進(jìn)行刪除只會(huì)將其從集群中刪除,并使所有對(duì)象處于“孤兒”狀態(tài)。
對(duì)象仍然可以通過(guò) REST API 查詢到(可通過(guò) kubectl 或 kuboard 查詢到) 對(duì)象的 deletionTimestamp 字段被設(shè)置 對(duì)象的 metadata.finalizers 包含值 foregroundDeletion
在孤兒刪除策略(orphan deletion strategy)中,會(huì)直接刪除所有者對(duì)象,并將從屬對(duì)象中的 ownerReference 元數(shù)據(jù)設(shè)置為默認(rèn)值。之后垃圾回收器會(huì)確定孤兒對(duì)象并將其刪除。
垃圾回收器如何工作?
如果對(duì)象的 OwnerReferences 元數(shù)據(jù)中沒有任何所有者對(duì)象,那么垃圾回收器會(huì)刪除該對(duì)象。垃圾回收器由 Scanner、Garbage Processor 和 Propagator 組成:
EventQueue:負(fù)責(zé)存儲(chǔ) k8s 中資源對(duì)象的事件 DAG(有向無(wú)環(huán)圖):負(fù)責(zé)存儲(chǔ) k8s 中所有資源對(duì)象的 owner-dependent 關(guān)系 Worker:從 EventQueue 中取出資源對(duì)象的事件,并根據(jù)事件的類型會(huì)采取操作
原文鏈接:https://sparsecode.io/garbage-collection-in-k8s.html
K8S 進(jìn)階訓(xùn)練營(yíng)
點(diǎn)擊屏末 | 閱讀原文 | 即刻學(xué)習(xí)

掃描二維碼獲取
更多云原生知識(shí)
k8s 技術(shù)圈

