写点什么

深入浅出 Kubernetes 实践篇 (三):命名空间删除问题

  • 2020-03-30
  • 本文字数:3677 字

    阅读完需:约 12 分钟

深入浅出Kubernetes 实践篇 (三):命名空间删除问题

阿里云售后技术团队的同学,每天都在处理各式各样千奇百怪的线上问题。常见的有,网络连接失败,服务器宕机,性能不达标,请求响应慢等。但如果要评选,什么问题看起来微不足道事实上却足以让人绞尽脑汁,我相信答案肯定是“删不掉”的问题。比如文件删不掉,进程结束不掉,驱动卸载不了等。


这样的问题就像冰山,影藏在它们背后的复杂逻辑,往往超过我们的预想。

背景

今天我们讨论的这个问题,跟 Kubernetes 集群的命名空间有关。命名空间是 Kubernetes 集群资源的“收纳”机制。我们可以把相关的资源,“收纳”到同一个命名空间里,以避免不相关资源之间不必要的影响。


命名空间本身也是一种资源。通过集群 API Server 入口,我们可以新建命名空间,而对于不再使用的命名空间,我们需要清理掉。命名空间的 Controller 会通过 API Server,监视集群中命名空间的变化,然后根据变化来执行预先定义的动作。



有时候,我们会遇到下图中的问题,即命名空间的状态被标记成了“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 在获取这个命名空间的信息。

Controller 在做什么?

和上一节类似,我们通过开启 Kube Controller Manager 最高级别日志,来研究这个组件的行为。在 Kube Controller Manager 的日志里,可以看到命名空间的 Controller 在不断地尝试一个失败了的操作,就是清理 tobedeletedb 这个命名空间里“收纳”的资源。



怎么样删除“收纳盒”里的资源


这里我们需要理解一点,就是命名空间作为资源的“收纳盒”,其实是逻辑意义上的概念。它并不像现实中的收纳工具,可以把小的物件收纳其中。命名空间的“收纳”实际上是一种映射关系。



这一点之所以重要,是因为它直接决定了,删除命名空间内部资源的方法。如果是物理意义上的“收纳”,那我们只需要删除“收纳盒”,里边的资源就一并被删除了。而对于逻辑意义上的关系,我们则需要罗列所有资源,并删除那些指向需要删除的命名空间的资源。


API、Group、Version


怎么样罗列集群中的所有资源呢,这个问题需要从集群 API 的组织方式说起。Kubernetes 集群的 API 不是铁板一块的,它是用分组和版本来组织的。这样做的好处显而易见,就是不同分组的 API 可以独立的迭代,互不影响。常见的分组如 apps,它有 v1,v1beta1 和 v1beta2 这三个版本。完整的分组/版本列表,可以使用 kubectl api-versions 命令看到。



我们创建的每一个资源,都必然属于某一个 API 分组/版本。以下边 Ingress 为例,我们指定 Ingress 资源的分组/版本为 networking.k8s.io/v1beta1。


kind: Ingressmetadata:  name: test-ingressspec:  rules:  - http:      paths:      - path: /testpath        backend:          serviceName: test          servicePort: 80
复制代码


用一个简单的示意图来总结 API 分组和版本。



实际上,集群有很多 API 分组/版本,每个 API 分组/版本支持特定的资源类型。我们通过 yaml 编排资源时,需要指定资源类型 kind,以及 API 分组/版本 apiVersion。而要列出资源,我们需要获取 API 分组/版本的列表。


Controller 为什么不能删除命名空间里的资源


理解了 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。


节点与 Pod 之间的通信

经过简单的测试,我们发现,这个问题实际上是 API server 和 metrics server pod 之间的通信问题。在阿里云 Kubernetes 集群环境里,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 之间的通信出了问题。

Route Controller 为什么不工作?

为了维持集群 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 全部都消失了。


问题大图

总体来说,这个问题与 Kubernetes 集群的 6 个组件有关系,分别是 API Server 及其扩展 Metrics Server,Namespace Controller 和 Route Controller,以及 VPC 路由表和 RAM 角色授权。



通过分析前三个组件的行为,我们定位到,集群网络问题导致了 API Server 无法连接到 Metrics Server;通过排查后三个组件,我们发现导致问题的根本原因是 VPC 路由表被删除且 RAM 角色授权策略被改动。

后记

Kubernetes 集群命名空间删除不掉的问题,是线上比较常见的一个问题。这个问题看起来无关痛痒,但实际上不仅复杂,而且意味着集群重要功能的缺失。这篇文章全面分析了一个这样的问题,其中的排查方法和原理,希望对大家排查类似问题有一定的帮助。


作者简介


罗建龙(花名声东),阿里云技术专家。多年操作系统和图形显卡驱动调试和开发经验。目前专注云原生领域,容器集群和服务网格。


相关阅读


深入浅出Kubernetes 实践篇 (一):节点就绪问题之一


深入浅出Kubernetes 实践篇 (二):节点就绪问题之二


2020-03-30 17:141122

评论

发布
暂无评论
发现更多内容

跨平台 SQL 编辑器和数据库查询工具RazorSQL for Mac

Mac相关知识分享

AB Micro850笔记 LD 指令块选择器与替换指令

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 使用ccw了解扩展与插件信息

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 加减乘除 取整取反取余绝对值

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 RSLinx 通信配置

万里无云万里天

自动化 PLC 工厂运维

Hides for Mac(隐藏程序Mac老板键)v6.0.1激活版

iMac小白

AB Micro850笔记 CCW F1 查看本地帮助文档

万里无云万里天

自动化 PLC 工厂运维

专业音频格式转换软件dBpoweramp Music Converter for Mac

Mac相关知识分享

软件

AB Micro850笔记 LD 逻辑运算 与或非异或

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 字符串处理

万里无云万里天

自动化 PLC 工厂运维

dBpoweramp Music Converter for Mac(音频格式转换器)R2024.09.30直装版

iMac小白

Omni Recover for Mac(iPhone数据恢复工具)v3.7.5激活版

iMac小白

大模型RAG:文档分块方案与RAG全流程

程序员架构进阶

大模型 10月月更 rag 大模型应用

AB Micro850笔记 使用ccw详细了解PLC信息

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 反向接触与反向线圈

万里无云万里天

自动化 PLC 工厂运维

技术文档管理系统精选10款:如何挑选适合您的工具

爱吃小舅的鱼

技术文档管理

Python 命名元组:让你的数据结构更具可读性与可维护性!

LLLibra146

Python namedtuple

计时与任务管理软件RH Timer pro for Mac

Mac相关知识分享

AB Micro850笔记 LD 比较大于小于 高低限值最大最小

万里无云万里天

自动化 PLC 工厂运维

Bookends for Mac(文献书籍管理工具)v15.0.7注册激活版

iMac小白

SyncBird Pro for Mac(iPhone文件管理器)v4.1.5激活版

iMac小白

AB Micro850笔记 ccw 交叉引用浏览器

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 ccw中能添加的设备一览

万里无云万里天

自动化 PLC 工厂运维

Wirecast Pro for Mac(视频直播制作工具)v16.3.0中文免激活版

iMac小白

终端仿真软件ZOC8 for Mac

Mac相关知识分享

Privatus for Mac(网页缓存清理工具)v7.1.1激活版

iMac小白

全面解析10款文档结构化管理系统,赋能企业数字化转型

爱吃小舅的鱼

文档管理 文档结构化管理

UE5+ChatGPT实现3D AI虚拟人综合实战

陆通

AB Micro850笔记 LD 直接接触与直接线圈

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 ccw 变量导出功能

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 设置线圈与重设线圈

万里无云万里天

自动化 PLC 工厂运维

深入浅出Kubernetes 实践篇 (三):命名空间删除问题_文化 & 方法_罗建龙(声东)_InfoQ精选文章