【k8s】使用Finalizers控制k8s资源删除

news2024/12/28 5:00:42

文章目录

  • 词汇表
  • 基本删除操作
  • Finalizers是什么?
  • Owner References又是什么?
  • 强制删除命名空间
  • 参考

你有没有在使用k8s过程中遇到过这种情况: 通过kubectl delete指令删除一些资源时,一直处于Terminating状态。
这是为什么呢?

本文将介绍当你执行kubectl delete语句时,K8s内部都执行了哪些操作。
以及为何有些资源’删除不掉’(具体表现为一直Terminating,删除namespace时很容易遇到这种情况)

接下来,我们聚焦讨论以下四个方面:

资源的哪些属性会对删除操作产生影响?

  • finalizers与owner references属性是如何影响删除操作的?
  • 如何利用Propagation Policy(分发策略)更改删除顺序?
  • 删除操作的工作原理?

方便起见,以下所有示例都将使用ConfigMaps和基本shell命令来演示该过程

词汇表

  • 资源: k8s的资源对象(如configmap, secret, pod…)
  • finalizers: 终结器,存放键的列表。列表内的键为空时资源才可被删除
  • owner references: 所有者引用(归谁管理/父资源对象是谁)
  • kubectl: K8s客户端工具

基本删除操作

Kubernetes提供了几个不同的命令,您可以使用它们来创建、读取、更新和删除对象。
出于本文的目的,我们将重点讨论四个kubectl命令:create、get、patch和delete.

下面是kubectl delete命令的基本示例

创建名为mymap的configmap对象:

$ kubectl create configmap mymap
configmap/mymap created

查看名为mymap的configmap对象:

$ kubectl get configmap/mymap
NAME    DATA   AGE
mymap   0      12s

删除名为mymap的configmap对象:

$ kubectl delete configmap/mymap
configmap "mymap" deleted

基本delete命令的删除操作状态图非常简单:

在这里插入图片描述
删除操作看似简单,但是有很多因素可能会干扰删除,包括finalizers与owner references属性

Finalizers是什么?

上面我们提到了两个属性:finalizers与owner references可能会干扰删除操作,导致删除阻塞或失败。
那Finalizers是什么?会对删除有何影响呢?

当要理解Kubernetes中的资源删除原理时,了解finalizers(以下我们称finalizers为终结器)的工作原理是很有帮助的,
可以帮助您理解为什么有些对象无法被删除。

终结器是资源发出预删除操作信号的属性,
控制着资源的垃圾收集,并用于提示控制器在删除资源之前执行哪些清理操作。

finalizers本质是包含键的列表,不具有实际意义。与annotations(注释)类似,finalizers是可以被操作的(增删改)。

以下终结器您可能遇到过:

  • kubernetes.io/pv-protection
  • kubernetes.io/pvc-protection

这两个终结器作用于卷,以防止卷被意外删除。

类似地,一些终结器可用于防止资源被删除,但不由任何控制器管理。
下面是一个自定义的configmap,它没有具体值,但包含一个终结器:

$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: mymap
  finalizers:
  - kubernetes
EOF

终结器通常用于名称空间(namespace),而管理configmap资源的控制器不知道该如何处理finalizers字段。
下面我们尝试删除这个configmap对象:

$ kubectl delete configmap/mymap &
configmap "mymap" deleted
$ jobs
[1]+  Running kubectl delete configmap/mymap

Kubernetes返回该对象已被删除,然而它并没有真正意义上被删除,而是在删除的过程中。
当我们试图再次获取该对象时,我们发现该对象多了个deletionTimestamp(删除时间戳)字段。

$ kubectl get cm mymap -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: "2021-09-29T11:04:40Z"
  deletionGracePeriodSeconds: 0
  deletionTimestamp: "2021-09-29T11:04:55Z"
  finalizers:
  - kubernetes
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:finalizers:
          .: {}
          v:"kubernetes": {}
    manager: kubectl
    operation: Update
    time: "2021-09-29T11:04:40Z"
  name: mymap
  namespace: default
  resourceVersion: "1378430"
  selfLink: /api/v1/namespaces/default/configmaps/mymap
  uid: 8d6ca0b1-4840-4597-8164-a63b526dbf5f

简而言之,当我们删除带有finalizers字段的对象时,该对象仅仅是被更新了,被标记为待删除状态,而不是被删除了。
这是因为Kubernetes获取到该对象包含终结器,通过添加deletionTimestamp(删除时间戳)字段将其置于只读状态(删除终结器键更新除外)。
换句话说,在删除该对象终结器之前,删除都不会完成。

接下来我们尝试通过patch命令删除终结器,并观察configmap/mymap是否会被’真正’删除。

$ kubectl patch configmap/mymap \
    --type json \
    --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
configmap/mymap patched

再次检索该对象:

$ kubectl get cm mymap
Error from server (NotFound): configmaps "mymap" not found

发现该对象已被真正删除,下图描述了带有finalizers字段的对象删除流程:
在这里插入图片描述

总结:当您试图删除一个带有终结器的对象,它将一直处于预删除只读状态,
直到控制器删除了终结器键或使用Kubectl删除了终结器。一旦终结器列表为空,Kubernetes就可以回收该对象,并将其放入要从注册表中删除的队列中

  • 对象存在finalizers,关联的控制器故障未能执行或执行finalizer函数hang住: 比如namespace控制器无法删除完空间内所有的对象,
    特别是在使用aggregated apiserver时,第三方apiserver服务故障导致无法删除其对象。
    此时,需要会恢复第三方apiserver服务或移除该apiserver的聚合,具体选择哪种方案需根据实际情况而定。
  • 集群内安装的控制器给一些对象增加了自定义finalizers,未删除完fianlizers就下线了该控制器,导致这些fianlizers没有控制器来移除他们。
    此时,需要恢复该控制器会手动移除finalizers(多出现于自定义operator),具体选择哪种方案根据实际情况而定。

Owner References又是什么?

上面我们提到了两个属性:finalizers与owner references可能会干扰删除操作,导致删除阻塞或失败。
并介绍了Finalizers,接下来我们聊聊Owner References.

Owner References(所有者引用或所有者归属)描述了对象组之间的关系。
指定了资源彼此关联的属性,因此可以级联删除整个资源树。

当存在所有者引用时,将处理终结器规则。所有者引用由名称和UID组成

所有者引用相同名称空间内的链接资源,它还需要UID以使该引用生效(确保唯一)。
Pods通常具有对所属副本集的所有者引用。 因此,当Deloyment或有StatefulSet被删除时,子ReplicaSet和Pod将在流程中被删除。

我们通过下面的例子,来理解Owner References(所有者引用)的工作原理:

1.创建cm/mymap-parent对象

$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: mymap-parent
EOF

2.获取cm/mymap-parent的UID

CM_UID=$(kubectl get configmap mymap-parent -o jsonpath="{.metadata.uid}")

3.创建cm/mymap-child对象,并设置ownerReferences字段声明所有者引用(通过kind、name、uid字段确保选择器可以匹配到)

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: mymap-child
  ownerReferences:
  - apiVersion: v1
    kind: ConfigMap
    name: mymap-parent
    uid: $CM_UID
EOF

即cm/mymap-parent为cm/mymap-child的父对象,此时我们删除cm/mymap-parent对象并观察cm/mymap-child对象状态

$ kubectl get cm
NAME           DATA   AGE
mymap-child    0      2m44s
mymap-parent   0      3m

$ kubectl delete cm mymap-parent
configmap "mymap-parent" deleted

$ kubectl get cm
No resources found in default namespace.

即我们通过删除父对象,间接删除了父对象下的所有子对象。 这种删除k8s中被称为级联删除。我们可不可以只删除父对象,而不删除子对象呢?

答案是: 可以的,删除时通过添加–cascade=false参数实现,我们通过下面的例子来验证:

$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: mymap-parent
EOF

$ CM_UID=$(kubectl get configmap mymap-parent -o jsonpath="{.metadata.uid}")

$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: mymap-child
  ownerReferences:
  - apiVersion: v1
    kind: ConfigMap
    name: mymap-parent
    uid: $CM_UID
EOF

$ kubectl delete --cascade=false configmap/mymap-parent
configmap "mymap-parent" deleted

$ kubectl get cm
NAME          DATA   AGE
mymap-child   0      107s

–cascade=false参数实际改变了父-子资源的删除顺序,k8s中关于父-子资源删除策略有以下三种:

  • Foreground: 子资源在父资源之前被删除(post-order)
  • Background: 父资源在子资源之前被删除 (pre-order)
  • Orphan: 忽略所有者引用进行删除

下面这段内容比较晦涩,没太理解:

Keep in mind that when you delete an object and owner references have been specified, finalizers will be honored in the process. 
This can result in trees of objects persisting, and you end up with a partial deletion. 
At that point, you have to look at any existing owner references on your objects,
 as well as any finalizers, to understand what’s happening

强制删除命名空间

有一种情况可能需要强制删除命名空间:

如果您已经删除了一个命名空间,并删除了它下面的所有对象,但名称空间仍然存在,一般为Terminating状态。
则可以通过更新名称空间的finalize属性来强制删除该名称空间。

会话1:

$ kubectl proxy

会话2:

$ NAMESPACE_NAME=test
cat <<EOF | curl -X PUT \
  127.0.0.1:8001/api/v1/namespaces/$NAMESPACE_NAME/finalize \
  -H "Content-Type: application/json" \
  --data-binary @-
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "$NAMESPACE_NAME"
  },
  "spec": {
    "finalizers": null
  }
}
EOF

我们应该谨慎思考是否强制删除命名空间,因为这样做可能只删除名称空间,命名空间下的其他资源删不完全,最终导致留下孤儿对象。
比如资源对象A存在于ddd命名空间,此时若强制删除ddd命名空间, 且对象A又未被删除,那么对象A便成了孤儿对象。

参考

使用Finalizers控制k8s资源删除
[kubernetes]Finalizers和优雅终止解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1314721.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker-consule 服务发现与注册

consul服务更新和服务发现 什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构&…

CSS margin-trim

margin-trim 主角登场主角的局限性兼容性 margin-trim &#x1f9ea;这是一个实验性的属性, 目前仅有 Safari 支持 看这个属性的名字就知道, 外边距修剪. 平常都会遇到一些排版上的问题, 比如垂直排列的元素之间增加下外边距 <div><li>123</li><li>…

提前预警,时刻守护:迅软DLP的数据安全先锋

许多数据泄密事件的发生&#xff0c;往往都是由于没有在案发事前做好安全保护&#xff0c;使得重要信息被随意攻击、盗取、泄密。比起在危机发生后亡羊补牢&#xff0c;更重要的是应该在案发之前未雨绸缪。迅软DLP作为迅软股份研发的“重磅选手”&#xff0c;可为政企单位在一切…

中职网络安全应急响应—Server2228

应急响应 任务环境说明: 服务器场景:Server2228(开放链接) 用户名:root,密码:p@ssw0rd123 1. 找出被黑客修改的系统别名,并将倒数第二个别名作为Flag值提交; 通过用户名和密码登录系统 在 Linux 中,利用 “alias” 命令去查看当前系统中定义的所有别名 flag:ss …

Springboot的火车票订票系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; Springboot的火车票订票系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#…

案例067:基于微信小程序的小区租拼车管理信息系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

获取和移除cookie的方法

下载npm的cookie插件, 在utils.js文件中引入插件: 封装原始的Cookies.get()方法: 在xxxx.vue文件中引入方法: 使用getCookie方法获取cookie: 封装 移除cookie: export const removeCookie name>{ const options { path: /, domain: xxx.com }; Cookies.remove(name, opti…

C#winform实现单页面自由切换窗口

一、介绍 这是效果图&#xff0c;由于视频压缩画质很差&#xff0c;看个效果就好。 左侧是打开界面的按钮&#xff0c;点击左侧按钮右侧打开不同窗口&#xff0c;点击右侧窗口中的按钮&#xff0c;也可以切换页面&#xff0c;可以方便的进行返回、下一页等操作。 每个窗口打开…

牛客后端开发面试题1

滴滴2022 1.redis过期策略 定时删除&#xff0c;定期删除&#xff0c;惰性删除 定时删除&#xff1a;设定一个过期时间&#xff0c;时间到了就把它删掉&#xff0c;对cpu不太友好&#xff0c;但是对内存友好 定期删除&#xff1a;每隔一个周期删除一次&#xff0c;对cpu和内存…

将 Github token 添加至远程仓库

将 Github token 添加至远程仓库后便于每次 push 重复输入的麻烦 首先,将已生成的 token 记录(注:生成后的 token 确认后便无法查看只能重新生成)并找到对应的项目 git 本地文件路径下 其次,将其与项目所关联,按如下格式配置即可 token 格式类似于 ghp_CAxxxxxxxxxxxxxxxxxGx5j…

MUR6060PT-ASEMI低功耗半导体二极管MUR6060PT

编辑&#xff1a;ll MUR6060PT-ASEMI低功耗半导体二极管MUR6060PT 型号&#xff1a;MUR6060PT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-247 特性&#xff1a;插件、快恢复二极管 最大平均正向电流&#xff1a;60A 最大重复峰值反向电压&#xff1a;600V 恢复时间&am…

金蝶云星空表单插件获取复选框的值

文章目录 金蝶云星空表单插件获取复选框的值 金蝶云星空表单插件获取复选框的值 object getPur this.View.Model.GetValue("F_XHWT_IsPur", rowIndexV);bool isSerial !Convert.ToBoolean(itemClose["F_XHWT_IsPur"] "");取得值可以直接转换成…

Python 自动化之收发邮件(二)

发邮件之Windows进程监控 文章目录 发邮件之Windows进程监控前言一、基本内容二、基本结构三、库模块四、函数模块1.进程监控2.邮件发送 五、程序运行模块1.获取时间2.用户输入3.进程监控3.1进程启动发邮件3.2进程停止发邮件 总结 前言 上一篇简单写了一下如何进行邮件的收发操…

11.1.0iPortal之新增【增强其他服务注册能力】

作者&#xff1a;yx 文章目录 前言 一、使用场景二、功能说明三、举例说明 前言 11.1.0版本以前&#xff0c;注册服务的地址必须是可以访问的&#xff0c;否则会注册失败&#xff0c;如下图所示&#xff1a; 11.1.0版本开始新增“服务在线检测”功能&#xff0c;即可以实现注…

【Android】在Android上使用mlKit构建人脸检测程序

在Android上构建人脸检测程序 目录 1、导入mlKit依赖包2、配置人脸检测器并且获取人脸检测器3、加载图片资源4、调用人脸检测器5、绘制矩形边框6、完整代码7、效果展示 1、导入mlKit依赖包 dependencies {// ...// Use this dependency to bundle the model with your appi…

使用 TensorFlow 创建生产级机器学习模型(基于数据流编程的符号数学系统)——学习笔记

资源出处&#xff1a;初学者的 TensorFlow 2.0 教程 | TensorFlow Core (google.cn) 前言 对于新框架的学习&#xff0c;阅读官方文档是一种非常有效的方法。官方文档通常提供了关于框架的详细信息、使用方法和示例代码&#xff0c;可以帮助你快速了解和掌握框架的使用。 如…

关于嵌入式开发的一些信息汇总:C标准、芯片架构、编译器、MISRA-C

关于嵌入式开发的一些信息汇总&#xff1a;C标准、芯片架构、编译器、MISRA-C 关于C标准芯片架构是什么&#xff1f;架构对芯片有什么作用&#xff1f;arm架构X86架构mips架构小结 编译器LLVM是什么&#xff1f;前端在干什么&#xff1f;后端在干什么&#xff1f; MISRA C的诞生…

使用国内镜像源安装opencv

在控制台输入命令&#xff1a; pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple 验证安装&#xff1a; step 1&#xff1a; 打开终端&#xff1b;step 2&#xff1a; 输入python&#xff0c;进入Python编译环境&#xff1b;step 3&#xff1a; 粘贴…

基于若依搭建微服务nacos版本(ruoyi-Cloud前后端分离)

说明&#xff1a;本文介绍基于Ruoyi-Cloud前后端分离nacos版本的微服务从0到1的搭建过程&#xff0c;同时新增一个新的微服务模块。是基于官方文档的补充说明&#xff0c;需要结合Ruoyi-Cloud的官方文档 https://doc.ruoyi.vip/ruoyi-cloud/ 如果直接查看官方文档便可成功部署&…

LeetCode刷题--- 全排列

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 【 http://t.csdnimg.cn/yUl2I 】 【C】 【 http://t.csdnimg.cn/6AbpV 】 数据结构与算法 【 http://t.csdnimg.cn/hKh2l 】 前言&…