Istio 金丝雀/蓝绿/A/B Testing

内容纲要

在Istio中实现金丝雀发布,蓝绿部署和A/B测试

Istio的流量管理功能允许我们在不影响服务稳定性的前提下,进行更灵活的服务部署和测试。这包括金丝雀发布,蓝绿部署,以及A/B测试。

在本文中,我们将通过一个名为 sales-order 的服务示例来演示这些策略。该服务有两个版本,v0和v1,这有助于我们调整并观察不同策略的影响。

前提条件

在开始之前,你需要拥有一个运行Istio服务网格的Kubernetes集群,以及两个版本的sales-order服务。这些服务的Kubernetes配置文件可在此处下载:GitHub链接

以下是sales-order服务的两个版本的Kubernetes deployments和service:

  • sales-order服务v0版本的Kubernetes YAML文件:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sales-order-deployment
  labels:
    app: sales-order
    version: v0
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sales-order
  template:
    metadata:
      labels:
        app: sales-order
        version: v0
    spec:
      containers:
        - name: sales-order
          image: fofcn/sales-order:latest
          ports:
            - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: sales-order-service
spec:
  type: ClusterIP
  selector:
    app: sales-order
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  • sales-order服务v1版本的Kubernetes YAML文件:
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sales-order-deployment-v1
  labels:
    app: sales-order
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sales-order
      version: v1
  template:
    metadata:
      labels:
        app: sales-order
        version: v1
    spec:
      containers:
        - name: sales-order-v1
          image: fofcn/sales-order-v1:latest
          ports:
            - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: sales-order-service
spec:
  type: ClusterIP
  selector:
    app: sales-order
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

你可以通过kubectl apply -f [文件名]命令部署sales-order服务的两个版本。

你已经部署好Istio并使其在这两个版本的服务中生效,下面我们可以进行下一步。

金丝雀发布(Canary)

在金丝雀发布中,我们将一小部分流量引向新版本的服务,并逐渐增加给新版本的流量比例,直到完全切换到新版本。

我们可以在Istio的 VirtualService 中设置,将80%的流量路由到 v0 版本,20%的流量路由到 v1 版本,以实现金丝雀部署:

# canary-deployment.yaml
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: sales-order-gateway
spec:
  selector:
    istio: ingressgateway # Use Istio default gateway implementation
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sales-order-vs
spec:
  hosts:
    - "*" 
  gateways:
    - sales-order-gateway
  http:
    - match:
        - uri:
            prefix: "/api/v1/order"
      route:
        - destination:
            host: sales-order-service
            subset: v0
            port:
              number: 8080
          weight: 80
        - destination:
            host: sales-order-service
            subset: v1
            port:
              number: 8080
          weight: 20
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sales-order-dr
spec:
  host: sales-order-service
  trafficPolicy:
    loadBalancer:
      simple: LEAST_REQUEST
    connectionPool:
      tcp:
        maxConnections: 1
        connectTimeout: 30ms
        tcpKeepalive:
          time: 7200s
          interval: 75s

  subsets:
    - name: v0
      labels:
        version: v0
    - name: v1
      labels:
        version: v1
---

你可以使用以下命令来部署此金丝雀发布策略:

kubectl apply -f canary-deployment.yaml

现在,你可以观察并验证你的服务是否按照你期望的方式进行金丝雀发布。

蓝绿部署(Blue-Green Deployment)

在蓝绿部署中,我们会保持两个独立的环境,即“蓝”环境和“绿”环境。在生产环境(“蓝”)中,服务的旧版本正在运行,而在预生产环境(“绿”)中,服务的新版本正在运行。一旦我们确认新版本的功能和性能满足需求,我们就可以通过修改Istio的 VirtualService 来将所有流量一次性切换到新版本。

---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: sales-order-gateway
spec:
  selector:
    istio: ingressgateway # Use Istio default gateway implementation
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sales-order-vs
spec:
  hosts:
    - "*" # 对所有请求都进行匹配
  gateways:
    - sales-order-gateway
  http:
    - match:
        - uri:
            prefix: "/api/v1/order"
      route:
        - destination:
            host: sales-order-service
            subset: v0
            port:
              number: 8080
          weight: 0
        - destination:
            host: sales-order-service
            subset: v1
            port:
              number: 8080
          weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sales-order-dr
spec:
  host: sales-order-service
  trafficPolicy:
    loadBalancer:
      simple: LEAST_REQUEST
    connectionPool:
      tcp:
        maxConnections: 1
        connectTimeout: 30ms
        tcpKeepalive:
          time: 7200s
          interval: 75s

  subsets:
    - name: v0
      labels:
        version: v0
    - name: v1
      labels:
        version: v1
---

然后,你可以使用下面这条命令部署此蓝绿部署策略:

kubectl apply -f blue-green-deployment.yaml

你现在应该注意到在你的Istio服务网格中,所有的流量都被切换到了新的服务。

A/B测试

在A/B测试中,我们将会针对两个版本的服务进行流量分发,然后分析各版本的性能指标以决定哪个版本更优。

Istio可以通过HTTP头部信息、请求路径等进行流量分发,以便我们对不同的用户群体或请求类型进行A/B测试。

进行 A/B 测试,我们可以根据请求的 headers 来路由到对应版本的服务。比如我们可以根据 x-version 的值为 v0 或 v1 来决定路由,那么在用户发送请求时,就可以在其 headers 中添加 x-version: v0 或 x-version: v1 来控制请求路由到哪个版本的服务。

# ab-testing.yaml
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: sales-order-gateway
spec:
  selector:
    istio: ingressgateway # Use Istio default gateway implementation
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sales-order-vs
spec:
  hosts:
    - "*" # 对所有请求都进行匹配
  gateways:
    - sales-order-gateway
  http:
    - match:
        - uri:
            prefix: "/api/v1/order"
          headers:
            x-version:
              exact: "v1"
      route:
        - destination:
            host: sales-order-service
            subset: v1
            port:
              number: 8080
          weight: 100
    - match:
        - uri:
            prefix: "/api/v1/order"
          headers:
            x-version:
              exact: "v0"
      route:
        - destination:
            host: sales-order-service
            subset: v0
            port:
              number: 8080
          weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sales-order-dr
spec:
  host: sales-order-service
  trafficPolicy:
    loadBalancer:
      simple: LEAST_REQUEST
    connectionPool:
      tcp:
        maxConnections: 1
        connectTimeout: 30ms
        tcpKeepalive:
          time: 7200s
          interval: 75s

  subsets:
    - name: v0
      labels:
        version: v0
    - name: v1
      labels:
        version: v1
---

最后,你可以运行下面这条命令来部署此A/B测试策略:

kubectl apply -f ab-testing.yaml

恭喜你!现在你可以在Istio服务网格中进行A/B测试了。

总结

使用Istio我们可以很容易的实现金丝雀,蓝绿和A/B测试。

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部