使用 Istio+Kiali 启动和可视化 Canary 部署
本系列文章
Kubernetes 中的金丝雀部署 #1:Gitlab CI Kubernetes 中的 Canary 部署 #2:Argo 推出 - (本文)
- 使用 Jenkins-X Istio Flagger 进行金丝雀部署
金丝雀部署
我们希望您阅读
Istio
我们假设通过阅读本文,您已经了解 Istio 是什么。 如果没有,那么您可以阅读相关内容
申请测试
每个 Pod 包含两个容器:我们的应用程序和 istio-proxy。
我们将使用一个带有前端 nginx 和后端 python pod 的简单测试应用程序。 nginx pod 将简单地将每个请求重定向到后端 pod 并充当代理。 详细信息可以在以下 yaml 中找到:
自己运行测试应用程序
如果您想按照我的示例并自己使用此测试应用程序,请参阅
初始部署
当我们启动第一个 Deployment 时,我们看到应用程序的 pod 只有 2 个容器,即 Istio sidecar 刚刚实现:
我们还在命名空间中看到 Istio Gateway Loadbalancer istio-system
:
流量产生
我们将使用以下 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(详细信息见下文)。
istioctl dashboard kiali # admin:admin
Kiali 通过 Mesh 可视化当前流量
正如我们所看到的,100% 的流量流向前端服务,然后流向带有标签 v1 的前端 Pod,因为我们使用简单的 nginx 代理将请求重定向到后端服务,后端服务又将它们重定向到后端 Pod带有标签 v1。
Kiali 与 Istio 配合得很好,并提供了盒装网格渲染解决方案。 太棒了。
金丝雀部署
我们的后端已经有两个 k8s 部署,一个用于 v1,一个用于 v2。 现在我们只需要告诉 Istio 将一定比例的请求转发到 v2 即可。
第 1 步:10%
我们需要做的就是调整 VirtualService 的权重
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
我们看到 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
第 3 步:100%
现在可以认为 Canary 部署完成,所有流量都重定向到 v2:
手动测试 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请求:
没有标头的请求仍将按 1/10 比例驱动:
两个依赖版本的金丝雀
现在我们将考虑前端和后端都有 v2 版本的选项。 对于两者,我们指定 10% 的流量应流向 v2:
我们看到前端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
结果,我们得到了我们需要的:
与手动 Canary 方法的差异
В 第一部分 我们手动执行 Canary 部署,同样使用两个 k8s 部署。 在那里,我们通过更改副本数量来控制请求的比率。 这种方法有效,但有严重的缺点。
Istio 使得无论副本数量多少都可以确定请求的比率。 例如,这意味着我们可以使用 HPA(Horizontal Pod Autoscalers),并且不需要根据 Canary 部署的当前状态进行配置。
总
Istio 工作得很好,与 Kiali 一起使用可以形成非常强大的组合。 我的下一个兴趣是将 Spinnaker 与 Istio 结合起来以实现自动化和金丝雀分析。
来源: habr.com