记得点击上方“云原生之路”关注哦

前言

经常操作 Kubernetes 集群的同学肯定对 finalizers 字段不陌生,每当删除 namespace 或 pod 等一些 Kubernetes 资源时,有时资源状态会卡在 Terminating,很长时间无法删除,甚至有时增加 --force flag 之后还是无法正常删除。这时就需要 edit 该资源,将 finalizers 字段设置为 [],之后 Kubernetes 资源就正常删除了。

这是一个比较常见的操作,但是当有人问 finalizers 字段的作用是什么的时候,我是懵逼的,我甚至不知道这个熟悉又陌生的单词怎么读!那么这篇文章就来探索一下 finalizers 这个字段到底是做什么的,在实践中应该怎么应用这个字段。(另外,这个单词读作 ['faɪnəlaɪzər]

Finalizers

Finalizers 字段属于 Kubernetes GC 垃圾收集器,是一种删除拦截机制,能够让控制器实现异步的删除前(Pre-delete)回调。其存在于任何一个资源对象的 Meta[1] 中,在 k8s 源码中声明为 []string,该 Slice 的内容为需要执行的拦截器名称。

对带有 Finalizer 的对象的第一个删除请求会为其 metadata.deletionTimestamp 设置一个值,但不会真的删除对象。一旦此值被设置,finalizers 列表中的值就只能被移除。

当 metadata.deletionTimestamp 字段被设置时,负责监测该对象的各个控制器会通过轮询对该对象的更新请求来执行它们所要处理的所有 Finalizer。当所有 Finalizer 都被执行过,资源被删除。

metadata.deletionGracePeriodSeconds 的取值控制对更新的轮询周期。

每个控制器要负责将其 Finalizer 从列表中去除。

每执行完一个就从 finalizers 中移除一个,直到 finalizers 为空,之后其宿主资源才会被真正的删除。

// DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This
// field is set by the server when a graceful deletion is requested by the user, and is not
// directly settable by a client. The resource is expected to be deleted (no longer visible
// from resource lists, and not reachable by name) after the time in this field, once the
// finalizers list is empty. As long as the finalizers list contains items, deletion is blocked.
// Once the deletionTimestamp is set, this value may not be unset or be set further into the
// future, although it may be shortened or the resource may be deleted prior to this time.
// For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react
// by sending a graceful termination signal to the containers in the pod. After that 30 seconds,
// the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup,
// remove the pod from the API. In the presence of network partitions, this object may still
// exist after this timestamp, until an administrator or automated process can determine the
// resource is fully terminated.
// If not set, graceful deletion of the object has not been requested.
//
// Populated by the system when a graceful deletion is requested.
// Read-only.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"`
// Number of seconds allowed for this object to gracefully terminate before
// it will be removed from the system. Only set when deletionTimestamp is also set.
// May only be shortened.
// Read-only.
// +optional
DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"`
// Must be empty before the object is deleted from the registry. Each entry
// is an identifier for the responsible component that will remove the entry
// from the list. If the deletionTimestamp of the object is non-nil, entries
// in this list can only be removed.
// Finalizers may be processed and removed in any order.  Order is NOT enforced
// because it introduces significant risk of stuck finalizers.
// finalizers is a shared field, any actor with permission can reorder it.
// If the finalizer list is processed in order, then this can lead to a situation
// in which the component responsible for the first finalizer in the list is
// waiting for a signal (field value, external system, or other) produced by a
// component responsible for a finalizer later in the list, resulting in a deadlock.
// Without enforced ordering finalizers are free to order amongst themselves and
// are not vulnerable to ordering changes in the list.
// +optional
// +patchStrategy=merge
Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"`

在 Operator 中的应用

知道了 Finalizers 是什么,那么当然也要知道怎么用 Finalizers 了。在实际开发 Operator 时,删除前(Pre-delete)回调是一个比较常见的功能,用于处理一些在资源删除前需要处理的逻辑,如:关联资源释放、释放资源通知、相关数据清理,甚至是阻止资源删除。一般 Finalizers 的处理也是会 Reconcile 中实现的,下面就使用 chaosblade-operator[2] 中的源码,简单介绍一些 Finalizers 的使用方式。

首先要了解的是 ChaosBlade-Operator 的工作原理:每个实验都会以 CR 的形式部署到 k8s 集群中,之后由 chaosblade-operator 来操作以 DaemonSet 形式部署 chaosblade-tool 对具体资源进行混沌实验。停止实验只需删除对应 CR 即可,在删除 CR 时,首先会执行一遍实验恢复逻辑,之后才会将 CR 删除。但如果恢复实验失败,则会将 CR 的 Phase 设置为 Destroying,而在 Reconcile 中观测到 Phase 状态为 Destroying 或者 metadata.deletionTimestamp 不为空时,就会不会移除 finalizers 中的拦截器名称,阻止该 CR 被删除。

这样设计的目的是为了在实验恢复失败后,让用户去主动查看实验恢复失败原因,如果是一些意外原因导致的实验恢复失败,及时去处理。在确认原因后,可使用 CLI 工具增加 --force-remove 进去强制删除,项目维护者在 Issue#368[3] 中也就这个设计给出了解答。

// pkg/controller/chaosblade/controller.go 部分源码
...
const chaosbladeFinalizer = "finalizer.chaosblade.io"
...
func (r *ReconcileChaosBlade) Reconcile(request reconcile.Request) (reconcile.Result, error) {reqLogger := logrus.WithField("Request.Name", request.Name)forget := reconcile.Result{}// Fetch the RC instancecb := &v1alpha1.ChaosBlade{}err := r.client.Get(context.TODO(), request.NamespacedName, cb)if err != nil {return forget, nil}if len(cb.Spec.Experiments) == 0 {return forget, nil}// Destroyed->delete// Remove the Finalizer if the CR object status is destroyed to delete itif cb.Status.Phase == v1alpha1.ClusterPhaseDestroyed {cb.SetFinalizers(remove(cb.GetFinalizers(), chaosbladeFinalizer))err := r.client.Update(context.TODO(), cb)if err != nil {reqLogger.WithError(err).Errorln("remove chaosblade finalizer failed at destroyed phase")}return forget, nil}if cb.Status.Phase == v1alpha1.ClusterPhaseDestroying || cb.GetDeletionTimestamp() != nil {err := r.finalizeChaosBlade(reqLogger, cb)if err != nil {reqLogger.WithError(err).Errorln("finalize chaosblade failed at destroying phase")}return forget, nil}...return forget, nil
}

如果 Phase 状态为 Destroyed,则从 Finalizers 中移除 finalizer.chaosblade.io,之后正常删除 CR。

结语

在实际工作中,像 Finalizers 这样的东西太多了,很多平时挂在嘴边的东西,深究起来我们可能对其并不了解,甚至原本的理解就是错误的。在今后的文章中,除了各种实践干货,笔者还会将更多的精力投注到基本原理、底层实现、源码剖析中,更聚焦于技术本身,在不重复造轮子的基础上,学习和了解更多产品背后的代码设计和实现原理。最后在分享一句弗兰西斯·培根的话:

“人生如同道路。最近的捷径通常是最坏的路。”

引用链接

[1] Meta: https://github.com/kubernetes/apimachinery/blob/master/pkg/apis/meta/v1/types.go#L246
[2] chaosblade-operator: https://github.com/chaosblade-io/chaosblade-operator
[3] Issue#368: https://github.com/chaosblade-io/chaosblade/issues/368

熟悉又陌生的 k8s 字段:finalizers相关推荐

  1. 计算机学术周报告计,学术周,一个熟悉又陌生的名词.doc

    学术周,一个熟悉又陌生的名词 无 题 学术,一个令人心生敬畏的领域,因其神秘而向往,因我无知而无所适从.学术周,一个熟悉而又陌生的名词.在信息化社会的信息海洋中,它是一条早已现身的小鱼儿:在现实中,它 ...

  2. 一座熟悉而陌生的城市--一个程序员的成长史(7)

    回到重庆,已经是两天以后了.代是雄的老家在农村,但他并没有急着回去,而是先到一个亲戚家住下,借此机会来重新看看重庆这张"熟悉而陌生"的面孔. 代是雄是土生土长的重庆人,但老家在农村 ...

  3. 谈谈我熟悉又陌生的cookie

    前言 大概是我的业务领域比较狭窄的原因,我总是会听说cookie,却很少在实际的开发中应用或者实践过它,今天刚好看到<<JavaScript高级程序设计第三版>>的数据存储部分 ...

  4. 熟悉又陌生 彪悍徐茂栋的双面人生

    "该出手时出手,该冷静时冷静."唯快不破和专注极致,是互联网时代的两个重要铁律,作为一个20年成功的连续创业者,时任窝窝商城董事长兼CEO徐茂栋的创业经历,即是这样的体现. 外界对 ...

  5. 故地重游,熟悉又陌生。

    自从感情问题后,离开CSDN好长好长一段时间,今天鬼使神差般重游,发现竟是如此陌生,回想从前废寝忘食的情景,真是惭愧.--CSDN在不断变化,我却依然裹足不前. 不管怎样,先尝尝新鲜,长这么大了还没玩 ...

  6. 熟悉又陌生的udelay

    申请CSDN博客认证专家通过,着实让我受宠若惊,自己还是有这份自知之明,与专家 大牛这些词汇还是有很长距离. 不过认证通过给了自己一份动力,在博客上分享更多自己的所学,与大家学习交流. 内核开发中经常 ...

  7. 既熟悉又陌生的“迪杰斯特拉”

    最近看一些专业课的书籍,在不同的书本上看到了Dijkstra(迪杰斯特拉)这个名字:可以毫不夸张地说,凡是学信息相关专业的学生都应该听说过他的名字(课堂上曾提到的"迪杰斯特拉算法" ...

  8. python的字符编码叙述_Python: 熟悉又陌生的字符编码

    字符编码是计算机编程中不可回避的问题,不管你用 Python2 还是 Python3,亦或是 C++, Java 等,我都觉得非常有必要厘清计算机中的字符编码概念.本文主要分以下几个部分介绍: 基本概 ...

  9. 雅思-我们遇到过的哪些熟悉又陌生的单词1

    1.wary: be careful 2.implicit 3.intrinsically 4. unorthodox ;不正规的,非正式的 5.panci 6.debilitate

最新文章

  1. css设置并排,CSS并排排列2个div
  2. 【Network Security!】用户组管理与批处理中(:goto)的用法
  3. centos 8 卸载anaconda_CentOS 7.8 (2003) 发布,附地址
  4. java日志——基本日志+高级日志
  5. jpane1_IDEA插件开发,Jpane中集成Web页面
  6. python decimal_python学习笔记一
  7. sql azure 语法_Azure SQL Server中的CREATE DATABASE语句概述
  8. Gartner发布云安全能力评估报告:阿里云全球第二,超过亚马逊!
  9. Linux vi/vim 中的一些技巧
  10. 那些年你用过的工具--网络工具Wireshark经验谈
  11. 排队叫号python编程_排队叫号系统源程序
  12. 四金及个人所得税的计算方法
  13. 概率论_证明_伯努利大数定律
  14. Generative Adversarial Networks in Computer Vision: A Survey and Taxonomy(计算机视觉中的GANs:综述与分类)
  15. 8、智慧交通项目(1)
  16. DHCP简单拓扑图演示
  17. android+qq+4.6.2,AndroidQQ通讯录4.6闪亮登场 让你领略“超快感”
  18. 企业级SaaS私有化部署的机会和挑战
  19. 如何理解 AI + IoT = AIoT?
  20. Microsoft AppLocale Utility,微软的多语言支持工具

热门文章

  1. 二氧化铅,氧化锌,四氧化三铁-碳复合材料增容电池的方法
  2. 亲测!这款耳机堪比AirPods,还不到200块!
  3. u盘连接计算机找不到,重装系统后U盘插入电脑怎么没反应?找不到U盘盘符解决办法...
  4. 按键精灵脚本-windows桌面自动化操作
  5. 重装 Windows 系统后键乱码解决方案
  6. 路由懒加载的三种写法
  7. [大数据]数据可视化 -- 练习卷(下)
  8. PMP-PMBOK-培训(7)Initiating a Project and Preparing the Project Plan
  9. 你也遇到JSONException:create instance error, null...问题啦?
  10. 0.高仿Android网易云音乐OkHttp+Retrofit+RxJava+Glide+MVC+MVVM