从Nginx Ingress迁移到MSE Ingress

本文介绍如何通过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/v1beta1networking.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-25745CVE-2021-25746CVE-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切流。

    image.png
  • 基于DNS解析

    原理:在DNS服务器中对于所有Nginx Ingress中关联的业务域名添加MSE SLB的解析结果,部分DNS服务商提供权重方式控制Nginx SLB和MSE SLB的流量比。

    image.png

前提条件

  • 已创建容器服务集群,且部署了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。

步骤一:路由规则迁移

  1. 登录MSE网关管理控制台

  2. 在顶部菜单栏选择地域。

  3. 在左侧导航栏,选择云原生网关 > 迁移上云

  4. 迁移上云页面,单击创建任务

  5. 创建迁移配置页面,进行相关配置。云原生网关将自动监听所选容器集群内且关联到源IngressClass的所有Ingress资源的变化,并生效Ingress资源中域名和路由的相关配置。

    重要

    如果目标云原生网关集群中已关联该容器集群,且已配置的IngressClass与此处的配置不同,则不允许迁移。请确保此处配置的IngressClass与已关联容器集群配置的IngressClass一致。

    配置项

    说明

    云原生网关实例

    选择要迁移至的目标云原生网关,版本要求至少为1.2.22。

    容器服务ACK/ACK Serverless集群

    选择要迁移的Nginx Ingress对应的容器集群,请确保云原生网关与容器集群网络是连通的。

    源IngressClass

    配置待迁移的Ingress资源关联的IngressClass资源。

    说明
    • 仅支持配置单个IngressClass。

    • 配置为空,即忽略IngressClass,表示监听集群中所有的Ingress资源。

    image.png

步骤二:路由校验

校验监听的Ingress的兼容性:

  • 如果无不兼容的Ingress Annotation,则继续下一步。

    image.png
  • 如果存在不兼容的Ingress Annotation,您可以提交工单咨询解决方案。

    重要
    • 注解nginx.ingress.kubernetes.io/service-weight的值为""可以忽略,该注解为旧版容器服务控制台默认添加,本身没有任何意义。

    • 迁移过程中,请勿删除线上正在使用的不兼容注解,因为这些不兼容的注解仍然被Nginx Ingress Controller解析并作用于您的业务流量。您可以在Ingress资源上额外添加MSE扩展的注解,在MSE Ingress实现相同的功能。待流量全部迁移至MSE Ingress之后,您可以按需删除不兼容的注解。

    image.png

步骤三:切流选择

切流前测试

正式切流前,建议先进行本地测试:修改本地hosts文件,为业务域名添加云原生网关SLB解析,通过curl或者postman等工具验证所有流量是否符合预期。

两种切流方式

复用原集群SLB

原理是将云原生网关节点实例添加到原SLB的后端服务器组中,在迁移过程中根据用户设置的权重分配业务流量到云原生网关。当迁移完成之后,访问该SLB的流量将全部转发至云原生网关。

image.png

相关配置项说明如下:

配置项

说明

容器集群命名空间

选择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

image.png
  1. 单击变更SLB, 系统自动将SLB脱离容器托管并修改监听调度算法为加权轮询

    重要

    该步骤会将SLB脱离容器托管,脱离之后无法感知Nginx Ingress Controller的Pod IP变化,请尽快按照下一步的要求修改注解,重新将K8s Service关联至SLB。

  2. 容器服务控制台中手工将复用原集群SLB选择的K8s Service的当前所有注解删除,并添加流量切换页面为您自动生成的注解。该步骤主要是将原K8s Service改为复用SLB,修改完成后,单击前置检查,检查通过后,会进入下一步。

  3. 设置转发云原生网关实例的流量权重,根据业务实际情况设置1~100,建议初次设置为1~10之间。

    1. 该值为云原生网关各节点的权重值总和,SLB会根据虚拟服务器组中云原生网关和 Nginx Ingress各节点的权重比值分配流量。其中Nginx Ingress节点的权重总和默认为100,所以当云原生网关权重也设为100,则承接1/2 流量。依此类推,当云原生网关权重设为50,则承接1/3流量。

    2. 迁移过程中,用户可以通过云原生网关提供的监控大盘观察网关各项指标,时刻关注网关健康状态以及业务指标是否符合预期。

      • 如果符合预期,可以逐步调大权重,修改权重的时间间隔要大于3分钟,因为后台是异步生效权重配置。

      • 如果不符合预期,权重设置为0即可,本次迁移终止。

    3. 您可以在容器服务控制台中将复用原集群SLB选择的K8s Service的注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight的值调低,间接调大云原生网关的权重。特别的,当该注解的值为0时,流量则全部导入云原生网关。

    4. SLB作为四层负载均衡,流量控制粒度为连接级别,该权重值无法精确控制请求级别的分发比例。

    5. 切流后如果出现成功率下跌,可将该权重设为0进行流量回滚。

      说明

      如果您希望长期处于迁移状态中,希望随时可以调整Nginx Ingress和MSE Ingress的流量权重,建议您长期处于当前步骤中。当您验证并确认流量符合预期,之后不再需要回滚所有流量到Nginx Ingress,可以点击完成流量验证继续下一步。

      重要

      单击完成流量验证后,将无法修改权重。

  4. 在容器服务控制台中将步骤三:切流选择选择的K8s Service服务的注解 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight的值设置为0,或者直接删除该Service资源,Nginx Ingress Controller的节点将会自动从该SLB摘除,则SLB的全部流量切换至云原生网关。

  5. 单击完成迁移,此次迁移任务结束。

DNS解析至云原生网关SLB

image.png

请前往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。