开发者社区> 问答> 正文

如何通过 ASM 实现 TCP 应用流量迁移?

如何通过 ASM 实现 TCP 应用流量迁移?

展开
收起
小天使爱美 2020-03-20 20:18:29 804 0
1 条回答
写回答
取消 提交回答
  • 服务网格 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,然后点击右上方的使用模版创建。

    部署 TCP- Echo 应用的 2 个版本。 登录容器服务控制台。 在左侧导航栏中选择应用 > 无状态。 在集群和命名空间下拉列表中依次选择要部署的目标集群和命名空间。选择目标集群和命名空间 单击右上方的使用模版创建。 在使用模板创建页面,将下面的 Yaml 模版粘贴到模版文本框中,单击创建。 apiVersion: apps/v1 kind: Deployment metadata: name: tcp-echo-v1 spec: replicas: 1 selector: matchLabels: app: tcp-echo version: v1 template: metadata: labels: app: tcp-echo version: v1 spec: containers: - name: tcp-echo image: docker.io/istio/tcp-echo-server:1.1 imagePullPolicy: IfNotPresent args: [ "9000", "one" ] ports: - containerPort: 9000

    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。

    2020-03-20 20:19:07
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
基于英特尔®架构的阿里云服务网格ASM技术加速应用服务加密通 立即下载
阿里云总监课第五期第四节:从容器到云原生–服务网格 立即下载
TCP Cluster for mqtt技术实施方案 立即下载