k8s gc机制详解-总结
接上篇gc源码分析,这篇主要从事件角度总结以在不同的删除策略(孤儿,前台,后台)模式下,删除k8s资源发生了什么。
以下都是以 deployA , rsA, podA作为介绍。(这个可以类比为任何有这种依赖关系的资源)
1. 孤儿模式
孤儿模式删除deployA: deployA会被删除,rsA不会删除,但是rsA的OwnerReference里deployA会被删除。
具体的流程如下:
(1) 客户端发起kubectl delete deploy deployA –cascade=false
(2)apiserver接收到请求,发现删除模式是organ。这个时候apiserver会做俩件事情:
-
设置deployA的deletionStamp
-
增加一个finalizer,organ
这个时候apiserver会直接返回,不会一直阻塞在这里等
(3)这个时候由于apiserver对deployA更新了。所以gc收到了deployA的更新事件,然后开始处理工作:
-
一,维护uidToNode图,就是删除了deployA这个node节点,并且将rsA节点的onwer删除。
-
二,将rsA这个对象的OwnerReference中的deployA删除;
-
三,将deployA这个对象的organ finalizer删除
(4)将deployA这个对象的organ finalizer删除实际上是一个更新事件。这个时候apiserver收到这个更新事件,发现deployA的所以finalizer被删除了,这个时候调用restful接口真正的删除 deployA。
2. 后台模式
后台模式删除deployA: deployA会被马上删除,然后删除rsA,最后删除pod
具体的流程如下:
(1) 客户端发起kubectl delete deployA propagationPolicy”:“Background”
(2)apiserver接收到请求,发现删除模式是Background。这个时候apiserver会直接将deployA删除。
(3)这个时候由于apiserver删除了deployA。所以gc收到了deployA的删除事件,然后开始处理工作:
-
一,维护uidToNode图,就是删除了deployA这个node节点,并且将rsA扔进attemptToDelete队列
-
二,处理rsA时,发现它的owner已经不存在了,所以马上以backgroud的方式,再删除rsA。
-
三,然后就是同样的操作,先删除了rsA,然后删除了pod。
3. 前台模式
前台模式删除deployA: podA会先删除,然后是rsA,最后是deployA。
具体的流程如下:
(1) 客户端发起kubectl delete deployA propagationPolicy:Foreground
(2)apiserver接收到请求,发现删除模式是Foreground。这个时候apiserver会做俩件事情:
-
设置deployA的deletionStamp
-
增加一个finalizer,Foreground
这个时候apiserver会直接返回,不会一直阻塞在这里等
(3)这个时候由于apiserver对deployA更新了。所以gc收到了deployA的更新事件,然后开始处理工作。
具体为:
一,维护uidToNode图。
首先是deployA这个node节点,会标记为 删除depents中。然后将 deployA的依赖(rsA)加入 attempToDelete队列。
处理rsA时,发现rsA的owner在等待删除depents。并且rsA还有自己的 depends。所以这个时候就调用前台删除接口删除 来删除rsA。
同样,前台删除rsA时,先标记rsA这个node节点,为 删除depents中,然后将 rsA的依赖(podA)加入 attempToDelete队列。
处理podA时,发现PodA的owner在等待删除depents。但是podA没有自己的 depends。所以这个时候就调用后台删除接口删除 来删除podA。
后台删除podA后,apiserver会直接将podA这个对象删除。所以gc收到了 删除事件。这个时候会将 podA这个节点删除,然后再将rsA加入删除队列。
接下来rsA发现自己的depents删除了,所以rsA的finalizer就会删除。然后apiserver就会将rsA删除。
然后gc收到了rsA的删除事件,同样的操作再将deployA删除。
4. 总结
gc的机制非常巧妙,而且和apiserver进行了联动。在实际过程中运用这种gc机制也非常有用。比如有俩个不相关的对象,通过设置OwnerReference, 就可以实现,俩个对象的级联删除。
5. 方法论
以上的流程,通过代码和实践进行验证。
代码分析见上一篇。实践就是通过实验,主要做了以下观察:
(1)看deployA的yaml发生了什么变化
(2)增大kcm的日志等级,查看gc的日志
(3)增大apiserver的日志等级,查看apiserver的处理
5.1 看deployA的yaml发生了什么变化
// -w 一直监控删除前后的变化 root@k8s-master:~/testyaml/hpa# kubectl get deploy zx-hpa -oyaml -w apiVersion: apps/v1 kind: Deployment metadata: annotations: deployment.kubernetes.io/revision: "1" creationTimestamp: "2021-07-09T07:21:48Z" generation: 1 labels: app: zx-hpa-test name: zx-hpa namespace: default resourceVersion: "6975175" selfLink: /apis/apps/v1/namespaces/default/deployments/zx-hpa uid: 6ccbe990-e4d3-4ba1-b67f-56a9bfbd69a0 spec: progressDeadlineSeconds: 600 replicas: 2 revisionHistoryLimit: 10 selector: matchLabels: app: zx-hpa-test strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: zx-hpa-test name: zx-hpa-test spec: containers: - command: - sleep - "3600" image: busybox:latest imagePullPolicy: IfNotPresent name: busybox resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 5 status: availableReplicas: 2 conditions: - lastTransitionTime: "2021-07-09T07:21:50Z" lastUpdateTime: "2021-07-09T07:21:50Z" message: Deployment has minimum availability. reason: MinimumReplicasAvailable status: "True" type: Available - lastTransitionTime: "2021-07-09T07:21:49Z" lastUpdateTime: "2021-07-09T07:21:50Z" message: ReplicaSet "zx-hpa-7b56cddd95" has successfully progressed. reason: NewReplicaSetAvailable status: "True" type: Progressing observedGeneration: 1 readyReplicas: 2 replicas: 2 updatedReplicas: 2 --- apiVersion: apps/v1 kind: Deployment metadata: annotations: deployment.kubernetes.io/revision: "1" creationTimestamp: "2021-07-09T07:21:48Z" generation: 1 labels: app: zx-hpa-test name: zx-hpa namespace: default resourceVersion: "6975316" selfLink: /apis/apps/v1/namespaces/default/deployments/zx-hpa uid: 6ccbe990-e4d3-4ba1-b67f-56a9bfbd69a0 spec: progressDeadlineSeconds: 600 replicas: 2 revisionHistoryLimit: 10 selector: matchLabels: app: zx-hpa-test strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: zx-hpa-test name: zx-hpa-test spec: containers: - command: - sleep - "3600" image: busybox:latest imagePullPolicy: IfNotPresent name: busybox resources: {} terminationMessagePath: /dev/termination-log