服务网格 ASM 的流量管理功能可以实现应用的流量迁移。本文将通过示例介绍如何通过 ASM 实现 TCP 应用流量的迁移。
前提条件 已开通以下服务: 服务网格 ASM 容器服务 负载均衡 已创建至少一个 ACK 集群。如果没有创建,请参见创建Kubernetes集群和创建 Kubernetes 托管版集群。 已创建一个 ASM 实例,并已将 ACK 集群添加到 ASM 实例中,请参见创建 ASM 实例和添加集群到 ASM 实例。 背景信息 本文以 Istio 官方 Task TCP-Traffic-Shifting 为例来讲述如何实现在一个TCP 服务的两个版本之间进行流量灰度切换。该 Task 中的服务是一个简单地 Echo 服务,在 v1 版本中,该服务在收到的数据在前面加上“one”并返回;在 v2 版本中,该服务在收到的数据前面加上“two”并返回。
步骤 一:部署示例应用 我们需要部署两个Deployment,如下图所示,打开容器服务控制台,选择应用 - 无状态,然后选择您希望部署的目标集群和namespace,然后点击右上方的使用模版创建。
apiVersion: apps/v1 kind: Deployment metadata: name: tcp-echo-v2 spec: replicas: 1 selector: matchLabels: app: tcp-echo version: v2 template: metadata: labels: app: tcp-echo version: v2 spec: containers: - name: tcp-echo image: docker.io/istio/tcp-echo-server:1.1 imagePullPolicy: IfNotPresent args: [ "9000", "two" ] ports: - containerPort: 9000 在无状态(Deployment)页面可以看到新创建的两个版本的 TCP-Echo 应用。TCP-Eco list 创建一个服务,并将其对外暴露。 登录容器服务控制台。 在左侧导航栏中选择路由与负载均衡 > 服务。 在服务(Service)页面,单击右上角的创建。 在创建服务对话框中,设置服务的相关信息,单击创建。 需要设置的参数如下所示: 名称:设为 tcp-echo 关联:选择 tcp-echo-v1。 说明 将从关联的 Deployment 中提取 app 这个标签作为 Service 的 Selector,这决定了 Kubernetes service 将流量转发到哪个 Deployment。由于tcp-echo-v1 和 tcp-echo-v2 两个 Deployment 拥有相同的标签,即 app:tcp-echo,因此可以关联任一 Deployment。 端口映射:名称设为 tcp;服务端口和容器端口设为 9000;协议设为 TCP。 在服务(Service)页面可以看到新创建的服务,type-echo。 步骤二:设置服务网格 ASM 的路由规则 通过设置服务网格的 Istio 网关、虚拟服务和目标规则,将流量全部指向 tcp-echo 服务的 v1 版本。
登录 ASM 控制台。 在左侧导航栏,选择服务网格 > 网格实例。 在网格实例页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。 创建 Istio 网关。 在控制平面区域,选择Istio网关页签,然后单击新建。 在新建页面,从命名空间下拉列表中选择 default,并在文本框中输入以下 Yaml 文件内容,单击确定。 apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: tcp-echo-gateway spec: selector: istio: ingressgateway servers: - port: number: 31400 name: tcp protocol: TCP hosts: - "" 在Istio网关页签下可以看到新创建的名为 tcp-echo-gateway 的 Istio 网关。 创建虚拟服务。 在控制平面区域,选择虚拟服务页签,然后单击新建。 在新建页面,从命名空间下拉列表中选择 default,并在文本框中输入以下 Yaml 文件内容,单击确定。 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: tcp-echo spec: hosts: - "" gateways: - tcp-echo-gateway tcp: - match: - port: 31400 route: - destination: host: tcp-echo port: number: 9000 subset: v1 在虚拟服务页签下可以看到新创建的名为 tcp-echo 的虚拟服务。 创建目标规则。 在控制平面区域,选择目标规则页签,然后单击新建。 在新建页面,从命名空间下拉列表中选择 default,并在文本框中输入以下 Yaml 文件内容,单击确定。 apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: tcp-echo-destination spec: host: tcp-echo subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 在目标规则页签下可以看到新创建的名为 tcp-echo-destination 的目标规则。 步骤三:部署入口网关 在入口网关中,添加端口 31400,并指向 Istio 网关的 31400 端口。
登录 ASM 控制台。 在左侧导航栏,选择服务网格 > 网格实例。 在网格实例页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。 在数据平面区域,单击部署入口网关。 在部署入口网关页面,为集群添加入口网关。 从部署集群列表中选择要部署入口网关的集群。 指定负载均衡的类型为公网访问。 选择负载均衡。 使用已有负载均衡:从已有负载均衡列表中选择。 新建负载均衡:单击新建负载均衡,从下拉列表中选择所需的负载均衡规格。 说明 建议您为每个 Kubernetes 服务分配一个 SLB。如果多个 Kubernetes 服务复用同一个 SLB,存在以下风险和限制: 使用已有的 SLB 会强制覆盖已有监听,可能会导致您的应用不可访问。 Kubernetes 通过 Service 创建的 SLB 不能复用,只能复用您手动在控制台(或调用 OpenAPI)创建的 SLB。 复用同一个 SLB 的多个 Service 不能有相同的前端监听端口,否则会造成端口冲突。 复用 SLB 时,监听的名字以及虚拟服务器组的名字被 Kubernetes 作为唯一标识符。请勿修改监听和虚拟服务器组的名字。 不支持跨集群复用 SLB。 单击添加端口,将名称设为 tcp,服务端口和容器端口设为 31400。 说明 服务端口指的是整个网格对外暴露的端口,是外部访问使用的端口;而容器端口指的是从服务端口进来的流量所指向的 Istio 网关端口,所以容器端口需要与 Istio 网关一致。 单击确定。 步骤四:检查部署结果 通过 Kubectl 确认 tcp-echo 服务的流量指向是否符合预期。
通过 Kubectl 客户端连接至 Kubernetes 集群。详情请参见通过kubectl连接Kubernetes集群。 执行以下命令,获得服务的地址与端口。 $ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}') 使用 telnet 指令向 tcp-echo 服务发起连接请求。 $ telnett $INGRESS_HOST $INGRESS_PORT Trying xxx.xxx.xxx.xxx... Connected to xxx.xxx.xxx.xxx. Escape character is '^]' 输入任意字符串,按 Enter 发送,返回的字符串前面带了“one”。这说明 tcp-echo 服务已经成功部署,且流量全部指向了 tcp-echo-v1版本。 步骤五:按比例将流量路由到 tcp-echo-v2 此处将 20% 的流量指向 tcp-echo-v2 版本,其余 80% 仍然打到 tcp-echo-v1。
修改 ASM 实例的虚拟服务配置。 在控制平面区域,选择虚拟服务页签 在虚拟服务页面,单击 tcp-echo 所在操作列中的 yaml。 在虚拟服务页签下可以看到新创建的名为 tcp-echo 的虚拟服务。 在编辑实例页面的文本框中输入以下 Yaml 文件内容,单击确定。 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: tcp-echo spec: hosts: - "*" gateways: - tcp-echo-gateway tcp: - match: - port: 31400 route: - destination: host: tcp-echo port: number: 9000 subset: v1 weight: 80 - destination: host: tcp-echo port: number: 9000 subset: v2 weight: 20 执行以下命令,向 tcp-echo 服务发起 10 次请求。 $ for i in {1..10}; do
docker run -e INGRESS_HOST=$INGRESS_HOST -e INGRESS_PORT=$INGRESS_PORT -it --rm busybox sh -c "(date; sleep 1) | nc $INGRESS_HOST $INGRESS_PORT";
done one Mon Nov 12 23:38:45 UTC 2018 two Mon Nov 12 23:38:47 UTC 2018 one Mon Nov 12 23:38:50 UTC 2018 one Mon Nov 12 23:38:52 UTC 2018 one Mon Nov 12 23:38:55 UTC 2018 two Mon Nov 12 23:38:57 UTC 2018 one Mon Nov 12 23:39:00 UTC 2018 one Mon Nov 12 23:39:02 UTC 2018 one Mon Nov 12 23:39:05 UTC 2018 one Mon Nov 12 23:39:07 UTC 2018 根据以上请求的分发情况,可以看到 20% 的流量指向了 tcp-echo-v2。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。