作者|声东阿里云售后技术专家
<>强导读强>:阿里云售后技术团队的同学,每天都在处理各式各样千奇百怪的线上问题。常见的有网络连接失败,服务器宕机,性能不达标及请求响应慢等。但如果要评选的话,什么问题看起来微不足道事实上却让人绞尽脑汁,我相信肯定是“删不掉”的问题,比如文件删不掉,进程结束不掉,驱动卸载不了等。这样的问题就像冰山,隐藏在它们背后的复杂逻辑,往往超过我们的预想。
引用>背景
今天我们讨论的这个问题,跟k8集群的名称空间有关.Namespace是k8集群资源的“收”纳机制。我们可以把相关的资源”收纳”到同一个名称空间里,以避免不相关资源之间不必要的影响。
名称空间本身也是一种资源。通过集群API服务器入口,我们可以新建命名空间,而对于不再使用的名称空间,我们需要清理掉.Namespace的控制器会通过API服务器,监视集群中名称空间的变化,然后根据变化来执行预先定义的动作。
有时候,我们会遇到下图中的问题,即名称空间的状态被标记成了“Terminating",但却没有办法被完全删除。
从集群入口开始
因为删除操作是通过集群API服务器来执行的,所以我们要分析API服务器的行为。跟大多数集群组件类似,API服务器提供了不同级别的日志输出。为了理解API服务器的行为,我们将日志级别调整到最高级。然后,通过创建删除tobedeletedb这个名称空间来重现问题。
但可惜的是,API服务器并没有输出太多和这个问题有关的日志。
相关的日志,可以分为两部分:
<李>一部分是名称空间被删除的记录,记录显示客户端工具是kubectl,以及发起操作的源IP地址是192.168.0.41,这符合预期,李> <李>另外一部分是Kube控制器经理在重复地获取这个名称空间的信息。李>
Kube控制器经理实现了集群中大多数的控制器,它在重复获取tobedeletedb的信息,基本上可以判断,是命名空间的控制器在获取这个名称空间的信息。
控制器在做什么?
和上一节类似,我们通过开启Kube控制器经理最高级别日志,来研究这个组件的行为。在Kube控制器管理的日志里,可以看到名称空间的控制器在不断地尝试一个失败了的操作,就是清理tobedeletedb这个名称空间里“收”纳的资源。
怎么样删除“收纳盒”里的资源?
这里我们需要理解一点,就是名称空间作为资源的“收纳盒”,其实是逻辑意义上的概念。它并不像现实中的收纳工具,可以把小的物件收纳其中.Namespace的“收”纳实际上是一种映射关系。
这一点之所以重要,是因为它直接决定了,删除名称空间内部资源的方法。如果是物理意义上的“收纳”,那我们只需要删除“收纳盒”,里边的资源就一并被删除了。而对于逻辑意义上的关系,我们则需要罗列所有资源,并删除那些指向需要删除的名称空间的资源。
API、组版
怎么样罗列集群中的所有资源呢?这个问题需要从集群API的组织方式说起.K8s集群的API不是铁板一块的,它是用分组和版本来组织的。这样做的好处显而易见,就是不同分组的API可以独立迭代,互不影响。常见的分组如应用程序,它有v1, v1beta1和v1beta2三个版本。完整的分组/版本列表,可以使用kubectl api-versions命令看到。
我们创建的每一个资源,都必然属于某一个API分组/版本。以下边入口为例,我们指定进入资源的分组/版本为networking.k8s.io/v1beta1。
我们为什么会删除不了集群的名称空间?