关于Kubernetes garbage collection的经验教训

前一段时间,笔者学到了一个关于Kubernetes的重要教训。故事从Kubernetes Operators开始,这是一种打包、部署和管理Kubernetes应用程序的方法。笔者犯的错误是集群中的garbage collection——它会清理不再有owner对象的对象(稍后会详细介绍)。             

任务              

去年,笔者的团队被指派开发一个Kubernetes Operator。对于团队中的大多数人来说,这是他们第一次体验Operator SDK(软件开发工具包)和Kubernetes controller(Kubernetes的控制回路)。

我们阅读了一些关于Operator SDK的基本介绍信息,并遵循了用Go编程语言构建Operator的快速入门指南。我们也学到了一些基本原则和一些简单的技巧。             

我们的任务是为数个项目开发一个能够安装、配置和确保生产就绪的Operator。我们的目标是自动化管理一组实例,只需要站点可靠性工程(SRE)团队进行极少的手动操作。这不是一项容易的任务。             

Bug来了

最初,我们追求概念验证实现,因此我们记录了一些bug,并计划稍后修复它们。             

我们的bug不紧急却重要,实际上是非常重要——Operator创建的所有命名空间有时都会在没有用户任何请求的情况下终止。这种情况不常发生,所以我们决定以后再解决。             

最后,笔者从backlog中找到了这个bug,并开始寻找根本原因。Operator肯定无法终止命名空间,因为当时代码中没有任何Delete API调用,事后看来,这是第一条线索。笔者查看Kubernetes API服务器上的日志并确保日志被安全保存,然后等待问题再次发生。 

在设置的环境中发生问题后,笔者在日志中搜索以下字符串的组合:“requestURI”:“/api/v1/namespaces/my namespace”+“verb”:“delete”。             

从搜索结果中,笔者找到了正在执行命名空间删除的内容:

“user”:{“username”:"system:serviceaccount:kube-system:generic-garbage-collector".              

现在笔者知道了命名空间是如何被删除的,但不知道为什么会这样。笔者打开了Kubernetes garbage collection文档,浏览了ownerReference字段的基本信息,并思考为什么会发生这种情况。             

我们在创建的命名空间上使用了ownerReference元数据字段。所有者是由custom resource API定义的我们自己的资源。当我们的custom resource被删除时,它通过ownerReference拥有的相关命名空间也被删除。删除关联对象使卸载步骤变得轻而易举。             

笔者觉得这没什么问题,所以继续阅读日志,寻找更多线索。笔者注意到当kube-controller-manager pod重新启动时,命名空间将被删除。重新启动的原因对笔者来说很有意义:kube-controller-manager pod运行在主节点上,我们的开发集群中只有一个主节点,对于我们使用的实例大小来说,该节点上的负载非常高。             

所以笔者试着自己重现这个问题。笔者删除了kube-controller-manager pod,有一个新的出现,笔者检查了它的日志。有一次笔者看到一些关于garbage collection的日志,终于想明白了,再回去看garbage collection文档。果然,“注意:不允许跨命名空间的owner reference。这意味着:1)命名空间范围的dependents只能指定同一命名空间中的owner,以及集群范围的owner。2) 集群范围的dependents只能指定集群范围的owner,而不能指定命名空间范围的owner。”              

我们的custom resource是命名空间范围的,但命名空间是集群范围的。即使我们使用的owner reference被禁止,Kubernetes API服务器也会创建命名空间。因此,如果命名空间是用owner reference创建的,就必须删除。             

经验教训              

笔者学到的技术方面的教训很简单:不要使用在其中命名空间范围的资源拥有集群范围的资源或其他命名空间中的资源的owner reference。当你使用这些“disallowed by design”的owner reference时,只要kube controller manager pod启动,garbage collection routine就会删除你的Kubernetes资源。

更重要的教训是不要小看文档。如果笔者第一次看文档的时候更有耐心的话,肯定会节省一些时间。             

你可能会认为,如果在将无效的owner reference添加到代码库时按照笔者的建议进行操作,本可以避免这种情况。但这并没有文档记录。只有2019年2月的一个pull请求添加了关于这一点的说明——这意味着,文档总是有改进的空间。

原文链接:

https://opensource.com/article/20/6/kubernetes-garbage-collection

猜你喜欢

转载自blog.csdn.net/k8scaptain/article/details/106851365