内容简介:在重新设置 Deployment 后,旧的副本集以及 Pod 是怎么被删除的呢?本文讲述了 K8s 中的垃圾回收机制,简单介绍了垃圾回收的概念、策略以及实现方法,希望能帮助大家进一步了解垃圾回收。作者:Abhishek
在重新设置 Deployment 后,旧的副本集以及 Pod 是怎么被删除的呢?本文讲述了 K8s 中的垃圾回收机制,简单介绍了垃圾回收的概念、策略以及实现方法,希望能帮助大家进一步了解垃圾回收。
作者:Abhishek
翻译:Bach(才云)
校对: bot(才云)、星空下的文仔(才云)
设想这么一个场景:我们在 K8s 上创建了一个对象,它根据需要生成副本集和 Pod。在检查时,我们遗漏了容器某个属性的设置,因此又重新编辑了 Deployment 。新的 Deployment 就产生了新的副本集对象和新的 Pod。这里就出现了一个问题,旧的副本集和 Pop 去哪了?另外,如果直接删除 Deployment,那副本集和 Pod 又会如何?事实就是,在删除 Deployment 后,副本集和 Pod 也会一起被删除,要不然集群早就乱套了。
在这个场景之下,我们可以深入思考几个问题: 在 K8s 中该如何实现级联删除?有几种级联删除策略?在 K8s 中有没有可能存在孤儿对象 (orphan object) ? 这些问题其实就是典型的垃圾回收(garbage collection,GC)问题。本文将介绍 K8s 中垃圾回收的概念以及实现方法。
K8sMeetup
什么是垃圾回收?
一般来说, 垃圾回收(GC)就是从系统中删除未使用的对象,并释放分配给它们的计算资源。 GC 存在于所有的高级编程语言中,较低级的编程语言通过系统库实现 GC。
GC 最常见的算法之一是 mark-and-sweep,这个算法会标记将删除的对象,再进行删除,如下图所示:
K8sMeetup
OwnerRefernce
在面向对象的语言中,一些对象会引用其他对象或者直接由其他对象组成,k8s 也有类似形式,例如副本集管理一组 Pod,而 Deployment 又管理着副本集。
但与面向对象语言不同的是,在 K8s 对象的定义中,没有明确所有者之间的关系,那么系统要如何确定它们的关系呢?其实,在 K8s 中,每个从属对象都具有 唯一数据字段名称
metadata.ownerReferences
用于确定关系。
从 Kubernetes v1.8 开始,K8s 对于 ReplicaSet、StatefulSet、DaemonSet、Deployment、Job、 CronJob 等创建或管理的对象,会自动为其设置 ownerReferences 的值。如果有需要,我们还可以手动设置 ownerReferences。
以下内容显示了 core-dns Deployment 上
metadata.ownerReferences
的值。
k get deployment -n kube-system -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES
coredns 2/2 2 2 44d coredns k8s.gcr.io/coredns:1.6.7
k 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"
}
]
认真观察上述命令的输出,其实它和其他对象 GC 之间是有些许差别的。对象关联参考金字塔是颠倒的:
K8sMeetup
K8s 的垃圾回收策略
如前面所讲,在 Kubernetes v1.8 之前,依赖对象逻辑删除的实现是在客户端,对于某些资源而言则是在控制器端。有时,客户端会中途失败,导致集群状态混乱,需要手动清理。后来为了解决这个问题,K8s 社区引入并实现了 Garbage Collector Controller(垃圾回收器) ,用更好用且更简单的方式实现 GC。在 K8s 中,有两大类 GC:
-
级联(Cascading) :在级联删除中,所有者被删除,那集群中的从属对象也会被删除。
-
孤儿(Orphan) :这种情况下,对所有者的进行删除只会将其从集群中删除,并使所有对象处于“孤儿”状态。
级联删除
在级联删除(cascading deletion strategy)中,从属对象(dependent object)与所有者对象(owner object)会被一起删除。在级联删除中,又有两种模式: 前台(foreground) 和 后台(background) 。
前台级联删除(Foreground Cascading Deletion) :在这种删除策略中,所有者对象的删除将会持续到其所有从属对象都被删除为止。当所有者被删除时,会进入“正在删除”(deletion in progress)状态,此时:
-
对象仍然可以通过 REST API 查询到(可通过 kubectl 或 kuboard 查询到)
-
对象的 deletionTimestamp 字段被设置
-
对象的 metadata.finalizers 包含值 foregroundDeletion
一旦对象被设置为 “正在删除” 状态,垃圾回收器将删除其从属对象。当垃圾回收器已经删除了所有的“blocking”从属对象(ownerReference.blockOwnerDeletion=true 的对象)以后,将删除所有者对象。
后台级联删除(Background Cascading Deletion) :这种删除策略会简单很多,它会立即删除所有者的对象,并由垃圾回收器在后台删除其从属对象。这种方式比前台级联删除快的多,因为不用等待时间来删除从属对象。
孤儿删除
在 孤儿删除策略(orphan deletion strategy) 中,会直接删除所有者对象,并将从属对象中的 ownerReference 元数据设置为默认值。之后垃圾回收器会确定孤儿对象并将其删除。
K8sMeetup
垃圾回收器如何工作?
如果对象的 OwnerReferences 元数据中没有任何所有者对象,那么垃圾回收器会删除该对象。 垃圾回收器由 Scanner、Garbage Processor 和 Propagator 组成 :
Scanner :它会检测 K8s 集群中支持的所有资源,并通过控制循环周期性地检测。它会扫描系统中的所有资源,并将每个对象添加到"脏队列"(dirty queue)中。
Garbage Processor :它由在"脏队列"上工作的 worker 组成。每个 worker 都会从"脏队列"中取出对象,并检查该对象里的 OwnerReference 字段是否为空。如果为空,那就从“脏队列”中取出下一个对象进行处理;如果不为空,它会检测 OwnerReference 字段内的 owner resoure object 是否存在,如果不存在,会请求 API 服务器删除该对象。
Propagator :用于优化垃圾回收器,它包含以下三个组件:
-
EventQueue :负责存储 k8s 中资源对象的事件
-
DAG(有向无环图) :负责存储 k8s 中所有资源对象的 owner-dependent 关系
-
Worker :从 EventQueue 中取出资源对象的事件,并根据事件的类型会采取操作
在有了 Propagator 的加入之后,我们完全可以仅在 GC 开始运行的时候,让 Scanner 扫描系统中所有的对象,然后将这些信息传递给 Propagator 和“脏队列”。只要 DAG 一建立起来之后,那么 Scanner 其实就没有再工作的必要了。
总体而言,K8s 中 GC 的实现是非常通用且非常有效,希望这篇文章可以帮助大家更加了解 K8s 中的 GC。
https://sparsecode.io/garbage-collection-in-k8s.html
推荐阅读:
在看点一下
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Go 语言的垃圾回收演化历程:垃圾回收和运行时问题
- 垃圾回收2:垃圾收集算法
- 垃圾收集3: 垃圾回收器
- 垃圾回收算法(7)-分代回收算法
- JAVA 垃圾回收机制(二) --- GC回收具体实现
- 对象回收判定与垃圾回收算法-JVM学习笔记(1)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
你必须知道的213个C语言问题
范立锋、李世欣 / 人民邮电出版社 / 2010-6 / 45.00元
《你必须知道的213个C语言问题》精选了213个在C语言程序设计中经常遇到的问题,目的是帮助读者解决在C语言学习和开发中遇到的实际困难,提高读者学习和开发的效率。这些问题涵盖了C语言与软件开发、C语言基础、编译预处理、字符串、函数、键盘操作、文件、目录和磁盘、数组、指针和结构、DOS服务和BIOS服务、日期和时间、重定向I/O和进程命令、C语言开发常见错误及程序调试等内容,均是作者经过充分的调研,......一起来看看 《你必须知道的213个C语言问题》 这本书的介绍吧!