OpenAI 宕机思考丨Kubernetes 复杂度带来的服务发现系统的风险和应对措施

本文涉及的产品
性能测试 PTS,5000VUM额度
云原生网关 MSE Higress,422元/月
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介: Kubernetes 体系基于 DNS 的服务发现为开发者提供了很大的便利,但其高度复杂的架构往往带来更高的稳定性风险。以 Nacos 为代表的独立服务发现系统架构简单,在 Kubernetes 中选择独立服务发现系统可以帮助增强业务可靠性、可伸缩性、性能及可维护性,对于规模大、增长快、稳定性要求高的业务来说是一个较理想的服务发现方案。希望大家都能找到适合自己业务的服务发现系统。

作者:王建伟(正己)


12 月 11 日,OpenAI 旗下 AI 聊天机器人平台 ChatGPT、视频生成工具 Sora 及其面向开发人员的 API 自太平洋时间下午 3 点左右起发生严重中断,耗费约三个小时才顺利恢复所有服务。


OpenAI 在事后报告中写道,“该问题源自新部署的遥测服务,此项服务无意间压垮了 Kubernetes 控制平面,导致关键系统发生连锁故障。引发事故的根本原因就是新的遥测服务配置意外在大规模集群中产生了大量 Kubernetes API 负载,导致控制平面不堪重负并破坏了基于 DNS 的服务发现能力。”


可见,即使如实力强大的 OpenAI,面对复杂 Kubernetes 架构,也不能很好处理 Kubernetes 服务发现和控制面解耦的问题。造成这个问题的关键原因在于容器调度和业务关键服务发现链路耦合在一起,互相干扰,Kubernetes 控制面故障影响了业务服务发现链路。那么,Kubernetes 体系下应如何选择服务发现系统,进一步提升业务稳定性呢?


笔者认为,大型业务的服务发现系统应该具备高可靠性,高可伸缩性,高性能及高可维护性等特点,采用独立服务发现系统是一种相对较好的方案。本文以社区主流服务发现系统 Nacos 为例,从可靠性、可伸缩性、高性能、可维护性等 4 个方面探讨如何提升 Kubernetes 中微服务应用的稳定性。


01 如何提升系统可靠性


产品、系统在规定的条件下,规定的时间内,完成规定功能的能力称为可靠性。


解耦控制面与运行时

众所周知,Kubernetes 主要工作资源调度,更偏向运维系统一些。从架构合理性上讲,运行时与控制面的系统不应耦合在一起,甚至即使运维系统挂了也不会影响运行时。服务发现是运行时需求,而 Kubernetes 服务发现与运维系统绑定,一旦 Kubernetes 故障,上层运行态应用会受到致命影响。


Kubernetes 服务发现依赖 API Server,而 API Server 被非常多的组件调用,任何组件异常调用都有可能把 API Server 打挂,进而影响服务发现。以 OpenAI 这次故障为例,本来是要增强系统的可观测性, 但因可观测组件的大量调用把 API Server 打挂了,导致系统 DNS 解析发生故障。如果服务发现体系相对独立,不依赖或弱依赖 Kubernetes 控制面,本次故障是可以避免的。


Nacos 作为独立注册配置中心,可以不依赖 Kubernetes 独立部署,面向运行时设计,且有遵循多项面向失败原则,帮助业务服务发现与底层运维系统结构隔离,做到运维态系统故障不影响运行态系统,大大提高系统可靠性。


提升系统容灾能力

首先,Nacos 可以帮助提升部署在 Kubernetes 上微服务体系的容灾能力。先讲一个实际案例,2023 年 11 月,国内某头部出行服务公司的 app 突然出现大面积报错,导致长达几十个小时的服务不可用,影响大量用户正常出行。据官方发布通过,此次故障原因是底层软件异常导致(据推测为 Kubernetes 升级出现异常)。


对于大规模微服务系统,Kubernetes 集群容灾是系统稳定性非常重要的一环。通常,为了实现 Kubernetes 集群级别容灾,我们通常会把应用部署在多个 Kubernetes 上。这样,即使一个 Kubernetes 集群出现问题,还有另一个集群可以提供服务。但因 Kubernetes 服务发现是面向本集群内的,多 Kubernetes 部署之后,应用间的服务发现,尤其是跨 Kubernetes 集群服务发现会变得比较困难。


Nacos 作为独立的注册配置中心,可以不依赖 Kubernetes 独立部署。因此,如果在多 Kubernetes 引入 Nacos 作为注册配置中心,跨 Kubernetes 的服务发现问题就迎刃而解了。下图给出了 Nacos 作为独立注册配置中心的一个架构示意图。

image.png

  • Nacos 独立于业务应用部署,可以部署在独立 Kubernetes 中也可以部署在其他平台上;
  • 业务应用部署在两个 Kubernetes 集群上,服务提供者向 Nacos 注册服务;
  • 服务订阅者从 Nacos 订阅服务,发起服务调用。


从上图可知,任何一个 Kubernetes 集群出现故障都不会影响整个系统的服务。因此,Nacos 能大幅提升 K8s 体系微服务系统的可靠性。


面向失败设计

针对微服务系统常见的问题,Nacos 做了多项面向失败的设计,帮助提升系统可靠性。本节重点介绍其中两个:客户端缓存和推空保护。


客户端缓存提高极端情况下系统可靠性

在 Kubernetes 系统中,CoreDNS 是服务发现的核心组件,所有 DNS 请求都经过CoreDNS。一旦 CoreDNS 故障,所有服务调用都会受到影响。跟 Kubernetes 服务发现不同,Nacos 客户端保存了缓存数据,在服务端故障无法更新服务 IP 列表的情况下,可以继续使用缓存提供服务,不会影响运行时服务调用。

image.png

推空保护防止服务实例被误下线

当 Nacos 服务端发现某个服务下的实例全部下线时,可以自动触发保护逻辑,不会给客户端推送空 IP 列表。推空保护策略能预防因网络抖动或运维失误等导致的服务实例全部异常下线问题,保障业务运行可靠性。


02 如何提升系统可伸缩性


信息系统不需要对本身进行大量修改,只需要通过增加软硬件资源使服务容量产生线性(理想情况下)增长的特性称为可伸缩性。


在微服务架构下,传统单体应用被切分为多个小应用提供某些独立功能。随着业务发展,服务数量可能会出现爆发式增长。以淘宝为例,仅仅 3 年时间微服务实例规模就从十万级别暴涨到了百万级别。微服务数量爆发式增长对注册配置中心的可伸缩性提出了很高的要求。


Kubernetes 服务发现的核心组件之一是 etcd,系统所有微服务相关数据均存储于其中。但 etcd 是基于 raft 一致性协议开发的系统,Raft 协议本身的特性决定所有写操作必须由 Leader 执行。因此,etcd 可伸缩性较差,无法通过水平扩容解决微服务大规模增长带来的压力。

image.png

那如何提升系统的可伸缩性呢?一种方案是业务拆分,即把业务按照一定的逻辑拆分到多个 Kubernetes 集群,每个 Kubernetes 内部业务封闭,但成本很高,可能会改变整个业务架构;另一种方案是引入可伸缩性好的注册配置中心。


与 etcd 不同,Nacos 服务发现能力基于自研的 Distro 协议构建,每个服务端均可提供写服务,其性能随着系统的水平扩展而提高。因此,Nacos 作为 Kubernetes 集群的注册配置中心,可以大幅提高整个系统的可伸缩能力。

image.png


03 如何提升系统性能


Kubernetes 系统内服务发现主要有两种方式:环境变量和 DNS。默认情况下,Kubernetes 会为每个服务自动生成一个环境变量,并注入到 Pod 中。如果业务规模很大,环境变量过多的问题就不可避免。环境变量过多会导致 Pod 启动过程很慢,笔者就多次遇到环境变量过多导致 Pod 无法启动的问题。


DNS 服务发现方式允许开发者像调用普通域名一样调用 Kubernetes 内的服务,为多语言技术栈开发带来了很大便利。但频繁的 DNS 解析一方面会导致请求响应时间变慢,另一方面也会有一定的资源消耗。笔者曾做过一个简单的实验,对比直接以 DNS 域名方式调用和以 IP 直连方式调用的响应时间。结果显示,平均每次调用DNS 方式的 RT 比直连慢 3%-5%。3%-5% 的延迟看起来微不足道,复杂业务可能都会有多次甚至几十次的调用,累积起来的延迟对终端用户的体验影响还是比较大的。


而 Nacos 服务发现方式,通常和微服务框架(SpringCloud/Dubbo 等)结合,推送 IP 列表给框架,然后框架用IP直连的方式发起调用,省去了 DNS 解析的消耗。


下图简要画出了 DNS 解析和 IP 直连方式的区别。

image.png

因此,对于技术栈统一的微服务架构,使用 Nacos 作为注册配置中心,可以进一步缩短响应时间提升系统吞吐量。


04 如何提升系统可维护性


系统发生故障后能够排除(或抑制)故障予以修复,并返回到原来正常运行状态的可能性称之为可维护性。


简化服务发现链路,降低维护成本

K8s 服务发现依赖组件众多,下图给出了其典型架构。可以看到整个链路很复杂,涉及到 api-server、etcd、kube-dns/coredns、kubelet、kube-proxy、iptables、ipvs 等组件。一个 Pod 从扩容到最终接收到请求大概需要 10 步。


1. 创建 Pod

2. 创建 Service

3. kubelet 检测 Pod 健康状态,并上报给 api-server

4. api-server 更新数据到 etcd

5. kube-proxy从api-server 收到 service 变更

6. kube-proxy 调用 iptables/ipvs 设置转发规则

7. kube-dns/coredns 从 api-server 监听到服务变化,更新 dns 解析记录

8. 调用方 pod 从 kube-dns/coredns 解析 service,得到 cluster ip

9. 调用方 pod 用拿到的 cluster ip 发起调用

10. 请求经过 iptables/ipvs 转发链到达服务提供方 pod

image.png

而 Nacos 的服务发现工作原理,如下图所示,涉及组件更少,只有 Nacos Sdk 和 Nacos Server;一个 Pod 从创建到最终接收到请求大概只需要 5 步:


1. 创建 Pod

2. 服务提供方 Pod 注册服务到 Nacos,并自动持续汇报心跳

3. 服务调用方 Pod 从 Nacos 订阅服务,拿到服务 IP 列表

4. 服务调用方使用 Pod IP 发起调用

5. 请求打到服务提供方 Pod

image.png

可以看出,相比 Kubernetes,Nacos 注册中心服务发现链路更短,涉及组件少。对于大规模微服务系统,采用 Nacos 作为注册配置中心,可以大幅提升系统的可维护性。


Kubernetes 与非 Kubernetes 服务互相发现,提升架构兼容性

随着 Kubernetes 的普及,新增系统通常选择直接部署在 Kubernetes 中。但仍有很多存量应用部署在传统虚拟机或物理机上。这两类应用经常互相调用,因此它们能互相发现变得十分必要。然而 Kubernetes 服务发现与 K8s 运维系统绑定,Kubernetes 服务要发现外部服务或被外部服务发现比较困难。如前所述,Nacos 是独立系统,对接入应用的部署平台没有限制,支持 Kubernetes 应用与非 Kubernetes 应用互相发现,下图是使用 Nacos 后 Kubernetes 与非 Kubernetes 应用互相发现的示意图。

image.png


05 Nacos 服务发现与 Kubernetes 服务发现特性对比


最后,下面表格中给出了 Nacos 服务发现与 Kubernetes 服务发现特性对比,方便大家选出更适合自己业务的微服务注册配置中心。


特性 Nacos Kubernetes
多K8s或非K8s服务互相发现
  • 支持
  • 不支持
控制面与运行时耦合
注册方式
  • SDK
  • HTTP API
  • 控制台
  • HTTP API
发现方式
  • SDK
  • HTTP API
  • DNS
  • 环境变量
  • DNS
健康检查
  • 心跳上报
  • HTTP
  • TCP
  • HTTP
  • TCP
  • 脚本
负载均衡
  • 基于权重随机
  • 支持自定义负载均衡插件
  • 依赖IPVS负载均衡能力,负载均衡方式更多
性能与可伸缩性
  • 自研distro一致性协议,水平扩展能力强
  • IP直连调用,性能高
  • 服务调用经过DNS解析、iptables和ipvs转发,有一定性能损耗
可维护性
  • 架构原理简单,运维及故障恢复成本低
  • 架构原理复杂,运维及故障恢复成本高
服务治理
  • 控制台功能丰富
支持服务增删查改等功能;支持服务调用关系查询;支持权重及上下线操作;
  • 控制台功能较弱,主要依靠kubectl命令行
生态集成
  • 支持主流rpc框架(dubbo、SpringCloud等)服务发现
  • 提供主流开发语言SDK
  • mesh生态支持较好
  • 基于DNS服务发现,多语言支持好


06 总结


Kubernetes 体系基于 DNS 的服务发现为开发者提供了很大的便利,但其高度复杂的架构往往带来更高的稳定性风险。以 Nacos 为代表的独立服务发现系统架构简单,在 Kubernetes 中选择独立服务发现系统可以帮助增强业务可靠性、可伸缩性、性能及可维护性,对于规模大、增长快、稳定性要求高的业务来说是一个较理想的服务发现方案。希望大家都能找到适合自己业务的服务发现系统。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
12天前
|
人工智能 自然语言处理 并行计算
ASAL:Sakana AI 联合 OpenAI 推出自动探索人工生命的系统,通过计算机模拟生命进化的过程
ASAL 是由 Sakana AI 联合 OpenAI 等机构推出的自动化搜索人工生命系统,基于基础模型实现多种搜索机制,扩展了人工生命研究的边界。
64 1
ASAL:Sakana AI 联合 OpenAI 推出自动探索人工生命的系统,通过计算机模拟生命进化的过程
|
11天前
|
Kubernetes 网络协议 API
OpenAI全球宕机思考:谈谈可观测采集稳定性建设
文章探讨了为什么大规模集群中的可观测性服务会产生大量API请求、API服务器为何对DNS解析至关重要以及故障恢复过程为何缓慢的原因。
|
5月前
|
Kubernetes 负载均衡 微服务
Kubernetes 生态系统中的微服务治理
【8月更文第29天】随着微服务架构的普及,管理分布式系统的复杂性也随之增加。Kubernetes 作为容器编排的事实标准,为微服务架构提供了强大的支持。结合像 Istio 这样的服务网格工具,Kubernetes 能够有效地解决微服务治理中的诸多挑战,如服务发现、负载均衡、流量管理和安全策略等。
69 1
|
15天前
|
人工智能 安全 机器人
OpenAI重拾规则系统,用AI版机器人定律守护大模型安全
在人工智能领域,大语言模型(LLM)展现出强大的语言理解和生成能力,但也带来了安全性和可靠性挑战。OpenAI研究人员提出“规则基于奖励(RBR)”方法,通过明确规则引导LLM行为,确保其符合人类价值观和道德准则。实验显示,RBR方法在安全性与有用性之间取得了良好平衡,F1分数达97.1。然而,规则制定和维护复杂,且难以完全捕捉语言的多样性。论文:https://arxiv.org/pdf/2411.01111。
57 13
|
3月前
|
Kubernetes 监控 测试技术
k8s学习--基于Ingress-nginx实现灰度发布系统
k8s学习--基于Ingress-nginx实现灰度发布系统
150 2
k8s学习--基于Ingress-nginx实现灰度发布系统
|
5月前
|
存储 Kubernetes API
Kubernetes系统
8月更文挑战第23天
53 1
|
5月前
|
资源调度 Kubernetes 调度
玩转Kubernetes集群:掌握节点和Pod自动扩缩容,让你的系统更智能、更高效!
【8月更文挑战第22天】Kubernetes的核心功能之一是自动扩缩容,确保系统稳定与高可用。节点自动扩缩容由调度器和控制器管理器协作完成,依据资源紧张程度动态调整。主要采用HPA、VPA及Cluster Autoscaler实现。Pod自动扩缩容通常通过HPA控制器按需调整副本数量。例如,设置HPA控制器监视特定部署的CPU使用率,在80%阈值上下自动增减副本数。合理利用这些工具可显著提升系统性能。
131 2
|
5月前
|
存储 Kubernetes API
|
5月前
|
存储 Kubernetes 调度
通过重新构建Kubernetes来实现更具弹性的容器编排系统
通过重新构建Kubernetes来实现更具弹性的容器编排系统
69 8
|
5月前
|
存储 缓存 Kubernetes
在K8S中,集群节点宕机,可能由哪些原因造成?
在K8S中,集群节点宕机,可能由哪些原因造成?

热门文章

最新文章