TLDR
除了我在评论中提到的之外,在对该主题进行更详细的检查后,我会选择方法 2 ,为特定微服务提供一个整体虚拟服务,并带有金丝雀部署和镜像。
方法一
如文档中所述
在不方便在单个 VirtualService 或 DestinationRule 资源中为特定主机定义完整的路由规则或策略集的情况下,最好在多个资源中逐步指定主机的配置。如果绑定到网关,Pilot 将合并此类目标规则并合并此类虚拟服务。
所以理论上你可以使用方法 1,但我会说有太多的配置,这样做有更好的主意。
假设您有 name 的旧应用程序和 namev1.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 个版本,在下面的示例中old
,new
然后为它配置虚拟服务和目标规则。
这里的问题是,为什么?因为它更容易管理,至少对我来说是这样,而且在这里使用金丝雀部署和镜像很容易,下面会详细介绍。
假设您部署了新应用程序,您不想在这里发送 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
测试新应用程序
客户端显然需要通过设置标头或通过解析不同的服务名称来指定他想要谈论的主要版本。
实际上,这取决于配置,如果您将上述选项与new
版本一起使用old
,那么这就是金丝雀部署(例如加权分布)的用途。您可以指定应发送到应用程序新版本的流量百分比。当然,您可以在虚拟服务中指定标头或前缀,以便用户可以使用您的应用程序的旧版本或新版本。
金丝雀部署
正如这里提到的
Istio 项目的好处之一是它提供了部署金丝雀服务所需的控制。金丝雀部署(或推出)背后的想法是通过首先使用一小部分用户流量对其进行测试来引入新版本的服务,然后如果一切顺利,可能会逐渐增加百分比,同时逐步淘汰旧版本。如果在此过程中出现任何问题,我们将中止并回滚到以前的版本。在最简单的形式中,发送到金丝雀版本的流量是随机选择的请求百分比,但在更复杂的方案中,它可以基于请求的区域、用户或其他属性。
根据您在该领域的专业水平,您可能想知道为什么甚至需要 Istio 对金丝雀部署的支持,因为像 Kubernetes 这样的平台已经提供了一种进行版本发布和金丝雀部署的方法。问题解决了,对吧?嗯,不完全是。尽管以这种方式进行部署在简单的情况下有效,但它非常有限,尤其是在接收大量(尤其是变化量)流量的大型云环境中,需要自动缩放。
istio
使用 Istio,流量路由和副本部署是两个完全独立的功能。实现服务的 Pod 数量可以根据流量负载自由伸缩,与版本流量路由的控制完全正交。这使得在存在自动缩放的情况下管理金丝雀版本成为一个更简单的问题。事实上,自动缩放器可能会响应流量路由变化导致的负载变化,但它们仍然独立运行,与负载因其他原因发生变化时没有什么不同。
Istio 的路由规则还提供其他重要优势;您可以轻松控制细粒度的流量百分比(例如,路由 1% 的流量而不需要 100 个 Pod),并且您可以使用其他标准控制流量(例如,将特定用户的流量路由到金丝雀版本)。为了说明这一点,让我们看一下部署 helloworld 服务,看看问题变得多么简单。
有一个例子。
镜像
经常用于测试新版本应用程序的第二件事是流量镜像。
正如这里提到的
使用 Istio,您可以使用流量镜像将流量复制到另一个服务。您可以将流量镜像规则合并为 Canary 部署管道的一部分,允许您在向其发送实时流量之前分析服务的行为。
如果您正在寻找最佳实践,我建议您从本教程开始,因为它在这里得到了很好的解释。
流量镜像的工作原理
流量镜像使用以下步骤工作:

当应用程序处理实时流量时,它可以帮助团队发现他们在预生产环境中通常不会发现的问题。您可以使用 Prometheus 和 Grafana 等监控工具来记录和监控您的测试结果。
此外,还有一个 nginx 示例完美地展示了它应该如何工作。
值得一提的是,如果你使用写API,比如订单或支付,那么镜像流量将意味着多次写API,比如订单。Christian Posta在此处详细描述了该主题。
让我知道您是否还有其他要讨论的内容。