使用CLB的Nginx Ingress如何迁移至ASM网关

本文介绍使用CLBNginx Ingress如何迁移至ASM网关。

前提条件

  • 已创建ASM企业版或旗舰版实例,且实例版本为最新版本。具体操作,请参见创建ASM实例

  • 已添加ACK集群到ASM实例。具体操作,请参见添加集群到ASM实例

  • ACK集群的CCM版本不低于v2.4.0。

方案示意图

ASM

迁移步骤

重要

在步骤二完成之前,您需要保证NginxIngress的端点不要发生变更,禁止例如扩缩容、重启等操作。如您为NginxIngress配置了HPA,请在开始第二步操作之前暂时关闭HPA,待第二步完成之后再启用。

步骤一:将NginxIngressCLB设置为可复用

1)执行下面的命令获取nginx ingressCLB实例id:

$ kubectl -n kube-system get svc nginx-ingress-lb -o yaml|grep service.k8s.alibaba/loadbalancer-id
service.k8s.alibaba/loadbalancer-id: lb-bp1gts52ced2vgaw1ni78

2)打开阿里云负载均衡控制台,对该负载均衡实例进行如下操作:

  • 关闭配置修改保护。

  • 修改CLB名称,将类似a6536b38e4b5f4b44b8e172c********的名称改为${clusterid}-ingress,例如改为c553a74e6ad13423aa839c8e5********-ingress。

  • 删除负载均衡实例的以下标签:kubernetes.do.not.deleteack.aliyun.com

  • 将名称以k8s/开头的虚拟服务器组的名称修改为:shared-端口号。例如,k8s/80/nginx-ingress-lb/kube-system/c553a74e6ad13423aa839c8e5******** 修改为shared-80。

3)修改nginx ingressservice,加入如下annotation:

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: ${负载均衡实例id}

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "false"

重要

请务必仔细核对虚拟服务器组id和端口号正确,以及在具有多个服务器组+端口号时,正确地使用半角逗号进行了分割。

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-vgroup-port: 有多个端口及虚拟服务器组的组合,可以通过英文半角逗号(,)分隔。例如"${YOUR_VGROUP_ID_1}:80, ${YOUR_VGROUP_ID_2}:443"需要注意的是,这里要求提供的是虚拟服务器组的id,而不是之前命名的名称如shared-80。

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "100"

步骤二:创建ASM网关

重要

您创建的ASM网关在迁移过程中不应启用HPA能力,如您需要弹性伸缩能力,请在完成迁移后再通过ASM控制台为网关启用HPA。

您需要通过Yaml创建ASM网关,但是您仍然可以在ASM网关创建页面以可视化配置网关,并在配置完毕后点击页面底部的预览按钮以直接获得一个基础的yaml文件。在您获得该yaml后,您需要对这个yaml中的serviceAnnotations进行编辑,添加如下service annotation,以复用NginxIngressCLB实例。

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: ${负载均衡实例id}

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "false"

重要

请务必仔细核对虚拟服务器组id和端口号正确,以及在具有多个服务器组+端口号时,正确地使用半角逗号进行了分割。

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-vgroup-port: 有多个端口及虚拟服务器组的组合,可以通过英文半角逗号(,)分隔。例如"${YOUR_VGROUP_ID_1}:80, ${YOUR_VGROUP_ID_2}:443"需要注意的是,这里要求提供的是虚拟服务器组的id,而不是之前命名的名称如shared-80。

service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "0"

相关ServiceAnnotations举例如下:

 serviceAnnotations:
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "lb-xxxxx"  //lb-xxxxx替换为您通过负载均衡管理控制台创建的CLB实例ID。
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: 'false'  //需要显示地设置为false,因为Istiogateway默认是覆盖监听的方式。
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-vgroup-port: "${YOUR_VGROUP_ID}:80"   //${YOUR_VGROUP_ID}替换为虚拟服务器。
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "0"   //设置Service流量权重,初始设置为0,ASM网关不接受流量。

步骤三:手动Translate IngressVS、DRIstio侧的配置

请参照如下Ingress配置,将Ingress翻译为Istio对应的VirtualService配置。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: helloworld
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - http:
        paths:
          - backend:
              serviceName: helloworld
              servicePort: 80
            path: /helloworld(/|$)(.*)
      host: example.com

预期结果:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: example-vs
spec:
  gateways:
  - istio-system/ingressgateway  ## your gateway name
  hosts:
  - example.com
  http:
  - name: route-helloworld
    match:
    - uri:
        prefix: /helloworld/
    - uri:
        prefix: /helloworld
    rewrite:
      uri: /
    route:
    - destination:
        host: helloworld
        port:
          number: 80

VirtualServiceDestinationrule可以和对应的服务Deployment放在同一个Namespace。如果不在同一个Namespace,对应的destination.host字段需要填写为FQDN格式。

步骤四:验证流量

Ingress配置转换为对应的VirtualService后,您还需要进行验证测试,确认配置是否正确以及是否生效。因此需要进行验证测试。参考方案示意图,您可以手动新建一个CLB,然后发送测试流量请求至该CLB进行测试流量验证,或是直接在集群内请求ASM入口网关服务,通过测试结果判断配置是否正确。

步骤五:调整Ingress对应的CLB下各个后端实例的权重,将流量逐渐迁移到ASM网关

推荐对应ASM网关实例的权重设置为一个较小的值(如1%),观察线上请求是否符合预期,一定时间后逐渐增加,直到全部切换到ASM网关。

说明

在您调整NginxIngressASM网关的权重时,CLB的转发权重总是按照端点权重占所有端点权重之和的比例进行转发。例如,您先将ASM网关的权重改为10,此时,若NginxIngress的权重为100,则总权重将为110,此时ASM网关的真实权重为10/110。

权重调整方式如下:

  • ASM网关的实例对应权重可以通过IstioGateway下的ServiceAnnotaions进行调整,对应service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "60"

  • Nginx实例对应的权重,可以通过编辑相关Service下的Annotation:service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight进行操作。若Service未配置权重相关Annotation,Nginx Ingress实例的分发权重可以直接通过CLB控制台下进行权重配置操作。