阿里云售后技术团队的同窗,天天都在处理各式各样千奇百怪的线上问题。常见的有,网络链接失败,服务器宕机,性能不达标,请求响应慢等。但若是要评选,什么问题看起来微不足道事实上却足以让人绞尽脑汁,我相信答案确定是“删不掉”的问题。好比文件删不掉,进程结束不掉,驱动卸载不了等。api
这样的问题就像冰山,影藏在它们背后的复杂逻辑,每每超过咱们的预想。服务器
今天咱们讨论的这个问题,跟K8S集群的命名空间有关。命名空间是K8S集群资源的“收纳”机制。咱们能够把相关的资源,“收纳”到同一个命名空间里,以免不相关资源之间没必要要的影响。网络
命名空间自己也是一种资源。经过集群API Server入口,咱们能够新建命名空间,而对于再也不使用的命名空间,咱们须要清理掉。命名空间的Controller会经过API Server,监视集群中命名空间的变化,而后根据变化来执行预先定义的动做。app
有时候,咱们会遇到下图中的问题,即命名空间的状态被标记成了“Terminating”,但却没有办法被彻底删除。工具
由于删除操做是经过集群API Server来执行的,因此咱们要分析API Server的行为。跟大多数集群组件相似,API Server提供了不一样级别的日志输出。为了理解API Server的行为,咱们将日志级别调整到最高级。而后,经过建立删除tobedeletedb这个命名空间来重现问题。性能
但惋惜的是,API Server并无输出太多和这个问题有关的日志。测试
相关的日志,能够分为两部分。一部分是命名空间被删除的记录,记录显示客户端工具是kubectl,以及发起操做的源IP地址是192.168.0.41,这符合预期;另一部分是Kube Controller Manager在重复的获取这个命名空间的信息。阿里云
Kube Controller Manager实现了集群中大多数的Controller,它在重复获取tobedeletedb的信息,基本上能够判断,是命名空间的Controller在获取这个命名空间的信息。spa
和上一节相似,咱们经过开启Kube Controller Manager最高级别日志,来研究这个组件的行为。在Kube Controller Manager的日志里,能够看到命名空间的Controller在不断地尝试一个失败了的操做,就是清理tobedeletedb这个命名空间里“收纳”的资源。3d
这里咱们须要理解一点,就是命名空间做为资源的“收纳盒”,实际上是逻辑意义上的概念。它并不像现实中的收纳工具,能够把小的物件收纳其中。命名空间的“收纳”其实是一种映射关系。
这一点之因此重要,是由于它直接决定了,删除命名空间内部资源的方法。若是是物理意义上的“收纳”,那咱们只须要删除“收纳盒”,里边的资源就一并被删除了。而对于逻辑意义上的关系,咱们则须要罗列全部资源,并删除那些指向须要删除的命名空间的资源。
怎么样罗列集群中的全部资源呢,这个问题须要从集群API的组织方式提及。K8S集群的API不是铁板一块的,它是用分组和版原本组织的。这样作的好处显而易见,就是不一样分组的API能够独立的迭代,互不影响。常见的分组如apps,它有v1,v1beta1和v1beta2这三个版本。完整的分组/版本列表,可使用kubectl api-versions命令看到。
咱们建立的每个资源,都必然属于某一个API分组/版本。如下边Ingress为例,咱们指定Ingress资源的分组/版本为networking.k8s.io/v1beta1。
kind: Ingress metadata: name: test-ingress spec: rules: - http: paths: - path: /testpath backend: serviceName: test servicePort: 80
用一个简单的示意图来总结API分组和版本。
实际上,集群有不少API分组/版本,每一个API分组/版本支持特定的资源类型。咱们经过yaml编排资源时,须要指定资源类型kind,以及API分组/版本apiVersion。而要列出资源,咱们须要获取API分组/版本的列表。
理解了API分组/版本的概念以后,再回头看Kube Controller Manager的日志,就会豁然开朗。显然命名空间的Controller在尝试获取API分组/版本列表,当遇到metrics.k8s.io/v1beta1的时候,查询失败了。而且查询失败的缘由是“the server is currently unable to handle the request”。
在上一节中,咱们发现Kube Controller Manager在获取metrics.k8s.io/v1beta1这个API分组/版本的时候失败了。而这个查询请求,显然是发给API Server的。因此咱们回到API Server日志,分析metrics.k8s.io/v1beta1相关的记录。在相同的时间点,咱们看到API Server也报了一样的错误“the server is currently unable to handle the request”。
显然这里有一个矛盾,就是API Server明显在正常工做,为何在获取metrics.k8s.io/v1beta1这个API分组版本的时候,会返回Server不可用呢?为了回答这个问题,咱们须要理解一下API Server的“外挂”机制。
集群API Server有扩展本身的机制,开发者能够利用这个机制,来实现API Server的“外挂”。这个“外挂”的主要功能,就是实现新的API分组/版本。API Server做为代理,会把相应的API调用,转发给本身的“外挂”。
以Metrics Server为例,它实现了metrics.k8s.io/v1beta1这个API分组/版本。全部针对这个分组/版本的调用,都会被转发到Metrics Server。以下图,Metrics Server的实现,主要用到一个服务和一个pod。
而上图中最后的apiservice,则是把“外挂”和API Server联系起来的机制。下图能够看到这个apiservice详细定义。它包括API分组/版本,以及实现了Metrics Server的服务名。有了这些信息,API Server就能把针对metrics.k8s.io/v1beta1的调用,转发给Metrics Server。
通过简单的测试,咱们发现,这个问题其实是API server和metrics server pod之间的通讯问题。在阿里云K8S集群环境里,API Server使用的是主机网络,即ECS的网络,而Metrics Server使用的是Pod网络。这二者之间的通讯,依赖于VPC路由表的转发。
以上图为例,若是API Server运行在Node A上,那它的IP地址就是192.168.0.193。假设Metrics Server的IP是172.16.1.12,那么从API Server到Metrics Server的网络链接,必需要经过VPC路由表第二条路由规则的转发。
检查集群VPC路由表,发现指向Metrics Server所在节点的路由表项缺失,因此API server和Metrics Server之间的通讯出了问题。
为了维持集群VPC路由表项的正确性,阿里云在Cloud Controller Manager内部实现了Route Controller。这个Controller在时刻监听着集群节点状态,以及VPC路由表状态。当发现路由表项缺失的时候,它会自动把缺失的路由表项填写回去。
如今的状况,显然和预期不一致,Route Controller显然没有正常工做。这个能够经过查看Cloud Controller Manager日志来确认。在日志中,咱们发现,Route Controller在使用集群VPC id去查找VPC实例的时候,没有办法获取到这个实例的信息。
可是集群还在,ECS还在,因此VPC不可能不在了。这一点咱们能够经过VPC id在VPC控制台确认。那下边的问题,就是为何Cloud Controller Manager没有办法获取到这个VPC的信息呢?
Cloud Controller Manager获取VPC信息,是经过阿里云开放API来实现的。这基本上等于,从云上一台ECS内部,去获取一个VPC实例的信息,而这须要ECS有足够的权限。目前的常规作法是,给ECS服务器授予RAM角色,同时给对应的RAM角色绑定相应的角色受权。
若是集群组件,以其所在节点的身份,不能获取云资源的信息,那基本上有两种可能性。一是ECS没有绑定正确的RAM角色;二是RAM角色绑定的RAM角色受权没有定义正确的受权规则。检查节点的RAM角色,以及RAM角色所管理的受权,咱们发现,针对vpc的受权策略被改掉了。
当咱们把Effect修改为Allow以后,没多久,全部的Terminating状态的namespace所有都消失了。
整体来讲,这个问题与K8S集群的6个组件有关系,分别是API Server及其扩展Metrics Server,Namespace Controller和Route Controller,以及VPC路由表和RAM角色受权。
经过分析前三个组件的行为,咱们定位到,集群网络问题致使了API Server没法链接到Metrics Server;经过排查后三个组件,咱们发现致使问题的根本缘由是VPC路由表被删除且RAM角色受权策略被改动。
K8S集群命名空间删除不掉的问题,是线上比较常见的一个问题。这个问题看起来无关痛痒,但实际上不只复杂,并且意味着集群重要功能的缺失。这篇文章全面分析了一个这样的问题,其中的排查方法和原理,但愿对你们排查相似问题有必定的帮助。
本文为云栖社区原创内容,未经容许不得转载。