TLDR
除了我在评论中提到的内容之外,在更详细地检查了这个主题后,我会选择“方法2”,使用一个总体的特定微服务的“虚拟服务”,进行“金丝雀部署”和“镜像”。
方法1
如
documentation中所述:
“在某些情况下,为特定主机定义完整的路由规则或策略不方便,可能更倾向于逐步在多个资源中指定主机的配置。如果它们绑定到网关,Pilot将合并这样的目标规则并合并这样的虚拟服务。”
因此,从理论上讲,您可以选择方法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
方法二
实际上,我会选择第二种方法。例如,你可以创建你的应用程序的两个版本,在下面的例子中是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这样的平台已经提供了一种进行版本发布和金丝雀部署的方式。问题解决了,对吧?嗯,并不完全是这样。虽然以这种方式进行发布在简单情况下是有效的,但在大规模云环境中接收大量(尤其是数量不同的)流量时非常受限,需要自动缩放。
与Kubernetes相比,Istio的流量路由和副本部署是两个完全独立的功能。实现服务的pod数目可以根据交通负载自由扩展和缩小,完全与版本流量路由控制无关。这使得在自动缩放存在的情况下管理金丝雀版本成为一个更简单的问题。实际上,自动缩放器可能会对交通路由变化导致的负载变化做出响应,但它们仍然是独立运行的,并且在负载因其他原因而改变时也不会有任何不同。
Istio的路由规则还提供了其他重要优点;您可以轻松地控制细粒度的流量百分比(例如,将1%的流量路由到不需要100个pod)并且可以使用其他标准来控制流量(例如,将特定用户的流量路由到金丝雀版本)。为了说明问题,让我们来看看部署helloworld服务并了解问题变得多么简单。
有一个示例。
镜像
第二个经常用于测试应用程序新版本的东西是流量镜像。
如此处所述:
使用 Istio,您可以使用流量镜像将流量复制到另一个服务。您可以将流量镜像规则作为金丝雀部署管道的一部分,允许您在向其发送实时流量之前分析服务的行为。
如果您正在寻找最佳实践,我建议从这个中等教程开始,因为这里解释得非常好。
流量镜像的工作原理
流量镜像是通过以下步骤进行的:
1. 部署应用程序的新版本并打开流量镜像。
2. 旧版本像以前一样响应请求,但也会异步地将副本发送到新版本。
3. 新版本处理流量,但不会向用户响应。
4. 运营团队监视新版本并向开发团队报告任何问题。
![enter image description here](https://istack.dev59.com/Yg2xK.webp)
由于该应用程序处理实时流量,因此它有助于团队发现通常在预生产环境中无法发现的问题。您可以使用监控工具(例如Prometheus和Grafana)记录和监控测试结果。
此外,还有一个nginx示例,完美地展示了它应该如何工作。
值得一提的是,如果您使用写API(如订单或付款),那么镜像流量将意味着多次写入API(如订单)。这个主题由Christian Posta在
这里中详细描述。
请告诉我,如果您还有其他想要讨论的事情。