本文介绍使用CLB的Nginx Ingress如何迁移至ASM网关。
前提条件
已创建ASM企业版或旗舰版实例,且实例版本为最新版本。具体操作,请参见创建ASM实例。
已添加ACK集群到ASM实例。具体操作,请参见添加集群到ASM实例。
ACK集群的CCM版本不低于v2.4.0。
方案示意图
迁移步骤
在步骤二完成之前,您需要保证NginxIngress的端点不要发生变更,禁止例如扩缩容、重启等操作。如您为NginxIngress配置了HPA,请在开始第二步操作之前暂时关闭HPA,待第二步完成之后再启用。
步骤一:将NginxIngress的CLB设置为可复用
1)执行下面的命令获取nginx ingress的CLB实例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.delete
、ack.aliyun.com
。将名称以k8s/开头的虚拟服务器组的名称修改为:shared-端口号。例如,k8s/80/nginx-ingress-lb/kube-system/c553a74e6ad13423aa839c8e5******** 修改为shared-80。
3)修改nginx ingress的service,加入如下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,以复用NginxIngress的CLB实例。
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 Ingress为VS、DR等Istio侧的配置
请参照如下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
VirtualService和Destinationrule可以和对应的服务Deployment放在同一个Namespace。如果不在同一个Namespace,对应的destination.host字段需要填写为FQDN格式。
步骤四:验证流量
Ingress配置转换为对应的VirtualService后,您还需要进行验证测试,确认配置是否正确以及是否生效。因此需要进行验证测试。参考方案示意图,您可以手动新建一个CLB,然后发送测试流量请求至该CLB进行测试流量验证,或是直接在集群内请求ASM入口网关服务,通过测试结果判断配置是否正确。
步骤五:调整Ingress对应的CLB下各个后端实例的权重,将流量逐渐迁移到ASM网关
推荐对应ASM网关实例的权重设置为一个较小的值(如1%),观察线上请求是否符合预期,一定时间后逐渐增加,直到全部切换到ASM网关。
在您调整NginxIngress或ASM网关的权重时,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控制台下进行权重配置操作。