如何处理服务网格中的重大更改

如何解决如何处理服务网格中的重大更改

我正在使用Kubernetes构建示例微服务应用程序,以找出最佳方案和未来项目的一些模式。我正在使用Istio作为服务网格来处理东西向的流量,并且我对概念(VirtualServices,DestinationRules等)有基本的了解。服务网格使我能够轻松推出微服务的新版本并将流量重定向到新实例(例如使用加权分配)。考虑到语义版本控制,这对于PatchMinor更新确实非常有效,因为从理论上讲,它们不会更改现有合同,因此可以替代现有合同服务。现在,我想知道如何正确处理服务的重大更改,因此进行了Major版本的更新。

很难找到关于此的信息,但是由于我得到的信息有限,我现在正在考虑两种方法:

  1. 服务的每个主要版本(例如user-service)都有自己的VirtualService,以便客户端可以正确地寻址(通过不同的服务名称,例如user-service-v1)。然后,使用Istio将主要版本(例如1.*)的流量正确路由到其他可用服务(例如user-service v1.3.1user-service v1.4.0)。

  2. 我为特定的微服务总共使用了VirtualService(例如user-service)。 VirtualService包含许多要使用的路由定义,例如客户端发送的标头(例如x-major-version=1),以将请求与目标匹配。

总体而言,两种方法之间没有太大差异。显然,客户端需要通过设置标头或解析其他服务名称来指定要与哪个主要版本通信。所描述的方法是否存在任何局限性?还是我完全没有其他选择?任何帮助和指示,我们将不胜感激!

解决方法

TLDR

除了我在评论中提到的内容外,在对该主题进行了更详细的检查之后,我会选择方法2 ,为特定的微服务选择一个整体虚拟服务 > canary部署镜像

方法1

documentation

中所述

在单个VirtualService或DestinationRule资源中为特定主机定义完整的路由规则或策略集的情况下,最好在多个资源中递增地指定主机的配置。如果将它们绑定到网关,飞行员将合并这些目标规则并合并这些虚拟服务。

因此,在理论中,您可以采用方法1,但是我想说的是太多的配置,并且有更好的主意。

假设您有名称为v1.3.1的旧应用程序和名称为v1.4.0的新应用程序,因此适当的虚拟服务如下所示。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-vervice1
spec:
  hosts:
  - '*'
  http:
  - name: "v1.3.1"
    route:
    - destination:
        host: service1.namespace.svc.cluster.local

---

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-service2
spec:
  hosts:
  - '*'
  http:
  - name: "v1.4.0"
    route:
    - destination:
        host: service2.namespace.svc.cluster.local

方法2

实践中,我将采用方法2,例如,您可以创建2个版本的应用,在下面的示例中,分别为oldnew,然后 为其配置虚拟服务和目标规则。

这里的问题是,为什么?因为它更易于管理(至少对我而言),并且在此处易于使用canary部署和镜像,请参见下文。

假设您部署了新的应用程序,那么您将不会在此处发送1%的传入流量,此外,您还可以使用镜像,因此发往旧服务的每个请求都将被镜像到新服务以进行测试。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-vervice
spec:
  hosts:
  - '*'
  http:
  - name: "old"
    route:
    - destination:
        host: service.namespace.svc.cluster.local
        subset: v1
      weight: 99
    mirror:
      host: service.namespace.svc.cluster.local
      subset: v2
    mirror_percent: 100
  - name: "new"
    route:
    - destination:
        host: service.namespace.svc.cluster.local
        subset: v2
      weight: 1

---


apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews-destination
spec:
  host: service.namespace.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1  <--- label on old pod
  - name: v2
    labels:
      version: v2  <--- label on new pod

测试新应用程序

客户显然需要通过设置标头或通过解析其他服务名称来指定他要使用的主要版本。

实际上,这取决于配置,如果您将以上选项与newold版本一起使用,则这就是金丝雀部署,例如加权分布,用于。您可以指定应发送到应用程序新版本的流量百分比。当然,您可以在虚拟服务中指定标头或前缀,以便用户可以使用旧版本或新版本的应用程序。

金丝雀部署

如上所述here

Istio项目的好处之一是,它提供了部署金丝雀服务所需的控制。金丝雀部署(或推出)背后的想法是引入一种新版本的服务,方法是首先使用一小部分用户流量对其进行测试,然后,如果一切顺利,则在逐步淘汰该百分比的同时逐步增加(可能会逐步增加)旧版本。如果在此过程中出现任何问题,我们将中止并回滚到以前的版本。以最简单的形式,发送到canary版本的流量是随机选择的请求百分比,但在更复杂的方案中,流量可以基于请求的区域,用户或其他属性。

根据您在该领域的专业水平,您可能想知道为什么还需要Istio对Canary部署的支持,因为Kubernetes等平台已经提供了进行版本发布和Canary部署的方法。问题解决了吧?好吧,不完全是。尽管以这种方式进行推广在简单的情况下是可行的,但它非常有限,尤其是在需要大量(特别是数量不同)流量且需要自动扩展的大规模云环境中。

istio

使用Istio,流量路由和副本部署是两个完全独立的功能。实施服务的Pod数量可以根据流量负载自由扩展和缩小,完全与版本流量路由的控制正交。这使得在存在自动缩放比例的情况下管理金丝雀版本变得简单得多。实际上,自动定标器可以响应因流量路由更改而导致的负载变化,但是它们仍独立运行,与负载因其他原因而变化时没有什么不同。

Istio的路由规则还具有其他重要优势;您可以轻松控制细粒度的流量百分比(例如,将流量的1%路由而不需要100个Pod),并且可以使用其他条件控制流量(例如,将特定用户的流量路由到canary版本)。为了说明这一点,让我们看一下部署helloworld服务,看看问题变得多么简单。

有一个example

镜像

经常用于测试应用程序新版本的第二件事是流量镜像。

如上所述here

使用Istio,您可以使用流量镜像将流量复制到另一个服务。您可以将流量镜像规则纳入金丝雀部署管道的一部分,从而可以在向其发送实时流量之前分析服务的行为。

如果您正在寻找最佳实践,我建议从中等水平开始使用此tutorial,因为这里对此有很好的解释。

流量镜像的工作原理

流量镜像按以下步骤工作:

  • 您部署该应用程序的新版本并打开流量 镜像。

  • 旧版本像以前一样响应请求,但还会向新版本发送异步副本。

  • 新版本处理流量,但不响应用户。

  • 操作团队将监视新版本,并向开发团队报告所有问题。

enter image description here

当应用程序处理实时流量时,它可以帮助团队发现在生产前环境中通常不会发现的问题。您可以使用Prometheus和Grafana等监视工具来记录和监视测试结果。

此外,还有一个有关nginx的示例,完美地展示了它应该如何工作。

值得一提的是,如果您使用订单或付款之类的写API,那么镜像流量将意味着多次写订单之类的写API。克里斯蒂安·波斯塔({@ 3)}对这个主题进行了详细的描述。


让我知道您还有什么要讨论的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res