写点什么

知乎:如何在大规模集群下使用 Istio 升级微服务架构

  • 2022-07-19
  • 本文字数:3466 字

    阅读完需:约 11 分钟

知乎:如何在大规模集群下使用Istio升级微服务架构

为进一步加强技术交流,推进云原生生态共建,6 月 28 日下午,首届云原生实践者大会在线上线下同步举办。来自作业帮、知乎、转转、58、同程等多家科技企业的数十名研发人员,以及中国信通院云大所的专家共同参与了此次技术研讨沙龙。

 

研讨会上,知乎核心架构平台开发工程师谢楚瑜讲述了“知乎的 Istio 之旅”,与参会者分享了知乎如何在大规模集群下使用 Istio 升级微服务架构,具体包括如何使 Istio 管理的服务和现存服务之间可以互相通信、知乎的 Istio 迁移都遇到和解决过哪些问题、Service Mesh 如何为业务提供了帮助,以及知乎如何在大规模集群中优化性能指标等。

 

以下,是谢楚瑜的分享。

 

大家好,我是谢楚瑜,这次主要是和大家分享下知乎是如何进行 Service Mesh 改造的、在改造期间有遇到了哪些问题,以及随着规模地不断扩大,我们又解决了哪些新的问题。

 

现状

 

先看一下 Service Mesh 在知乎目前的情况。

 

目前,我们的核心业务以及数百个周边业务都已经完成迁移。在每天的高峰期,Service Mesh 中的流量可以达到百万级别的 rps。在指标维度也已经达到了百万级别。我们服务治理的各种功能,如压测、鉴权、限流和断路等也通过 Service Mesh 完成了兼容和重构。

 

然后说下迁移的兼容方案。知乎在早期的时候就已经完成了容器化改造。那时候,我们其实还没有用上 K8s,是自己做了一套基于负载均衡以及服务发现的服务通信发现。因此,在迁移 Service Mesh 时,我们必须首先提供一套方案即可以兼容以前的服务通信,又兼容旧方案的服务治理功能,同时迁移过程对业务无感知,如果有大规模故障还可以快速回滚到旧方案。

 

为了满足上述需求,我们首先做的就是梳理现有的服务调用流程。

 

以前,客户端会直接通过注册中心目标服务的负载均衡地址进行访问。但在云原生环境的做法应该是通过 coreDNS 查询它的一个 ServiceIP,通过这个 ServiceIP 进行服务间通信。如果是在 Service Mesh 里的话,访问 serviceIP 时会直接通过 Envoy 发现一个合适的服务端实例,直接从客户端打到服务端。

 

考虑到对旧方案的兼容,我们决定对服务发现组件进行改造,增加一个服务发现的代理。如果是上了 Mesh 的服务访问没上 Mesh 的服务,那么它其实和以前是一样的,仍然通过旧的负载均衡方案去调用。而对于客户端、服务端都是在 Mesh 环境下服务调用,这个代理将会返回 ServiceIP,这样一来就不需要做 SDK 层面的修改,可以直接兼容旧的负载均衡方案和新的 Service Mesh 调用了。这样有一个好处,如果我们需要切换到旧方案,比如紧急回滚的情况,只需要把这个代理上面的配置修改下就可以直接切回过往的一套流量方式。

 

除此之外,关于鉴权和限流这些功能,我们通过一些 Controller 实现了一套同步方案,然后通过 ServiceMesh 的能力实现了兼容。然后关于从零上 Mesh 其实还有很多改造的点,比如限流。我们上一次 IstioCon 的分享有比较详细的描述,这次暂时不赘述了。

 

在迁移期间,我们有遇到过很多的问题。就像我前面提到的,我们当时有一种集中式的代理方案,在切换到 Mesh 以后,Mesh 其实会给每个业务容器实例后加上一个 Sidecar,这样相当于说,它的连接方式从以前一种集中式的代理访问,变成一种点对点的模式。

 

这会直接导致服务端收到并发数发生很明显的变化,很多性能比较敏感的服务也会发生改变。关于这个问题,我们通过一些指标去做连接池的适配,对于延时变化非常敏感的服务,我们会做一些人工处理。

 

然后是连接管理带来的一些差异。比如我们以前那一套负载均衡方案,会在客户端断开连接以后,仍然保持跟服务端的连接。然而在 Istio 中,如果客户端连接断开,那么它和服务端连接也就断了,这导致我们的业务会在监控上看到一些不一样的错误,如 Golang 服务会看到更多的 Context Cancel 这类错误。对于这种情况,我们是通过 SDK 对异常的采集做适配来解决。

 

还有一个比较核心的点。在 Istio 中,每次读取指标文件都可能在内存里面同时写两份完整的指标配置。当一个实例的指标文件达到上百兆的时候,对 Sidecar 的性能影响是非常大的。我在后面会具体提到指标这块我们是怎么解决的。

 

业务应用

 

在做好了基础的兼容和适配以后,剩下就是考虑怎么样让业务应用起来。

 

考虑到 Istio 对象的复杂度非常高,一上来如果直接看 VS、DR,还有 Authpolice、Service Entry 这些东西的话,很难直接用起来。另外,每一个配置都可能会因为需求的复杂而进行重复配置,比如一个 vs 的配置里面有时可能会加一个故障注入改一下,然后又加一个重试规则又改一下。

 

基于这个问题,我们实现了一个类似于 Envoyfilter 一样的 Crd、Istiofilter。通过这个 crd,我们可以对 Istio 应用一种 overlay 形式配置。这样我们可以通过配置多个 Istiofilter 同时管理同一个 vs 配置。如果中间某些配置不要了,比如不要流量镜像了,就只需要删掉对应的 IstioFilter,随后 vs 上面就只会减少这一个 mirror 的配置,其他配置仍然可以正常使用。目前这一套 Istiofilter 也是有开源版本的,可以直接在 GitHub 上找到。

 

除此之外,我们 Mesh 的所有能力目前都是直接面向业务研发开放使用的。目前大部分功能都是基于接口这一种粒度进行配置。他们可以通过指标或者自己手动在接口配置界面上配置他们的一些接口定义,在完善接口配置以后就可以在上面使用一些故障注入和限流功能。

 

考虑到自身业务的特殊性,我们并没有全面使用 Istio 原生提供的功能。比如,我们自己实现了流量镜像功能,它其实可以支持超过 100%这种比例的配置,这样就可以拿线上的流量进行压测,也可以将压力都集中在需要测试的服务端实例上,避免影响其他的客户端应用。

 

前面提到我们大概有百万级的 Rps,同时也已经有 10 万+的实例运行在上面,这样就会有一些新的问题。比如像 Ipvs 上如果 Service 数量太多,一些采集工作会导致它在机器上面软中断时间变长,进而从业务角度观察会有一些网络延迟。最终我们是通过livepatch关闭了特性来解决的这个问题。

 

然后是做了 DNS 优化。前面提到,我们当时是用了自己的一套服务发现体系,没有用 coreDNS。然后我们在切到 Mesh 的时候发现,当时的 coreDNS 比较难以支撑我们的性能需求。于是我们自己搭建了一套 local Dns,每个 K8s 节点放一个 DNS 实例,同时结合这一个 Istio 的 smartdns,减少了由于服务域名没有填写完整而重复查询 DNS 的次数,这样尽量优化 DNS 在服务调用中的时间开销。

 

关于 Istio 的参数配置,首先由于集群规模较大、服务更新频繁,对于一些服务来说可能配置推送会非常频繁,推送内容也非常比较大,这样的话推送配置非常容易超时。所以,我们根据集群规模调了配置,包括减少了配置推送的量,只针对某个位去推送所需的配置。我们做了一个自动的服务配置范围(sidecar crd)的适配,这样确保每个服务都按需加载配置。

 

除此之外,我们还使用了 Istio 的 DiscoverySelector 减少 Istio 采集集群信息的范围。因为我们的集群中除了常规的业务容器外,还有很多永远不会参与服务间通信的容器。但是 DiscoverySelector 有个问题:它里面的接口可能和我们集群的 K8s 接口不兼容,Istio 版本如果低于 1.13 的话,可能会因为 panic 导致 istiod 偶发重启。更多细节我们以前也在知乎专栏上做过很详细的分享。

 

指标方面,前面提到我们指标的维度已经比较大,总维度在百万以上,这对我们的指标系统确实存在一个挑战。我们以前其实只有一个 victoriametrics 集群,随着指标规模扩大,我们将指标集群分成了两个:一个是短期存储,只存大概一个星期左右的全量指标;另一个是长期存储,它会把短期存储指标里面的 pod 信息去掉,然后把剩下聚合过的指标存三个月。这样,我们可以做到在大部分情况都能较快地查询到监控数据。

 

还有一个维度的问题,比如最常见的 Istio request total 指标,会把某一个客户端的版本信息,以及服务的版本信息全部都带上。但这会遇到一个问题,比如某一个服务端一直不更新、客户端一直更新的情况,会导致服务端有特别多不会增长的指标堆积在里面。可惜 Envoy 也不支持指标过期的功能,导致每一次拉取指标时我们会多拉很多冗余的指标。

 

最终,我们决定在服务端去除客户端的版本信息、客户端的指标中去除掉服务端的版本信息,通过这种方式优化指标维度。这样做了之后,我们的指标系统压力有了很大程度的下降,个别服务的 duration 指标维度甚至下降了 20 万。通过这些操作,我们集群的监控指标维度基本趋于稳定。

 

在知乎的 Mesh 化过程中,Mesh 一方面带来了很多新的问题,比如性能上、运营上的问题。但是另一方面,我们利用 Mesh 节约了很多过往需要在 sdk 层面反复实现的功能,也利用 Mesh 弥补了我们在监控与测试链路方面的许多缺失。Service Mesh 是一项充满魅力的技术,而知乎的 Mesh 之路也将继续下去。

2022-07-19 09:513261

评论

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

官宣 | 极狐GitLab SaaS来了

极狐GitLab

为冬奥加油——利用贝塞尔曲线实现冰墩墩

战场小包

前端 canvas 冬奥会 2月月更

OpenHarmony移植案例与原理:startup子系统之syspara_lite系统属性部件

华为云开发者联盟

Token OpenHarmony startup子系统 syspara_lite系统

深入解析 Flink 细粒度资源管理

Apache Flink

大数据 flink 开源 编程 实时计算

大数据培训:Flink 快照分析

@零度

flink 大数据开发

跨项目度量,CTO、PMO们的好帮手

阿里云云效

阿里云 云原生 敏捷开发 CTO 研发度量

人才短缺、成本高昂,制造企业智能化转型路径如何破局?

百度开发者中心

教你一个快速视频处理的神器:Python moviepy

华为云开发者联盟

Python 视频 音频 视频处理 Moviepy

【网络安全】知名网络安全企业有哪些?

行云管家

网络安全 数据安全 堡垒机

HTTP流量神器Goreplay核心源码详解

华为云开发者联盟

Go 流量 GOREPLAY TCP/HTTP

千万级CPS的开源网络压测软件dperf

百度开发者中心

Mysql数据库表中有索引为什么还是查询慢?

慕枫技术笔记

数据库 2月月更

剖析react核心设计原理--异步执行调度

有道技术团队

【Python训练营】Python每日一练----第23天:字符计数

是Dream呀

2月月更

作业7

施正威

虎符Hoo交易所开启全新生态布局 完成HOO首次回购

区块链前沿News

Hoo 虎符交易所 HOO回购

美景本天成,妙笔偶得之——“妙笔”是怎样炼成的?

百度开发者中心

注意!这种笔试方式正在逐渐被取代……

ShowMeBug

笔试 在线面试

DevSecOps端到端的安全能力构建为什么重要

极狐GitLab

安全 DevSecOps

在线YAML转XML工具

入门小站

工具

【堡垒机】堡垒机是啥?一线品牌有哪些?

行云管家

网络安全 数据安全 堡垒机 IT运维

直播预告|一线专家邀你共话:数据科学赋能多元应用场景价值

MobTech袤博科技

算法 数据 商业

百度App Objective-C/Swift 组件化混编之路(一)

百度开发者中心

2021年第4季度中国网络零售B2C市场交易规模达23593.9亿元

易观分析

B2C 网络零售

深入浅出特征工程 – 基于 OpenMLDB 的实践指南(上)

第四范式开发者社区

机器学习 数据库 大数据 OpenMLDB

刷屏的“1620”有多难?3D+AI技术带你一秒看懂

百度开发者中心

全方位构建信创生态体系,焱融科技完成海光 CPU 生态兼容性认证

焱融科技

云计算 分布式 高性能 文件存储 生态

关于极狐GitLab SaaS,你应该知道这些!

极狐GitLab

DevSecOps SaaS平台

用UML来描述领域模型吧

蜜糖的代码注释

UML 领域建模 2月月更

英特尔至强单月总出货量超其他厂商全年服务器CPU总出货量

科技新消息

百度App Objective-C/Swift 组件化混编之路(二)- 工程化

百度开发者中心

知乎:如何在大规模集群下使用Istio升级微服务架构_服务革新_谢楚瑜_InfoQ精选文章