kubernetes garbage collection

Table of Contents

1. 前言

k8s 是一个异步的调度系统,当一个资源生命周期结束,内部的垃圾回收机制是如何运行的呢?

2. 代码参考

v1.14.0-alpha.3 commitid: cd9e590178c9f3812e296484b587de1c79461033

3. 简要说明

这里仅对 pod 以及 容器 的删除做了简要的说明

k8s 的垃圾回收机制逐渐向 evict 模块移动而不是直接放在 kubelet 中

垃圾回收作为整个系统的分支而不是核心部分,虽然刚刚开始;

之后也许会有 GCI 这种东西出现(虽然 Runtime 这个接口中已经有了)

4. gc 设计文档

5. gc 触发条件

https://kubernetes.io/docs/concepts/cluster-administration/kubelet-garbage-collection/

通过查看这个文档可以发现,旧的 gc 机制正在逐渐被被新的 evict 机制所取代

32433802967_02cec4c8ea_b.jpg

6. 代码详解

6.1. pod 的删除

kubelet 启动时会启动 syncLoop 来处理 file、apiserver、http 这三个 channel 的变化

详细的变化处理可以看 kubelet.go 的 1872 行 syncLoopIteration 的定义

46652355984_cbdc25a632_b.jpg

HandlePodRemoves 作为 SyncHandler 的回调,会调用 deletePod 来删除 pod

46460484945_87762890bc_b.jpg

46652355044_391da5f7f0_b.jpg

这里注意 1728 行注释提及的内容

这里会发送信号给 podKillCh 这个 channel

46652354244_bc15228405_b.jpg

podKiller 运行了一个 goroutine 从 podKillch 中读取数据然后杀死 pod

40410062263_c45668e5c7_b.jpg

killPod 中调用了 controllerRuntime 中的 KillPod

46460483455_4af6f90c77_b.jpg

46652350224_a86023cd7b_b.jpg

KillPod 会调用 runtime 中的 KillContainer 来尝试删除容器

47322699852_12a80766db_b.jpg

在删出容器之前会先运行 preStopContainer 来检查 lifecycle hooks

46460479795_95338376c9_b.jpg

然后才会停止容器,通常情况下来请求 api 删除容器

46460479755_75d546ff74_b.jpg

至此一个 pod 删除完毕

6.2. podcontainerdeletor

kubelet/podcontainerdeletor.go

在启动 ContainerGc 后还启动了 podContainerDeletor 用于处理 pleg 这个 channel 中传来的信号

47322697572_d69f84d0a2_b.jpg

46460479735_570bbdf0a5_b.jpg

同样在 syncLoopIteration 中被使用

6.3. kuberuntimegc

kubelet/kuberuntime/kuberuntimegc.go

在第一次删除 pod 时,是允许失败的,因为会有一个线程周期性的清理无用的资源

47375539501_bf6be2efb6_b.jpg

kubelet 在 Bootstrap 时会启动一个垃圾回收线程

启动一个镜像垃圾回收器

根据 回收策略 启动了一个 容器垃圾回收

46460479695_9489ab772c_b.jpg

定义了 runtime 的接口 其中声明了 GarbageCollect

47322697422_8622386c72_b.jpg

接下来是 k8s 通常情况下的垃圾回收运行机制

46460479575_f90f83f0dd_b.jpg

1.获得应该被驱逐的容器(没有在工作并且创建时间超出了回收策略设置的时间)

2.根据回收策略中的 MaxPerPodContainer 字段删除每个 pod 中最老的容器

3.根据回收策略中的 MaxContainers 字段删除最老的容器

47322697172_da82ec4c74_b.jpg

4.获取所有无用的 sandbox

5.删除应该被驱逐的 sandbox

47375551361_03e590e742_n.jpg

最后删除 pod 的日志目录

46460479375_5b1cacaa3c_b.jpg

Created: 2023-11-24 Fri 09:50

Validate