通过结合 LinkerdFlagger 来根据服务指标自动金丝雀(canary)发布,从而降低部署风险。

Linkerd 2.10 中文手册持续修正更新中:

Linkerd 2.10 系列

Linkerd 的流量拆分(traffic split)功能允许您在服务之间动态转移流量。

这可用于实施低风险部署策略,如蓝绿(blue-green)部署和金丝雀(canaries)。

但简单地将流量从一个服务版本转移到下一个版本只是一个开始。

我们可以将流量拆分与

Linkerd 的自动黄金指标(golden metrics)遥测相结合,

并根据观察到的指标推动流量决策。例如,我们可以逐渐将流量从旧部署转移到新部署,

同时持续监控其成功率。如果在任何时候成功率下降,

我们可以将流量转移回原始部署并退出发布。

理想情况下,我们的用户始终保持快乐(remain happy),没有注意到任何事情!

在本教程中,我们将引导您了解如何将 Linkerd

Flagger 结合使用,

后者是一种渐进式交付工具,

可将 Linkerd 的指标和流量拆分绑定在一个控制循环中,

从而实现全自动、指标感知的金丝雀部署。

先决条件

  • 要使用本指南,您需要在集群上安装 Linkerd 及其 Viz 扩展。

    如果您还没有这样做,请按照安装Linkerd 指南进行操作。
  • Flagger 的安装依赖于 kubectl 1.14 或更新版本。

安装 Flagger

Linkerd 将管理实际的流量路由,

Flagger 会自动执行创建新 Kubernetes 资源(resources)、

观察指标(watching metrics)和逐步将用户发送到新版本的过程。

要将 Flagger 添加到您的集群并将其配置为与 Linkerd 一起使用,请运行:

  1. kubectl apply -k github.com/fluxcd/flagger/kustomize/linkerd
  2. # customresourcedefinition.apiextensions.k8s.io/alertproviders.flagger.app created
  3. # customresourcedefinition.apiextensions.k8s.io/canaries.flagger.app created
  4. # customresourcedefinition.apiextensions.k8s.io/metrictemplates.flagger.app created
  5. # serviceaccount/flagger created
  6. # clusterrole.rbac.authorization.k8s.io/flagger created
  7. # clusterrolebinding.rbac.authorization.k8s.io/flagger created
  8. # deployment.apps/flagger created

此命令添加:

  • Canary

    CRD

    可以配置发布的方式。
  • RBAC 授予 Flagger 修改它需要的所有资源的权限,例如部署(deployments)和服务(services)。
  • 配置为与 Linkerd 控制平面交互的控制器。

要观察直到一切正常运行,您可以使用 kubectl

  1. kubectl -n linkerd rollout status deploy/flagger
  2. # Waiting for deployment "flagger" rollout to finish: 0 of 1 updated replicas are available...
  3. # deployment "flagger" successfully rolled out

设置 demo

demo 由三个组件组成:负载生成器(load generator)、部署(deployment)和前端(frontend)。

部署会创建一个 pod,该 pod 会返回一些信息,例如名称。

您可以使用响应(responses)来观察随着 Flagger 编排的增量部署。

由于需要某种活动流量才能完成操作,因此负载生成器可以更轻松地执行部署。

这些组件的拓扑结构如下所示:

要将这些组件添加到您的集群并将它们包含在 Linkerd

数据平面中,请运行:

  1. kubectl create ns test && \
  2. kubectl apply -f https://run.linkerd.io/flagger.yml
  3. # namespace/test created
  4. # deployment.apps/load created
  5. # configmap/frontend created
  6. # deployment.apps/frontend created
  7. # service/frontend created
  8. # deployment.apps/podinfo created
  9. # service/podinfo created

通过运行以下命令验证一切是否已成功启动:

  1. kubectl -n test rollout status deploy podinfo
  2. # Waiting for deployment "podinfo" rollout to finish: 0 of 1 updated replicas are available...
  3. # deployment "podinfo" successfully rolled out

通过在本地转发前端服务并通过运行在本地的

http://localhost:8080 来打开检查它:

  1. kubectl -n test port-forward svc/frontend 8080

我这里,为方便看到真实的一个 demo,直接加个 IngressRoute

ingress-route.yaml

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: podinfo-dashboard-route
  5. namespace: test
  6. spec:
  7. entryPoints:
  8. - websecure
  9. tls:
  10. secretName: hacker-linner-cert-tls
  11. routes:
  12. - match: Host(`podinfo.hacker-linner.com`)
  13. kind: Rule
  14. services:
  15. - name: frontend
  16. port: 8080

你可以直接访问 https://podinfo.hacker-linner.com

流量转移发生在连接的客户端而不是服务器端。

来自网格外部的任何请求都不会被转移,并且将始终被定向到主后端。

LoadBalancer 类型的服务将表现出这种行为,因为源不是网格的一部分。

要转移外部流量,请将入口控制器添加到网格中。

配置发布

在更改任何内容之前,您需要配置发布应如何在集群上推出(rolled out)。

该配置包含在

Canary

定义中。要应用于您的集群,请运行:

  1. cat <<EOF | kubectl apply -f -
  2. apiVersion: flagger.app/v1beta1
  3. kind: Canary
  4. metadata:
  5. name: podinfo
  6. namespace: test
  7. spec:
  8. targetRef:
  9. apiVersion: apps/v1
  10. kind: Deployment
  11. name: podinfo
  12. service:
  13. port: 9898
  14. analysis:
  15. interval: 10s
  16. threshold: 5
  17. stepWeight: 10
  18. maxWeight: 100
  19. metrics:
  20. - name: request-success-rate
  21. thresholdRange:
  22. min: 99
  23. interval: 1m
  24. - name: request-duration
  25. thresholdRange:
  26. max: 500
  27. interval: 1m
  28. EOF

Flagger 控制器正在监视这些定义(definitions),并将在集群上创建一些新的资源。

要观察这个过程,运行:

  1. kubectl -n test get ev --watch

将创建一个名为 podinfo-primary 的新部署,

其副本数量与 podinfo 具有的副本数量相同

一旦新 Pod 准备就绪,原始部署将缩减为零。

这提供了由 Flagger 作为实现细节管理的部署,并维护您的原始配置文件和工作流。

看到以下行后,一切都已设置:

  1. 0s Normal Synced canary/podinfo Initialization done! podinfo.test

除了托管部署之外,还创建了一些服务来协调应用程序的新旧版本之间的路由流量。

这些可以使用 kubectl -n test get svc 查看,应该如下所示:

  1. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  2. frontend ClusterIP 10.7.251.33 <none> 8080/TCP 96m
  3. podinfo ClusterIP 10.7.252.86 <none> 9898/TCP 96m
  4. podinfo-canary ClusterIP 10.7.245.17 <none> 9898/TCP 23m
  5. podinfo-primary ClusterIP 10.7.249.63 <none> 9898/TCP 23m

此时,拓扑看起来有点像:

本指南没有涉及 Flagger 提供的所有功能。

如果您有兴趣将 Canary 版本与 HPA 相结合、

处理自定义指标或进行其他类型的版本发布

(例如 A/B 测试),请务必阅读文档

开始推出(rollout)

作为一个系统,Kubernetes resources 有两个主要部分:spec 和 status。

当控制器看到 spec 时,它会尽其所能使当前系统的 status 与 spec 相匹配。

通过部署,如果任何 pod 规范配置发生更改,控制器将启动 rollout。

默认情况下,部署控制器(deployment controller)将协调滚动更新(rolling

update
)。

在这个例子中,Flagger 会注意到部署的规范(spec)发生了变化,

并开始编排金丝雀部署(canary rollout)。

要启动此过程,您可以通过运行以下命令将镜像更新为新版本:

  1. kubectl -n test set image deployment/podinfo \
  2. podinfod=quay.io/stefanprodan/podinfo:1.7.1

对 pod 规范的任何修改(例如更新环境变量或annotation)都会导致与更新 image 相同的行为。

更新时,金丝雀部署 (podinfo) 将扩大(scaled up)。

准备就绪后,Flagger 将开始逐步更新 TrafficSplit CRD

配置 stepWeight 为 10,每增加一次,podinfo 的权重就会增加 10。

对于每个周期,都会观察成功率,只要超过 99% 的阈值,Flagger 就会继续推出(rollout)。

要查看整个过程,请运行:

  1. kubectl -n test get ev --watch

在发生更新时,资源和流量在较高级别将如下所示:

更新完成后,这张图会变回上一节的图。

您可以在 1.7.11.7.0 之间切换 image 标签以再次开始发布(rollout)。

Resource

canary resource 会更新当前状态和进度,你可以通过运行以下命令来查看:

  1. watch kubectl -n test get canary

在幕后,Flagger 正在通过更新流量拆分 resource 来拆分主后端和金丝雀后端之间的流量。

要查看此配置在推出期间如何更改,请运行:

  1. kubectl -n test get trafficsplit podinfo -o yaml

每次增加都会增加 podinfo-canary 的权重并减少 podinfo-primary 的权重。

一旦部署成功,podinfo-primary 的权重将重新设置为 100,

并且底层金丝雀部署(podinfo)将被缩减。

指标

随着流量从主要部署转移到金丝雀部署,Linkerd 提供了对请求目的地发生的事情的可见性。

这些指标显示后端实时接收流量并衡量成功率(success rate)、延迟(latencies)和吞吐量(throughput)。

在 CLI 中,您可以通过运行以下命令来观看:

  1. watch linkerd viz -n test stat deploy --from deploy/load

对于更直观的东西,您可以使用仪表板。

通过运行 linkerd viz dashboard 启动它,

然后查看 podinfo 流量拆分的详细信息页面。

浏览器

再次访问 http://localhost:8080

刷新页面将显示新版本和不同标题颜色之间的切换。

或者,运行 curl http://localhost:8080 将返回一个

类似于以下内容的 JSON 响应:

  1. {
  2. "hostname": "podinfo-primary-74459c7db8-lbtxf",
  3. "version": "1.7.0",
  4. "revision": "4fc593f42c7cd2e7319c83f6bfd3743c05523883",
  5. "color": "blue",
  6. "message": "greetings from podinfo v1.7.0",
  7. "goos": "linux",
  8. "goarch": "amd64",
  9. "runtime": "go1.11.2",
  10. "num_goroutine": "6",
  11. "num_cpu": "8"
  12. }

随着推出的继续,这种 response 会慢慢改变。

清理

要进行清理,请从集群中删除 Flagger 控制器并通过运行以下命令删除 test 命名空间:

  1. kubectl delete -k github.com/fluxcd/flagger/kustomize/linkerd && \
  2. kubectl delete ns test
  1. 我是为少
  2. 微信:uuhells123
  3. 公众号:黑客下午茶
  4. 加我微信(互相学习交流),关注公众号(获取更多学习资料~)

Linkerd 2.10(Step by Step)—2. 自动化的金丝雀发布的更多相关文章

  1. Linkerd 2.10(Step by Step)—4. 如何配置外部 Prometheus 实例

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  2. Linkerd 2.10(Step by Step)—使用 Kustomize 自定义 Linkerd 的配置

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  3. Linkerd 2.10(Step by Step)—多集群通信

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traef ...

  4. Linkerd 2.10(Step by Step)—将 GitOps 与 Linkerd 和 Argo CD 结合使用

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traef ...

  5. Linkerd 2.10(Step by Step)—控制平面调试端点

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  6. Linkerd 2.10(Step by Step)—配置超时

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  7. Linkerd 2.10(Step by Step)—配置重试

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  8. Linkerd 2.10(Step by Step)—配置代理并发

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  9. Linkerd 2.10(Step by Step)—3. 自动轮换控制平面 TLS &Webhook TLS 凭证

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

随机推荐

  1. node-redis基本操作

    //npm install redis var redis = require("redis"), client = redis.createClient(); client.se ...

  2. 每天一道面试题LeetCode 01 -- 两数之和

    Two Sum 两数之和 Given an array of integers, find two numbers such that they add up to a specific target ...

  3. GDOI2021 游记

    蹭了个名额去参加 \(\text{GDOI}\) \(\text{tg}\),体验了一下大佬的生活/kk (以下试题皆为 \(\text A\) 卷 DAY -1 不知道要复习什么.本来没有机会来参加 ...

  4. linux 查看运行java所在目录

    通过ps及top命令查看进程信息时,只能查到相对路径,查不到的进程的详细信息 需要查看pos_service.jar的绝对路径(在哪里目录下)  使用:ll /proc/PID Linux在启动一个进 ...

  5. 『政善治』Postman工具 — 9、在Postman中使用断言

    目录 1.Tests的介绍 2.常用SNIPPETS(片段)说明 (1)常用变量相关 (2)状态码相关 (3)响应结果断言: (4)Header : (5)响应速度: 3.示例 (1)响应码断言 (2 ...

  6. JavaWeb——MySQL基础

    内容索引 数据库的基本概念 MySQL数据库软件 安装 卸载 配置 SQL 数据库的基本概念 1. 数据库的英文单词: DataBase 简称 : DB 2. 什么数据库? * 用于存储和管理数据的仓 ...

  7. [re模块、json&pickle模块]

    [re模块.json&pickle模块] re模块 什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则 ...

  8. [bug] Navicat 连 虚拟机MySQL

    参考 https://www.cnblogs.com/brankoliu/p/10845491.html https://blog.csdn.net/qq_40087740/article/detai ...

  9. [算法] O(nlogn)和O(n^2)算法性能比较

    选择排序.插入排序.归并排序 main.cpp 1 #include <iostream> 2 #include "Student.h" 3 #include &quo ...

  10. 使用ps、top、ps_mem命令找出Linux中的最大内存消耗过程

    使用ps.top.ps_mem命令找出Linux中的最大内存消耗过程 2020-02-08 16:06:59作者:自力稿源:云网牛站 您可能已经看到Linux系统多次消耗过多的内存,如果是这种情况,那 ...