背景
由于业务需要,当前集群需要进行拆分,部分业务需要迁移到新的集群中。
此时在新老环境中各有一个ASM和一个ACK实例。
由于一些特殊原因,DNS切流无法覆盖所有客户端,部分客户端依然通过IP访问到老的网关。
本文主要介绍如何处理老网关上的流量。
推荐方案:使用网关作为TCP Proxy转发流量
1. 在旧集群中创建新网关的对应的ServiceEntry
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: new-gateway-se namespace: istio-system spec: hosts: - ${新网关SLB地址} addresses: - ${新网关SLB地址} ports: - number: 80 name: port-0 protocol: TCP - number: 443 name: port-1 protocol: TCP location: MESH_EXTERNAL resolution: STATIC endpoints: - address: ${新网关SLB地址} EOF
2. 保存当前已有的配置
保存网关配置
kubectl get gateway -A -o yaml > gateway.yaml
保存virtualservice配置:
kubectl get virtualservice -A -o yaml > virtualservice.yaml
vs全部下载之后,需要删除掉不在网关上生效的VS。
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: httpbin namespace: default spec: gateways: - default/httpbin hosts: - '*' http: - name: httpbin route: - destination: host: httpbin
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: httpbin namespace: default spec: gateways: - mesh # 没有gateways默认就是mesh hosts: - '*' http: - name: httpbin route: - destination: host: httpbin
3. 删除当前配置
kubectl delete -f gateway.yaml kubectl delete -f virtualservice.yaml
4. 创建流量规则,TCP原样转发到新网关
以下内容保存到tcp_gateway_rules.yaml
apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: tcp-gateway namespace: default spec: selector: istio: ingressgateway # 需要选中对应的网关 servers: - hosts: - '*' port: name: tcp-0 number: 80 protocol: TCP - hosts: - '*' port: name: tcp-1 number: 443 protocol: TCP --- apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: tcp-vs spec: hosts: - "*" gateways: - tcp-gateway tcp: - match: - port: 80 route: - destination: host: ${新网关SLB地址} port: number: 80 - match: - port: 443 route: - destination: host: ${新网关SLB地址} port: number: 443
执行
kubectl apply -f tcp_gateway_rules.yaml
5. 出现问题如何回滚
kubectl delete -f tcp_gateway_rules.yaml kubectl apply -f gateway.yaml kubectl apply -f virtualservice.yaml
6. 如果新旧两个网关在同一个VPC内部,如何通过内网访问呢?
假如您的新旧两个网关在同一个VPC内部,并且新的网关已经是公网SLB,并没有内网IP。
如何使用内网访问新的网关呢?
您可以给新的网关创建一个内网SLB。
手动创建一个Service,并且将这个Service绑定到ASM网关上即可。
首先您可以使用以下命令获取当前ASM网关的Service:
kubectl -n istio-system get svc istio-${asm网关名称} -o yaml > istio-gateway-svc.yaml
删除所有label。
修改一个新的name。
删除spec中的clusterIP和clusterIPs字段,删除status字段。
保存,重新apply
kubectl apply -f istio-gateway-svc.yaml
这样您就为这个网关创建了一个对应的内网SLB。注意:这个service只能用于迁移临时使用,在ASM网关上进行的任何配置变更都不会影响这个Service,迁移完成后请手动删除新创建的Service。