Kubernetes 中的金丝雀部署 #3:Istio

使用 Istio+Kiali 启动和可视化 Canary 部署

Kubernetes 中的金丝雀部署 #3:Istio

本系列文章

  1. Kubernetes 中的金丝雀部署 #1:Gitlab CI
  2. Kubernetes 中的 Canary 部署 #2:Argo 推出
  3. (本文)
  4. 使用 Jenkins-X Istio Flagger 进行金丝雀部署

金丝雀部署

我们希望您阅读 第一部分,我们简要解释了 Canary 部署是什么,并展示了如何使用标准 Kubernetes 资源来实现它们。

Istio

我们假设通过阅读本文,您已经了解 Istio 是什么。 如果没有,那么您可以阅读相关内容 这里.

申请测试

Kubernetes 中的金丝雀部署 #3:Istio

每个 Pod 包含两个容器:我们的应用程序和 istio-proxy。

我们将使用一个带有前端 nginx 和后端 python pod 的简单测试应用程序。 nginx pod 将简单地将每个请求重定向到后端 pod 并充当代理。 详细信息可以在以下 yaml 中找到:

自己运行测试应用程序

如果您想按照我的示例并自己使用此测试应用程序,请参阅 项目自述文件.

初始部署

当我们启动第一个 Deployment 时,我们看到应用程序的 pod 只有 2 个容器,即 Istio sidecar 刚刚实现:

Kubernetes 中的金丝雀部署 #3:Istio

我们还在命名空间中看到 Istio Gateway Loadbalancer istio-system:

Kubernetes 中的金丝雀部署 #3:Istio

流量产生

我们将使用以下 IP 生成前端 Pod 接收并转发到后端 Pod 的流量:

while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done

我们还将添加 frontend.istio-test 到我们的主机文件。

通过 Kiali 查看网格

我们安装了测试应用程序和 Istio,以及 Tracing、Grafana、Prometheus 和 Kiali(详细信息见下文)。 项目自述文件)。 因此我们可以通过以下方式使用 Kiali:

istioctl dashboard kiali # admin:admin

Kubernetes 中的金丝雀部署 #3:Istio

Kiali 通过 Mesh 可视化当前流量

正如我们所看到的,100% 的流量流向前端服务,然后流向带有标签 v1 的前端 Pod,因为我们使用简单的 nginx 代理将请求重定向到后端服务,后端服务又将它们重定向到后端 Pod带有标签 v1。

Kiali 与 Istio 配合得很好,并提供了盒装网格渲染解决方案。 太棒了。

金丝雀部署

我们的后端已经有两个 k8s 部署,一个用于 v1,一个用于 v2。 现在我们只需要告诉 Istio 将一定比例的请求转发到 v2 即可。

第 1 步:10%

我们需要做的就是调整 VirtualService 的权重 istio.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

Kubernetes 中的金丝雀部署 #3:Istio

我们看到 10% 的请求被重定向到 v2。

第 2 步:50%

现在只需将其增加到 50% 就足够了:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
...
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 50
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 50

Kubernetes 中的金丝雀部署 #3:Istio

第 3 步:100%

现在可以认为 Canary 部署完成,所有流量都重定向到 v2:

Kubernetes 中的金丝雀部署 #3:Istio

手动测试 Canary

假设我们现在将所有请求的 2% 发送到 v10 后端。 如果我们想手动测试 v2 以确保一切按我们的预期工作怎么办?

我们可以根据HTTP headers添加特殊的匹配规则:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - headers:
        canary:
          exact: "canary-tester"
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

现在使用curl我们可以通过发送标头来强制v2请求:

Kubernetes 中的金丝雀部署 #3:Istio

没有标头的请求仍将按 1/10 比例驱动:

Kubernetes 中的金丝雀部署 #3:Istio

两个依赖版本的金丝雀

现在我们将考虑前端和后端都有 v2 版本的选项。 对于两者,我们指定 10% 的流量应流向 v2:

Kubernetes 中的金丝雀部署 #3:Istio

我们看到前端v1和v2都以1/10的比例转发后端v1和v2的流量。

如果我们需要将流量从 frontend-v2 转发到 backend-v2,因为它与 v1 不兼容怎么办? 为此,我们将为前端设置 1/10 比率,该比率通过协商控制到达后端 v2 的流量 sourceLabels :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
...
  - match:
    - sourceLabels:
        app: frontend
        version: v2
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100

结果,我们得到了我们需要的:

Kubernetes 中的金丝雀部署 #3:Istio

与手动 Canary 方法的差异

В 第一部分 我们手动执行 Canary 部署,同样使用两个 k8s 部署。 在那里,我们通过更改副本数量来控制请求的比率。 这种方法有效,但有严重的缺点。

Istio 使得无论副本数量多少都可以确定请求的比率。 例如,这意味着我们可以使用 HPA(Horizo​​ntal Pod Autoscalers),并且不需要根据 Canary 部署的当前状态进行配置。

Istio 工作得很好,与 Kiali 一起使用可以形成非常强大的组合。 我的下一个兴趣是将 Spinnaker 与 Istio 结合起来以实现自动化和金丝雀分析。

来源: habr.com

添加评论