问题描述:
istio的控制面istiod包装了virtual service和destination rules ,他们是应用粒度的,而istiod和envoy之间的交互又被拆分成了xds,也就是lds,rds,cds这些,特别是rds和cds,一旦配置下发的顺序不对,就会出现流量有损。
同时,istio管控的数据面envoy是分布式的,通常情况下是成千上万的,而istiod的每次批次变更都是类似广播的方式下发到所有的envoy节点,一旦有些节点没有及时下发就会存在流量问题。
如果我们没有能力保证每次变更都是向前兼容的,那么通常情况下就会出锅。
如果我们想解决上面的问题,我们就必须要能够知道修改的vs或者dr是不是已经完全同步到所有的envoy了,以及哪些还没同步完成。
方案设计:
一、核心问题分析
而上面问题的核心点,主要有两个场景需要解决:
补充说明:我们在istiod前面关联了两个服务istiou作为用户面,kiali用来管控istiod
第一个:就是istiou实现了多种场景的分组和路由功能,这里很多都是通过VS和DR来进行操作的,如何能够在istod和sidecar去表达这个事情?
第二个:就是isitod和很多sidecar之间的xds数据的一致性如何保证,包括:正常进度的展示、出问题之后的异常处理策略(例如:重试、关闭劫持、摘除等等)
我们的目标是:尽量保证配置的数据,sidecar里面是能够在5s内,100%完成同步的。一旦出现了配置数据不同步的情况的话,我们如何能够知道这件事情,并且处理方法是什么,以及兜底策略是什么?
二、具体解决思路
场景一:
如何能够在istod和sidecar去表达这个事情?
问题 1:
istiou---->kiali---->istiod--→envoy 整条链路如何实现这种表达,他们之间的交互逻辑是什么样子的?
1)istiou在操作业务功能时,如需要修改virtualservice,需要给virtualservice打上业务相关的标签,方便后端去追踪业务功能对应xds配置的下发状态即进度。
2)istiou如果需要关注配置下发进度,调用kiali暴露的xds同步状态接口查询某一资源类型的xds同步状态。
3)kiali 查询每个istiod,拿到当前istiod下所有下属sidecar的xds同步状态信息,然后kiali聚合所有istiod的结果。

问题2:
代码修改评估,哪些地方是需要我们有代码修改的?
1) istiou各个业务功能更新vs的地方,需要打上业务功能标签
2)kiali聚合&分析istiod xds同步状态数据,提供接口暴露给istiou
- istiod提供新接口,实现获取下属sidecar 的xds同步状态数据,并根据业务功能标签过滤这些数据,比如: /debug/syncz 的扩展,该接口能:
. 按标签过滤资源:根据从Kiali传来的标签(如 grayRelease=256),找到对应的 VirtualService 等配置。
. 映射并查询同步状态:将这些配置资源映射到其下发的目标Sidecar列表,然后通过istiod内部已有的 xDS 状态追踪机制(与Envoy的 Last NACK 和 Last ACK 相关),返回每个Sidecar的配置版本号、同步状态(SYNCED/ NOT_SENT/ STALE/ ERROR)、以及错误信息(如果是NACK)。
问题3:
表达这些功能的标签名字规范是什么样子的?
标签都放到对应CR的metadata.labels下面,标签名为业务功能英文简称,值为当前业务功能版本号,以金丝雀发布为例:
标签名为grayRelease, 值为256,256为发布平台上对应的发布版本号
问题4:
处于漂移阶段的sidecars怎么处理?
1)已注册到zk的sidecar都返回同步状态。
2)什么时候结束进度查询由istiou决定,把决策权交给用户面。

场景二:
isitod和很多sidecar之间的xds数据的一致性如何保证,包括:正常进度的展示、出问题之后的异常处理策略(例如:重试、关闭劫持、摘除等等)

kiali去查询istiod每次同步xds配置的状态信息,并缓存起来,并定时同步,并提供查询接口,一旦有状态是没同步成功,可以通过api来把状态不对的展示出来。
这里可以根据配置的告警规则,比如超过5%触发告警,或者某些核心应用没有同步上报告警。
一旦收到告警之后,根据sidecar的状态信息,去决策是重新发布配置,还是回滚,或者把这些sidecar摘除。
特别说明:
这里有一个关键点,为了避免配置导致的流量跌0或异常,需要实现一个兜底流量路由的fallback机制。(这个在后续文章中会单独介绍。)