Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

可以控制"控制平面"是否能主动向"数据平面"推送资源 #887

Open
alexzzh opened this issue Mar 27, 2024 · 14 comments
Open

Comments

@alexzzh
Copy link
Contributor

alexzzh commented Mar 27, 2024

Why do you need it?

  • 在需要极高稳定性的客户环境下,客户"强制"规定在某个时间范围不允许进行配置变更,此时不能假设此阶段不会有人(误)操作或者控制平面一定不会推送配置,故需要软件层增加一种"protect"机制,从技术层面切断控制平面主动向数据平面推送的路径。

How could it be?

  • 方案1: PR
  • 方案2: PR - 废弃
  • 考虑到higress controller 类似于mcp server,会识别全局配置 configmap(envoyfilter)、 ingress资源、 wasmplugin资源转换成istio 的crd,并基于mcp-over-xds协议通过xDS server下发给pilot,所以可以控制发出的 pushRequest 不进入xDS server的pushchannel,来达到此效果。

other infomation

  • 考虑到service 、config、eds update、global config变更时最终都会调用 ConfigUpdate, 将来还会有其他场景调用该函数,所以控制点选择在 ConfigUpdate接口内部,比较收敛,向前兼容
@CH3CHO
Copy link
Collaborator

CH3CHO commented Mar 27, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?

你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

@alexzzh
Copy link
Contributor Author

alexzzh commented Mar 27, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?

你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

用户现场,我们总是会遇到有人(不一定是自己人)操作后台,并因此受到处罚,所以依赖"口头约定“是最不可靠的。
源头限制是一个比较好的方案,整个控制面(包括ui)都是"只能查,不能改"状态,但这涉及的面可能更广。

@CH3CHO
Copy link
Collaborator

CH3CHO commented Mar 27, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?
你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

用户现场,我们总是会遇到有人(不一定是自己人)操作后台,并因此受到处罚,所以依赖"口头约定“是最不可靠的。 源头限制是一个比较好的方案,整个控制面(包括ui)都是"只能查,不能改"状态,但这涉及的面可能更广。

建议是从变更源头来限制。比如大家一般修改配置都是走UI,那么UI卡住可以满足绝大部分的需求,而且变更风险低。

@alexzzh
Copy link
Contributor Author

alexzzh commented Mar 27, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?
你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

用户现场,我们总是会遇到有人(不一定是自己人)操作后台,并因此受到处罚,所以依赖"口头约定“是最不可靠的。 源头限制是一个比较好的方案,整个控制面(包括ui)都是"只能查,不能改"状态,但这涉及的面可能更广。

建议是从变更源头来限制。比如大家一般修改配置都是走UI,那么UI卡住可以满足绝大部分的需求,而且变更风险低。

是的 , 如果能ui强制限制配置调整肯定更好,这个需求是我们的业务需要。

目前的修改是提供开关,默认不影响程序原来的行为。 我这边改不了前端代码. ^V^

@CH3CHO
Copy link
Collaborator

CH3CHO commented Mar 27, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?
你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

用户现场,我们总是会遇到有人(不一定是自己人)操作后台,并因此受到处罚,所以依赖"口头约定“是最不可靠的。 源头限制是一个比较好的方案,整个控制面(包括ui)都是"只能查,不能改"状态,但这涉及的面可能更广。

建议是从变更源头来限制。比如大家一般修改配置都是走UI,那么UI卡住可以满足绝大部分的需求,而且变更风险低。

是的 , 如果能ui强制限制配置调整肯定更好,这个需求是我们的业务需要。

目前的修改是提供开关,默认不影响程序原来的行为。 我这边改不了前端代码. ^V^

但现在这个方案存在一些漏洞,不是一个完整的解决方案。

@alexzzh
Copy link
Contributor Author

alexzzh commented Mar 28, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?
你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

用户现场,我们总是会遇到有人(不一定是自己人)操作后台,并因此受到处罚,所以依赖"口头约定“是最不可靠的。 源头限制是一个比较好的方案,整个控制面(包括ui)都是"只能查,不能改"状态,但这涉及的面可能更广。

建议是从变更源头来限制。比如大家一般修改配置都是走UI,那么UI卡住可以满足绝大部分的需求,而且变更风险低。

是的 , 如果能ui强制限制配置调整肯定更好,这个需求是我们的业务需要。
目前的修改是提供开关,默认不影响程序原来的行为。 我这边改不了前端代码. ^V^

但现在这个方案存在一些漏洞,不是一个完整的解决方案。

一些漏洞指的是重启会引起配置推送吗? 这个是预期的
如果是controller重启,默认本身就是允许推送的
如果是gateway重启,肯定要保证重启后的gateway能拉取配置并成功运行

而且正常运行过程,不应该出现两个组件重启的情况,该方案主要是为了限制正常运行过程,控制平面主动推送的场景,不管是人为操作还是程序流程。

@CH3CHO
Copy link
Collaborator

CH3CHO commented Mar 28, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?
你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

用户现场,我们总是会遇到有人(不一定是自己人)操作后台,并因此受到处罚,所以依赖"口头约定“是最不可靠的。 源头限制是一个比较好的方案,整个控制面(包括ui)都是"只能查,不能改"状态,但这涉及的面可能更广。

建议是从变更源头来限制。比如大家一般修改配置都是走UI,那么UI卡住可以满足绝大部分的需求,而且变更风险低。

是的 , 如果能ui强制限制配置调整肯定更好,这个需求是我们的业务需要。
目前的修改是提供开关,默认不影响程序原来的行为。 我这边改不了前端代码. ^V^

但现在这个方案存在一些漏洞,不是一个完整的解决方案。

一些漏洞指的是重启会引起配置推送吗? 这个是预期的 如果是controller重启,默认本身就是允许推送的 如果是gateway重启,肯定要保证重启后的gateway能拉取配置并成功运行

而且正常运行过程,不应该出现两个组件重启的情况,该方案主要是为了限制正常运行过程,控制平面主动推送的场景,不管是人为操作还是程序流程。

不只是重启。一般对稳定性要求高的场景,我们都要考虑横向扩容的可能性。比如在业务高峰期,我们冻结变更以保证稳定。同时,集群的容量也需要能够及时横向扩展以应对流量的上涨。很多时候,我们会使用 K8s 提供的 HPA 等技术来进行自动的集群容量调整。在这种情况下使变更生效,而且集群内各实例的配置不一致,应该不能算是预期内的吧?

@alexzzh
Copy link
Contributor Author

alexzzh commented Mar 28, 2024

变更冻结这种需求是否应该在源头进行限制,而不是在最终生效的地方?
你上面也提到了,不管是谁重启,controller 还是 gateway,都会导致被冻结的变更在终端生效,产生预期外的配置变更。

用户现场,我们总是会遇到有人(不一定是自己人)操作后台,并因此受到处罚,所以依赖"口头约定“是最不可靠的。 源头限制是一个比较好的方案,整个控制面(包括ui)都是"只能查,不能改"状态,但这涉及的面可能更广。

建议是从变更源头来限制。比如大家一般修改配置都是走UI,那么UI卡住可以满足绝大部分的需求,而且变更风险低。

是的 , 如果能ui强制限制配置调整肯定更好,这个需求是我们的业务需要。
目前的修改是提供开关,默认不影响程序原来的行为。 我这边改不了前端代码. ^V^

但现在这个方案存在一些漏洞,不是一个完整的解决方案。

一些漏洞指的是重启会引起配置推送吗? 这个是预期的 如果是controller重启,默认本身就是允许推送的 如果是gateway重启,肯定要保证重启后的gateway能拉取配置并成功运行
而且正常运行过程,不应该出现两个组件重启的情况,该方案主要是为了限制正常运行过程,控制平面主动推送的场景,不管是人为操作还是程序流程。

不只是重启。一般对稳定性要求高的场景,我们都要考虑横向扩容的可能性。比如在业务高峰期,我们冻结变更以保证稳定。同时,集群的容量也需要能够及时横向扩展以应对流量的上涨。很多时候,我们会使用 K8s 提供的 HPA 等技术来进行自动的集群容量调整。在这种情况下使变更生效,而且集群内各实例的配置不一致,应该不能算是预期内的吧?

扩容后的影响是否可以忽略还是要看用户场景,
PR中的“在需要极高稳定性的客户环境下,客户"强制"规定在某个时间范围不允许进行配置变更"的另一层面是不会对集群内进行任何变更操作,包括扩缩容,只允许在固定时间窗口内做变更操作(比如证券行业的休市时间),所以对于我们的使用场景这点是可以忽略的。

因为PR限制的是主动推送,如果希望使用了该功能+动态扩容+配置一致,那就扩容前调用 /debug/ignorePushRequest?disable=true&push=true 接口,扩容后再调用 /debug/ignorePushRequest 接口打开, 保持扩容后的状态。

另外,ui层面不允许修改,只允许查询就是最优方案。

@CH3CHO
Copy link
Collaborator

CH3CHO commented Mar 28, 2024

一些漏洞指的是重启会引起配置推送吗? 这个是预期的 如果是controller重启,默认本身就是允许推送的 如果是gateway重启,肯定要保证重启后的gateway能拉取配置并成功运行
而且正常运行过程,不应该出现两个组件重启的情况,该方案主要是为了限制正常运行过程,控制平面主动推送的场景,不管是人为操作还是程序流程。

不只是重启。一般对稳定性要求高的场景,我们都要考虑横向扩容的可能性。比如在业务高峰期,我们冻结变更以保证稳定。同时,集群的容量也需要能够及时横向扩展以应对流量的上涨。很多时候,我们会使用 K8s 提供的 HPA 等技术来进行自动的集群容量调整。在这种情况下使变更生效,而且集群内各实例的配置不一致,应该不能算是预期内的吧?

扩容后的影响是否可以忽略还是要看用户场景, PR中的“在需要极高稳定性的客户环境下,客户"强制"规定在某个时间范围不允许进行配置变更"的另一层面是不会对集群内进行任何变更操作,包括扩缩容,只允许在固定时间窗口内做变更操作(比如证券行业的休市时间),所以对于我们的使用场景这点是可以忽略的。

因为PR限制的是主动推送,如果希望使用了该功能+动态扩容+配置一致,那就扩容前调用 /debug/ignorePushRequest?disable=true&push=true 接口,扩容后再调用 /debug/ignorePushRequest 接口打开, 保持扩容后的状态。

另外,ui层面不允许修改,只允许查询就是最优方案。

我个人认为这个功能使用存在一定的局限性,可能不太适合做在开源版本里。@johnlanni ,你有什么意见吗?

@johnlanni
Copy link
Collaborator

我不建议通过debug接口控制单个实例的配置,可以尝试的做法是在全局配置里增加一个开关来进行控制。

@alexzzh
Copy link
Contributor Author

alexzzh commented Mar 28, 2024

我不建议通过debug接口控制单个实例的配置,可以尝试的做法是在全局配置里增加一个开关来进行控制。

这里的全局配置指的是使用 higress-config 这个configmap 吗? 一开始考虑过这个方案。
因为希望调整这个开关时不需要重启就能生效,所以不能作为deployment中的环境变量, 使用higress-config 这个configmap是一个方案,但存在一些弊端:
1 目前 higress-config 这个configmap 中属于higress的每个全局变量都会生成对应的envoyfilter, 如果在这里增加一个控制开关,会打破“全局配置都会生成envoyfilter”这个约定,当然这个约定可能本身就不存在,也不应该存在,对于用户来说,只要配置能动态生效,不会关心具体实现,只是现在higress的全局配置比较少,看起来存在这个约定而已 ==》这不是关键原因

2 考虑到service 、config、eds update、global config变更时最终都会调用 ConfigUpdate, 将来还会有其他场景调用该函数,所以控制点选择在 ConfigUpdate接口内部,比较收敛,向前兼容 ---- 基于这个考虑,目前的实现是在 DiscoveryServer 中增加开关变量以及在ConfigUpdate 函数中判断这个变量值, 如果使用configmap来实现,需要在 ConfigmapMgr 中修改 DiscoveryServer 这个变量,目前XDSUpdater没有这个接口,增加这个接口对代码侵入性太强,不太推荐 ==》这是关键原因

看了下debug接口,也会有控制平面推送,清理cache等控制操作,也是DiscoveryServer本身的功能,所以选择在debug接口操作,这个操作会影响到连接到这个控制平面的所有数据平面的配置推送。

或者说这里的全局配置指的其他含义? 可以进一步说明一下,本身对higress也是刚了解,进一步学习下。

@johnlanni
Copy link
Collaborator

@alexzzh 感谢你详细的说明,我理解你的顾虑,第一点确实不是关键问题,第二点侵入性的问题,可以看下更合适的修改方式。
不考虑在debug接口支持这个功能是因为会增加运维成本,需要逐个控制面进行操作配置,可能你们的场景比较特殊控制面只有一个节点,但很多用户都是多节点部署控制面的。

@alexzzh
Copy link
Contributor Author

alexzzh commented Apr 3, 2024

@alexzzh 感谢你详细的说明,我理解你的顾虑,第一点确实不是关键问题,第二点侵入性的问题,可以看下更合适的修改方式。 不考虑在debug接口支持这个功能是因为会增加运维成本,需要逐个控制面进行操作配置,可能你们的场景比较特殊控制面只有一个节点,但很多用户都是多节点部署控制面的。

好的, 如果是多控制平面确实不方便,这点没考虑到。

@alexzzh
Copy link
Contributor Author

alexzzh commented Apr 12, 2024

根据上述讨论: 之前的方案是通过debug接口来控制,会增加运维成本,故不推荐, 更适合通过全局开关来控制,又因为需要能够动态调整,所以选择在mech config中增加 ignorePushRequest 参数来控制。详见 PR

回到最初的需求: 确保某段时间内数据平面不会发生配置变更,基于该需求,现阶段相较于ui冻结,按照这个pr来解决可以通用些,因为资源来源不仅仅是通过ui来配置,除了 higress 自身监听的 ingress、wasmplugin、gateway api(将来), 用户可能还需要 envoyfiter 、k8s crd 以及 各厂家自定义crd, 甚至存在直接使用istio crd的用户, 对于这些资源都有可能影响数据平面的配置。 @johnlanni

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Progress
Development

No branches or pull requests

3 participants