Kubernetes中的垃圾回收

开发 前端
考虑一个场景; 您在Kubernetes中创建了一个部署对象; 因此,它根据提供的清单生成副本集和pod。 后来,您意识到您错过了一个容器的属性,并且为了快速修复,您编辑了部署。 版本的部署会产生新的副本集对象和更新的Pod。

 考虑一个场景; 您在Kubernetes中创建了一个部署对象; 因此,它根据提供的清单生成副本集和pod。 后来,您意识到您错过了一个容器的属性,并且为了快速修复,您编辑了部署。 版本的部署会产生新的副本集对象和更新的Pod。 知道旧的会怎样吗? 同样,如果删除部署,副本集或Pod将会发生什么。 答案是显而易见的。 删除部署将删除副本集和Pod; 否则,将会变得一团糟。

上面的陈述引出了一个更大的问题:在Kubernetes中如何实现级联删除,是否有多种级联删除策略,在K8中是否可能存在孤立对象? 看起来这是典型的垃圾回收问题。 这篇文章将讨论Kubernetes中垃圾收集的概念和实现。 首先,让我们快速探索垃圾收集。

什么是垃圾收集(GC)?

简而言之,垃圾回收就是从系统中删除未使用的对象,并释放分配给它们的计算资源。 GC出现在所有高级编程语言中,而低级编程语言通过系统库具有GC。

GC的最常见算法之一是标记扫描。 我没有介绍算法的详细信息,但是我们可以从标题有两个阶段的角度来解释它,在第一阶段中标记了在清除阶段删除的对象。

 

Kubernetes中的垃圾回收

 

> From Wikipedia

这是对GC的非常简短的说明,如果需要,请按照参考部分中发布的链接进行详细说明。 现在,我们将探讨在K8s中实现GC的方法。

业主拥有; OwnerReference元数据

像面向对象的语言一样,某些对象引用其他对象/由其他对象组成,在Kubernetes中以类似的方式,某些对象拥有其他对象。 例如,副本集是一组Pod的所有者,而部署是副本集的所有者。

与面向对象的语言不同,在K8s对象清单定义中,我们从来没有明确定义或编写与所有者相关的关系,而是系统如何确定该关系? 在K8s中,每个从属对象都有一个唯一的元数据字段名称metas.ownerReferences用于关系表示。

  • 从Kubernetes 1.8开始,K8为由特定控制器(例如ReplicaSet,StatefulSet,DaemonSet,Deployment,Job和CronJob)创建或采用的对象设置ownerReferences的值。
  • 如果需要,还可以手动设置ownerReferences。
  • 一个对象可以有多个ownerReferences,例如在名称空间中。

下面显示了Kind K8s独立群集上core-dns部署的metadata.ownerReferences值

如果仔细看一下以上命令的输出,您会发现与其他GC实现的细微差别。 对象关联参考金字塔是颠倒的,而不是常规的颠倒的。 下图将为您提供帮助。

 

Kubernetes中的垃圾回收

 

> Downside Up association of the objects in K8s

Kubernetes中的垃圾回收策略

如前所述,在Kubernetes 1.8之前,依赖对象删除逻辑的实现是在客户端,对于一些资源也是在控制器端。 客户端不是原子操作,有时中途失败会导致群集状态混乱,需要手动清理。 后来,为解决此问题,K8s社区引入并实现了垃圾收集器控制器,以更好,更简单的方式处理GC。

在用于未使用对象GC的K8中,有两大类:

  • 级联:在级联之一中,所有者的删除导致从群集中删除从属对象。
  • 孤儿:顾名思义,对所有者对象的删除操作只会将其从集群中删除,并使所有从属对象处于"孤儿"状态。

让我们深入了解上述策略。

在级联删除策略中,从属对象与所有者对象一起被删除。 在级联内,有两种模式:前景和背景。

前景级联删除:在前景策略中,所有者对象删除将一直等待,直到所有从属对象都被删除为止。 当前台删除是所有者对象状态更改为进行中的删除时,将发生第一个更改。 处于"正在删除"状态的对象的属性如下:

  • 通过REST API,该对象仍然可见
  • 设置了对象的deleteTimestamp
  • 对象的元数据.finalizers包含值" foregroundDeletion"。

一旦状态发生变化,垃圾收集器将删除所有"阻塞"依赖项(拥有者参考.blockOwnerDeletion = true的对象),最后删除拥有者对象。

背景级联删除:这要简单得多,在这种情况下,它将直接删除所有者对象。 稍后,GC确定相关对象并将其从后台删除。 它比前台快得多,因为没有等待时间来删除从属对象。

在孤立策略中,将删除所有者对象,并将从属对象中的ownerReferences元数据设置为默认值。 之后,GC控制器确定孤立对象并将其删除。

Kubernetes垃圾收集器控制器如何工作?

如果对象的OwnerReferences元数据中没有任何所有者对象,则GC控制器负责删除该对象。 GC控制器由扫描仪,垃圾处理器和传播器组成。

扫描程序:使用发现API,它会检测K8s集群中支持的所有资源,并通过控制循环定期检测它,扫描系统中的所有资源,并将每个对象添加到"脏队列"中。

垃圾处理器:由在"脏队列"上工作的工人组成。 每个工作人员都会从"脏队列"中取出一个项目,并检查该项目的OwnerReferences是否为空。 如果为空,则仅从Dirty队列中取出下一个条目进行处理; 否则,检查OwnerReferences元数据中的每个条目。 如果OwnerReferences中列出的所有所有者均不存在,则工作程序会请求API服务器删除该对象。

传播器:传播器用于优化GC控制器,包含三个组件。 事件队列,单个工作程序以及与所有者相关的关系的DAG。 以下是繁殖器的特性

  • DAG仅存储名称/ uid /孤立三元组,而不存储每个项目的整个主体。
  • 监视所有资源的创建/更新/删除事件,并将事件排入事件队列。
  • 工作者从事件队列中使项目出队。
  • K8s对象的创建或更新会相应地更新DAG。 如果资源具有所有者,但该所有者在DAG中尚不存在,则除了将对象添加到DAG之外,它还将对象排队到"脏队列"中。
  • 删除K8s对象会将其从DAG中删除,并将其所有从属对象排队到"脏队列"中。
  • 传播者不需要执行任何RPC,因此只需一个工作线程就足够了,并且锁定起来也更容易。
  • 使用传播器,我们仅需在启动GC时运行扫描程序以填充DAG和脏队列。

总体而言,Kubernetes中GC的实现是非常通用和复杂的,并且非常有效。 我希望这篇文章可以帮助您了解K8s中GC的见解。 感谢您的阅读和期待反馈或赞赏。

 

责任编辑:华轩 来源: 今日头条
相关推荐

2024-07-25 11:22:23

2017-06-12 17:38:32

Python垃圾回收引用

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2021-01-04 10:08:07

垃圾回收Java虚拟机

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2022-01-20 10:34:49

JVM垃圾回收算法

2019-12-02 16:23:03

Python编程语言“垃圾”回收

2021-03-03 08:13:57

模式垃圾回收

2011-02-28 13:38:45

PHP垃圾回收算法

2021-11-05 15:23:20

JVM回收算法

2022-06-22 09:54:45

JVM垃圾回收Java

2009-07-06 17:34:22

Java垃圾回收

2009-12-30 10:14:29

JVM垃圾回收

2011-06-28 10:19:40

C#开发

2023-03-26 22:48:46

Python引用计数内存

2024-10-28 13:18:54

2009-06-25 17:48:24

Java垃圾回收

2023-12-19 21:52:51

Go垃圾回收开发

2023-08-08 10:29:55

JVM优化垃圾回收

2010-12-13 11:14:04

Java垃圾回收算法
点赞
收藏

51CTO技术栈公众号