1. 程式人生 > 其它 >09-K8S Basic-kubernetes垃圾回收器 Garbage Collection(GC)

09-K8S Basic-kubernetes垃圾回收器 Garbage Collection(GC)

一、Kubernetes之Garbage Collection

  • 在以前的博文中介紹過如何配置kubelet,按策略刪除無用image、正常或者異常終止不會再啟動的container,以節省資源。kubelet回收的物件在容器層面。那麼kubernetes層面的物件,比如podReplicaSet、Replication Controller、Deployment、StatefulSet、DaemonSet等型別的物件,垃圾回收又是如何呢?
  • 實際上,按理說以上的kubernetes物件並不會產生垃圾,物件一直都存在,除非使用者或者某種控制器將物件刪除。這裡稱為"Garbage Collection"不太準確,實際上它想講的是在執行刪除操作時如何控制物件之間的依賴關係。比如,Deployment物件建立ReplicaSet物件,ReplicaSet物件又建立pod物件,那麼在刪除Deployment時,是否需要刪除與之相依賴的ReplicaSet與pod呢?

1.1、從物件與根物件(Owners and dependents)

  • 某些kubernetes物件是其它物件的owner。比如ReplicaSet物件就是其所管理的pod物件的owner,本文稱這類物件為“根物件”。而被管理的pod對ReplicaSet存在dependent,pod物件通過metadata.ownerReferences欄位指向其依賴的物件,本文稱這類物件為“從物件”。在kubernetes1.8中,ReplicationController, ReplicaSet, StatefulSet, DaemonSet, Deployment, Job and CronJob自動向其建立、收養的物件新增metadata.ownerReferences欄位的值,當然也可以手動設定。以下是擁有3個pod的ReplicaSet設定檔案:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-repset
spec:
  replicas: 3
  selector:
    matchLabels:
      pod-is-for: garbage-collection-example
  template:
    metadata:
      labels:
        pod-is-for: garbage-collection-example
    spec:
      containers:
      - name: nginx
 
 
建立此ReplicaSet:
    kubectl create -f https://k8s.io/examples/controllers/replicaset.yaml
 
 
檢視:
    kubectl get pods --output=yaml
 
 
結果如下:確認ownerReferences的值
apiVersion: v1
kind: Pod
metadata:
  ...
  ownerReferences:
  - apiVersion: apps/v1
    controller: true
    blockOwnerDeletion: true
    kind: ReplicaSet
    name: my-repset
    uid: d9607e19-f88f-11e6-a518-42010a800195

1.2、如何控制垃圾回收刪除從物件?

  • 當刪除一個物件時,可以控制以何種方式刪除其從物件,自動刪除從物件稱為級聯刪除(cascading deletion)。有background與foreground兩種方式。也可以不只刪除根物件不刪除從物件。

1.2.1、前臺級聯刪除

  • 前臺級聯刪除時,根物件首先進入"deletion in progress"狀態,在"deletion in progress"狀態下,存在如下事實:
    • 如果通過REST API訪問根物件,仍然可見。
    • 根物件的deletionTimestamp被設定。
    • 根物件元資料metadata.finalizers包含"foregroundDeletion"。
  • 一旦根物件的狀態被設定成"deletion in progress",垃圾回收器開始啟動對從物件的刪除。如果從物件的object有“ownerReference.blockOwnerDeletion=true”屬性,那麼垃圾回收器必需等到此類從物件被刪除完成以後,才可以刪除根物件。否則垃圾回收器啟動對從物件的刪除後立即刪除根物件。
  • “ownerReference.blockOwnerDeletion=true”會延遲根物件的刪除。在kubernetes1.7版本中增加了一個admission controller,它根據根物件訪問許可權,對將ownerReference.blockOwnerDeletion設定成true的操作進行訪問控制,防止未經授權的使用者將ownerReference.blockOwnerDeletion的值設定成true,從而延遲根物件的刪除。
  • 如果從物件的ownerReferences由某種控制器設定,那麼使用者最好不要手動修改其值。

1.2.2、後臺級聯刪除

  • 後臺級聯刪除時,kubernetes立即刪除根物件並返回。垃圾回收器在後臺刪除其從物件。

1.2.3、不刪除從物件

  • 只刪除根物件不刪除從物件,這種方式稱為“Orphan”,保留下來的從物件變成了“孤兒”。

1.3、在具體操作時設定刪除策略

  • 在執行具體的操作請求時,通過設定刪除請求中的"propagationPolicy"欄位為 “Orphan”, “Foreground”, or “Background”中的一種,選擇上述三種刪除策略中的一種。

  • 在kubernetes1.9以前,對大部分控制器的刪除,預設策略是"Orphan"(注意本段中說的預設值指REST API的預設行為,不是kubectl命令),包含ReplicationController, ReplicaSet, StatefulSet, DaemonSet, and Deployment,也就是在刪除根物件時不刪除從物件。並且當apiVersion是extensions/v1beta1, apps/v1beta1, and apps/v1beta2時,除非特別指定,預設刪除策略仍然是"Orphan"。在kubernetes1.9版本中,所有型別的物件,在app/v1版本的apiVersion中,預設從物件刪除。

  • 後臺級聯刪除示例:

kubectl proxy --port=8080
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \
-H "Content-Type: application/json"
  • 注意上例中kubectl充當的是proxy角色,直接呼叫REST API執行刪除操作,注意其propagationPolicy的取值。
  • 前臺級聯刪除示例:
kubectl proxy --port=8080
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
-H "Content-Type: application/json"
  • 不刪除從物件示例
kubectl proxy --port=8080
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
-H "Content-Type: application/json"
  • kubectl命令也支援級聯刪除操作。在執行kubectl命令時指定"--cascade"選項,其值為true時刪除從物件,為false不刪除從物件,預設值為true。 示例如下:
kubectl delete replicaset my-repset --cascade=false
# 當--cascade為true時,kubectl採用的是前臺級聯刪除還是後臺級聯刪除,文件中沒有講。

1.4、級聯刪除Deployment時的注意點

  • 當級聯刪除Deployment時,其刪除請求中的propagationPolicy必需設定成Foreground。否則Deployment建立的ReplicaSet會被級聯刪除,但是ReplicaSet建立的pod不會被級聯刪除,會成為孤兒。