本文介绍如何通过MSE白屏化迁移工具将自建Nginx Ingress迁移至MSE Ingress。
什么是MSE Ingress
MSE Ingress是在MSE云原生网关之上提供更为强大的Ingress流量管理方式。MSE Ingress将流量网关、微服务网关和安全网关三合一,兼容K8s Ingress标准API,解决了三层网关架构独立设计和独立运维导致的资源消耗大、性能损耗大、稳定性难控、安全防护复杂等难题。
MSE Ingress优势
相较于传统网关,MSE Ingress在资源成本、性能、安全性和易用性上具有如下优势:
遵循标准:MSE Ingress严格遵循K8s Ingress标准API,支持networking.k8s.io/v1beta1和networking.k8s.io/v1。
兼容性强:兼容Nginx Ingress注解80%以上的使用场景,Nginx Ingress配置无需修改即可在MSE Ingress生效。关于MSE Ingress支持的注解汇总信息,请参见MSE Ingress支持的Annotation。
扩展丰富:相较于Nginx Ingress原生注解,MSE提供功能更丰富的扩展注解,例如认证鉴权、Header控制、限流和安全防护等。更多关于MSE Ingress增强的扩展注解,请参见MSE Ingress高级用法。
架构安全:采用数据面和控制面分离部署,实现资源隔离,架构设计更安全。
性能强劲:支持HTTPS硬件加速、QPS性能提升。
迁移Nginx Ingress至MSE Ingress的必要性
Nginx Ingress目前存在的主要问题:
重大安全漏洞:Nginx Ingress在安全领域出现了高危安全漏洞CVE-2021-25745、CVE-2021-25746和CVE-2021-25748。
与Ingress APIVersion和K8s集群版本耦合严重,影响用户升级K8s集群的进程。ACK Kubernetes 1.24版本中彻底弃用了v1beta1版本的Ingress资源,同时Nginx Ingress Controller在1.0.0及以上版本才支持v1的Ingress资源,导致升级ACK Kubernetes 1.24版本必须提前升级Nginx Ingress Controller。
升级Nginx Ingress Controller的流程复杂且容易出现流量损失。
需要额外部署一套新版本的Nginx Ingress Controller。
需要手动修改模板参数以完成应用版本的升级。
只支持基于DNS方式进行老网关迁移流量到新网关,时效性差,出现问题时无法快速回滚。
将Nginx Ingress网关迁移至MSE Ingress后,可将Ingress网关与Ingress APIVersion、K8s集群版本解耦,解决后续K8s集群升级依赖Nginx Ingress Controller版本的困扰。此外,MSE Ingress提供了迁移场景的产品化工具,用户可以采用复用SLB的方式做细粒度切流,提高迁移过程中的时效性和稳定性。
迁移方式
MSE Ingress提供了如下两种迁移方式:
复用Nginx Ingress SLB
原理:在MSE Ingress中复用ACK集群中Nginx Ingress Controller的Service创建的SLB,MSE Ingress的节点自动添加到原SLB的已有监听的虚拟服务器组中,最终通过设置流量权重完成流量迁移。
在保留原有流量链路可用的前提下完成MSE Ingress复用已有SLB,以及自动同步原有的Nginx Ingress规则。最后在验证无误后,逐步切流到MSE Ingress,整个过程可保留原有流量入口SLB不变,不需要变更DNS切流。
基于DNS解析
原理:在DNS服务器中对于所有Nginx Ingress中关联的业务域名添加MSE SLB的解析结果,部分DNS服务商提供权重方式控制Nginx SLB和MSE SLB的流量比。
前提条件
已创建容器服务集群,且部署了Nginx Ingress Controller。
已创建MSE Ingress,且版本至少为1.2.22。
如果未曾创建MSE Ingress,请参考文档通过MSE Ingress访问容器服务。
说明配置IngressClass时,请采用通过MseIngressConfig资源方式,且IngressClass需设置为待迁移的Ingress所属的IngressClass,例如nginx。
注意事项
本文描述的迁移不是复制您的Ingress配置,而是让您的Ingress配置被MSE Ingress复用,实时监听已有的Ingress资源变化并解析。
迁移过程中,如果您的Ingress配置发生变化,会同时反映在Nginx Ingress Controller和MSE Ingress。
迁移完成之后,请不要随意删除线上正在使用的Ingress配置,迁移仅仅是让现有的Ingress配置以及未来新添加的Ingress配置被MSE Ingress监听并解析。
迁移完成之后,现有的Ingress配置以及未来新添加的Ingress配置仍然需要关联之前使用的IngressClass。例如之前Ingress的spec中的ingressClassName为nginx,那么在迁移之后,现有的Ingress配置以及未来新添加的Ingress配置的spec中的ingressClassName仍然需要是nginx。
步骤一:路由规则迁移
登录MSE网关管理控制台。
在顶部菜单栏选择地域。
在左侧导航栏,选择云原生网关 > 迁移上云。
在迁移上云页面,单击创建任务。
在创建迁移配置页面,进行相关配置。云原生网关将自动监听所选容器集群内且关联到源IngressClass的所有Ingress资源的变化,并生效Ingress资源中域名和路由的相关配置。
重要如果目标云原生网关集群中已关联该容器集群,且已配置的IngressClass与此处的配置不同,则不允许迁移。请确保此处配置的IngressClass与已关联容器集群配置的IngressClass一致。
配置项
说明
云原生网关实例
选择要迁移至的目标云原生网关,版本要求至少为1.2.22。
容器服务ACK/ACK Serverless集群
选择要迁移的Nginx Ingress对应的容器集群,请确保云原生网关与容器集群网络是连通的。
源IngressClass
配置待迁移的Ingress资源关联的IngressClass资源。
说明仅支持配置单个IngressClass。
配置为空,即忽略IngressClass,表示监听集群中所有的Ingress资源。
步骤二:路由校验
校验监听的Ingress的兼容性:
如果无不兼容的Ingress Annotation,则继续下一步。
如果存在不兼容的Ingress Annotation,您可以提交工单咨询解决方案。
重要注解nginx.ingress.kubernetes.io/service-weight的值为""可以忽略,该注解为旧版容器服务控制台默认添加,本身没有任何意义。
迁移过程中,请勿删除线上正在使用的不兼容注解,因为这些不兼容的注解仍然被Nginx Ingress Controller解析并作用于您的业务流量。您可以在Ingress资源上额外添加MSE扩展的注解,在MSE Ingress实现相同的功能。待流量全部迁移至MSE Ingress之后,您可以按需删除不兼容的注解。
步骤三:切流选择
切流前测试
正式切流前,建议先进行本地测试:修改本地hosts文件,为业务域名添加云原生网关SLB解析,通过curl或者postman等工具验证所有流量是否符合预期。
两种切流方式
复用原集群SLB
原理是将云原生网关节点实例添加到原SLB的后端服务器组中,在迁移过程中根据用户设置的权重分配业务流量到云原生网关。当迁移完成之后,访问该SLB的流量将全部转发至云原生网关。
相关配置项说明如下:
配置项 | 说明 |
容器集群命名空间 | 选择Nginx Ingress SLB关联的K8s Service所在的命名空间。 |
容器集群SLB服务 | 选择Nginx Ingress SLB关联的K8s Service的名称。 |
SLB ID | 单击查询到的SLB,确认该SLB是目标待迁移的SLB。 |
端口及后端服务器 | 选择原集群SLB实例的监听端口和网关协议(HTTP/HTTPS),会自动展示目标虚拟服务器组。 说明 请注意端口以及对应协议的选择,否则流量可能有损。 |
DNS解析至云原生网关SLB
请您前往DNS供应商的域名解析服务,为迁移路由涉及的所有域名添加云原生网关SLB地址的映射。建议使用DNS的权重解析方式逐步切流。
步骤四:流量切换
两种切流方式
复用原集群SLB
单击变更SLB, 系统自动将SLB脱离容器托管并修改监听调度算法为加权轮询。
重要该步骤会将SLB脱离容器托管,脱离之后无法感知Nginx Ingress Controller的Pod IP变化,请尽快按照下一步的要求修改注解,重新将K8s Service关联至SLB。
在容器服务控制台中手工将复用原集群SLB选择的K8s Service的当前所有注解删除,并添加流量切换页面为您自动生成的注解。该步骤主要是将原K8s Service改为复用SLB,修改完成后,单击前置检查,检查通过后,会进入下一步。
设置转发云原生网关实例的流量权重,根据业务实际情况设置1~100,建议初次设置为1~10之间。
该值为云原生网关各节点的权重值总和,SLB会根据虚拟服务器组中云原生网关和 Nginx Ingress各节点的权重比值分配流量。其中Nginx Ingress节点的权重总和默认为100,所以当云原生网关权重也设为100,则承接1/2 流量。依此类推,当云原生网关权重设为50,则承接1/3流量。
迁移过程中,用户可以通过云原生网关提供的监控大盘观察网关各项指标,时刻关注网关健康状态以及业务指标是否符合预期。
如果符合预期,可以逐步调大权重,修改权重的时间间隔要大于3分钟,因为后台是异步生效权重配置。
如果不符合预期,权重设置为0即可,本次迁移终止。
您可以在容器服务控制台中将复用原集群SLB选择的K8s Service的注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight的值调低,间接调大云原生网关的权重。特别的,当该注解的值为0时,流量则全部导入云原生网关。
SLB作为四层负载均衡,流量控制粒度为连接级别,该权重值无法精确控制请求级别的分发比例。
切流后如果出现成功率下跌,可将该权重设为0进行流量回滚。
说明如果您希望长期处于迁移状态中,希望随时可以调整Nginx Ingress和MSE Ingress的流量权重,建议您长期处于当前步骤中。当您验证并确认流量符合预期,之后不再需要回滚所有流量到Nginx Ingress,可以点击完成流量验证继续下一步。
重要单击完成流量验证后,将无法修改权重。
在容器服务控制台中将步骤三:切流选择选择的K8s Service服务的注解 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight的值设置为0,或者直接删除该Service资源,Nginx Ingress Controller的节点将会自动从该SLB摘除,则SLB的全部流量切换至云原生网关。
单击完成迁移,此次迁移任务结束。
DNS解析至云原生网关SLB
请前往DNS供应商的域名解析服务,为迁移路由涉及的所有域名添加云原生网关SLB地址的映射。建议使用DNS的权重解析方式逐步切流。
快速回滚
如果在流量迁移过程中发现不符合预期,您可以根据以下方式快速回滚,使流量恢复至Nginx Ingress Controller。
复用原集群SLB:权重设置为0即可,本次迁移终止。
DNS解析至云原生网关SLB:用户在DNS提供商上对所有的业务域名删掉云原生网关SLB地址即可。
步骤五:完成迁移
复用原集群SLB
对于SLB切流方式,如果您还有其他SLB未切流完毕,请确保这些SLB完成切流。如果您已经完成了所有SLB的切流,后续您可以按需删除K8s Service以及Nginx Ingress Controller。
DNS解析至云原生网关SLB
对于DNS切流方式,如果您所有业务域名的IP地址已经全部解析为MSE网关的SLB地址列表,后续您可以按需删除K8s Service以及Nginx Ingress Controller。
问题排查
非法请求:mse.backend.gw.MIGRATE_INGRESS_CLASS_CONFLICT
说明您的网关之前已经关联了该容器服务集群,并开启了Ingress监听,但是此处迁移时设置的IngressClass与原Ingress监听配置不一致,请确保IngressClass的配置一致。
如果您需要修改之前已配置的IngressClass,请按照实际情况选择以下方法:
如果您是通过MseIngressConfig管理MSE Ingress,请参见通过MSE Ingress访问容器服务进行修改。
如果您不是通过MseIngressConfig管理MSE Ingress,请至网关控制台的服务来源中修改对应容器集群的Ingress监听选项。
非法请求:mse.backend.gw.MIGRATE_SERVICE_ANNOTATION_NOT_MATCH [annotation is not expected]
说明您的K8s Service的注解未修改成指定注解。
非法请求:mse.backend.gw.MIGRATE_SERVICE_NOT_MATCH [weight hasn't be 0 or service hasn't been deleted]
说明K8s Service服务的注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight的值未设置为0或者K8s Service未删除,请到容器服务控制台修改该K8s Service服务的注解 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight的值为0,或者删除该K8s Service。