本文编译自2022稀土开发者大会。字节跳动云原生工程师张军分享了集群 kube- 的负载均衡和治理方案。
它是字节跳动针对kube-特性专门定制的七层网关。彻底解决了kube-负载的问题,同时在社区首次实现了kube-的完整治理,包括请求路由、分流、 、降级等,显着提升可用性的集群。
项目地址:
1. 背景
在一个集群中,kube-是整个集群的入口。任何用户或程序对集群资源的增删改查等操作都需要经过kube-,所以它的高可用决定了整个集群的高可用。Kube-本质上是一个无状态服务器。为了实现其高可用,通常会部署多个 kube-,并引入外部负载均衡器(以下简称 LB)进行流量代理。
为了保证集群的安全,kube- 对请求进行认证和授权,这里的认证就是识别用户的身份。支持多种认证策略,如Token、Token、Token、TLS相互认证等。
目前,kube- 使用最多的策略是 TLS 双向认证。TLS相互认证需要LB正确地将请求中的X509 Cert传递给kube-,但是传统的七层LB无法做到这一点,在转发过程中X509 Cert会丢失,导致kube-无法认证用户。
所以目前LB的选择一般是云厂商的LVS、SLB或者nginx的四层负载均衡方案。
四层负载均衡工作在OSI的第四层,即传输层,使用NAT技术进行代理转发
七层负载均衡工作在OSI的第七层,即应用层,一般根据请求的URL地址进行代理转发。
但是使用四层 LB 会导致额外的问题,如下:
请求负载不均衡:由于使用了kube-和HTTP2协议连接,多个HTTP2请求会复用同一个底层TCP连接服务器集群技术,不会长时间断开。在 kube- 升级或实例重启过程中,很容易导致 kube-only 长时间延迟启动的少数请求。在极端情况下,高负载的实例可能会出现 OOM 甚至导致雪崩。
请求治理缺乏灵活性:第 4 层负载均衡在传输层工作。它只负责消息的传递,而不能在应用层处理 HTTP 协议的信息,因此相比第 7 层负载,它在请求治理上缺乏“灵活性”。和“情报”。例如,无法根据请求的内容(如verb、url等字段)制定灵活的负载均衡和路由策略,也无法在网关处进行限流降级等处理层。
社区中有一些相关的作品试图解决上述问题,但都没有解决问题:
随着云原生技术的发展,目前字节跳动95%以上的业务都在互联网上运行,这对集群的高可用提出了更高的要求。事实上,在生产环境中,我们也遇到过很多由于 kube-load 不平衡或者请求治理能力不足导致的事故。面对以上问题,我们根据kube-的流量特性开发了七层网关。
2. 建筑设计
作为访问和转发kube-请求的七层网关,它具有以下特点:
对客户端完全透明,客户端无需任何修改即可访问;
它支持同时代理来自多个 K8s 集群的请求。不同的 K8s 集群通过不同的域名或虚拟地址(vip)来区分。
负载均衡从 TCP 连接级别转变为 HTTP 请求级别,从而实现快速有效的负载均衡,彻底解决 kube- 负载问题。
高度可扩展的负载均衡策略,目前支持Round Robin、策略、负载均衡策略插件,易于扩展。
支持灵活的路由策略,根据请求信息进行路由,包括但不限于/verb/user//等。提供kube-的基础能力,以较低的运维成本实现kube-之间的隔离,提高集群稳定性.
配置管理云原生,以K8s标准API的形式管理网关配置,支持配置热更新。
支持网关的通用能力,如限流、降级、动态服务发现、优雅退出、异常检测等。
对外以K8s标准API的形式提供代理配置管理服务,主要提供路由转发规则、上游集群kube-、集群证书信息、限流等请求治理策略等配置信息的维护和变更。代理kube-请求的流程如下图所示,主要分为请求解析、路由匹配、用户认证、流量治理、反向代理五个步骤。下面详细描述这些步骤:
2.1 请求解析
可以深入理解 kube- 模型,从中解析出更多信息,将 kube- 分为两种:
资源请求,例如 Pod 的 CRUD (CRUD)。
非资源请求,例如访问/查看 kube-、访问/查看暴露的指标等。
对于资源请求,可以从请求的 URL 中解析以下内容:
最后,一个请求可以解析出多维路由字段,如下图,这些字段将作为路由选择的依据。
2.2 路由匹配
从请求中解析出多维路由字段后,可以很方便的组合非常强大的路由规则来区分不同的API请求,比如
通过 Verb 和 sum 的结合,我们可以直接将请求匹配到所有列表 Pod。
通过User,等,我们可以匹配对kube–,kube-等核心控制组件的请求。
通过路由规则匹配不同的请求后,我们可以做更精细的流量控制,比如分流、限流、熔断等。
匹配规则可以通过修改后的配置管理服务直接暴露给外部API——实时生效。
2.3 用户认证
为了正确代理 kube- 的七层流量,使请求在代理后能够在 kube- 中正确认证和授权,需要将请求中的用户信息透传给 kube-,这就要求请求也可以进行身份验证。用户信息。
kube-支持的认证方式可以分为以下几类
基于x509客户端证书的认证方式:通过规则kube-中的CA证书,解析客户端证书中的用户和用户组信息
基于Token的认证方式:通过向kube-发送请求,需要kube-对Token进行认证,从而获取对应的用户信息。
识别出用户后,通过kube-提供的(user )机制转发,详情将在2.5.1节介绍。另外,只对请求进行鉴权,不对请求进行授权判断,授权操作由kube-进行。
2.4 请求治理
作为七层网关,具有丰富的流量治理能力,包括:
2.4.1 负载均衡
确认后,也确认了。根据负载均衡策略,选择其中之一转发请求。一个好的负载均衡策略可以优化资源效率、最大化吞吐量、减少延迟和容错。
目前支持循环和负载均衡策略。这两种策略简单有效,可以满足大部分场景的需求。此外,它支持灵活的负载均衡策略扩展,可以快速实现Least等算法,满足更多场景的需求。
2.4.2 健康监测
会定期主动访问kube-的/接口进行健康监测。代理流量只会转发到健康的 kube-;不健康的kube-会被暂时阻塞,恢复健康后会恢复新的流量
2.4.3 电流限制
提供默认限流能力,在某些情况下可以有效防止kube-。它的限流方案比它自己的 APF(API 和 )更容易理解和配置。请求解析和路由匹配后,将确定该请求的限流规则。
比如我们想限制普通用户列表pods的QPS,但排除控制组件(如-,),我们可以在路由匹配中区分两类用户,分别为他们配置限流规则。
提供了两种限流策略:
token :令牌桶是一种常见的限流方式,可以有效限制请求的QPS,在一定程度上允许突发请求。
max :最大请求数是比令牌桶限制性更强的方法。它限制了在特定时间可以执行的最大请求数。它通常用于限制一些更耗时的请求,例如大型集群中的 pod 的完整列表。请求可能会持续几分钟,并且会占用大量 kube-。只有通过令牌桶的当前限制,才会发出过多的请求,导致出现 kube-OOM 等问题。
2.4.4 降级
支持降级处理异常集群控制平面。
如果发生 kube- 或 ETCD 故障,可能会导致集群雪崩。在雪崩的情况下,有些请求会返回成功,有些请求会失败,客户端不断重试,这很容易导致集群的意外行为,例如大规模驱逐和删除 Node 和 Pod。
在这种情况下,开发人员可以通过执行降级来拒绝所有流量。在降级状态下,集群相当于被冻结,所有的写入都无法成功。这可确保现有 Pod 进程保持活动状态并避免业务影响。集群恢复正常后,先解除限制,让Node上报心跳,然后再恢复集群的其他流量。
2.5 反向代理
在反向代理部分,有以下关键技术点:
2.5.1(模拟用户)
通过流量治理后,会根据选中的kube-进行转发。转发时传递的机制将用户信息传递给 kube-。在中添加以下信息:
-User:用户名 -Group:用户组
它是 kube- 提供的一种机制,允许一个用户充当另一个用户来执行 API 请求。在使用这种机制之前,我们需要在 kube- 客户端上配置权限。请求的具体流程如下:
kube – 对用户进行身份验证并识别用户正在模拟的操作。
kube – 确保你有权限。
kube – 基于 HTTP 识别模拟用户名和用户组,并将请求执行者替换为模拟用户。
对被冒充的用户进行授权验证,检查其是否具有访问相应资源的权限。
kube-该机制得到很好的支持,在审计日志中也兼容。
最后,依靠用户认证和机制完成原始用户信息的透传,解决了传统七层LB无法代理kube-的问题。并且在代理过程中,对客户端完全透明,客户端无需任何修改即可访问。