2. 自动化的金丝雀发布

Linkerd流量拆分功能允许您在服务之间动态转移流量。 这可用于实施低风险部署策略,如蓝绿部署金丝雀

但简单地将流量从一个服务版本转移到下一个版本只是一个开始。 我们可以将流量拆分Linkerd 的自动黄金指标遥测相结合, 并根据观察到的指标推动流量决策。例如,我们可以逐渐将流量从旧部署转移到新部署, 同时持续监控其成功率。如果在任何时候成功率下降, 我们可以将流量转移回原始部署并退出发布。 理想情况下,我们的用户始终保持快乐(remain happy),没有注意到任何事情!

在本教程中,我们将引导您了解如何将 Linkerd 与 Flagger 结合使用, 后者是一种渐进式交付工具, 可将 Linkerd 的指标和流量拆分绑定在一个控制循环中, 从而实现全自动指标感知金丝雀部署。

前提条件

  • 要使用本指南,您需要在集群上安装 Linkerd 及其 Viz 扩展。 如果您还没有这样做,请按照安装 Linkerd 指南进行操作。
  • Flagger 的安装依赖于 kubectl 1.14 或更新版本。

安装 Flagger

Linkerd 将管理实际的流量路由, 而 Flagger 会自动执行创建新 Kubernetes 资源、 观察指标逐步将用户发送到新版本的过程。 要将 Flagger 添加到您的集群并将其配置为与 Linkerd 一起使用,请运行:

kubectl apply -k github.com/fluxcd/flagger/kustomize/linkerd

此命令添加:

  • Canary CRD 可以配置发布的方式。
  • RBAC 授予 Flagger 修改它需要的所有资源的权限,例如 deploymentsservices
  • 配置为与 Linkerd 控制平面交互的控制器。

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

kubectl -n linkerd rollout status deploy/flagger

设置 demo

demo 由三个组件组成:load generatordeploymentfrontenddeployment 会创建一个 pod,该 pod 会返回一些信息,例如 name。 您可以使用响应(responses)来观察随着 Flagger 编排的增量部署。 由于需要某种活动流量才能完成操作,因此 load generator 可以更轻松地执行部署。 这些组件的拓扑结构如下所示:

Topology
Topology

要将这些组件添加到您的集群并将它们包含在 Linkerd 数据平面中,请运行:

kubectl create ns test && \
  kubectl apply -f https://run.linkerd.io/flagger.yml

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

kubectl -n test rollout status deploy podinfo

通过在本地转发 frontend 服务并通过运行以下命令在本地的 http://localhost:8080 来打开检查它:

kubectl -n test port-forward svc/frontend 8080

配置发布

在更改任何内容之前,您需要配置发布应如何在集群上推出(rolled out)。 该配置包含在 Canary 定义中。要应用于您的集群,请运行:

cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  service:
    port: 9898
  analysis:
    interval: 10s
    threshold: 5
    stepWeight: 10
    maxWeight: 100
    metrics:
    - name: request-success-rate
      thresholdRange:
        min: 99
      interval: 1m
    - name: request-duration
      thresholdRange:
        max: 500
      interval: 1m
EOF

Flagger 控制器正在监视这些定义,并将在集群上创建一些新的资源。 要观察这个过程,运行:

kubectl -n test get ev --watch

将创建一个名为 podinfo-primary 的新 deployment, 其副本数量与 podinfo 具有的副本数量相同 一旦新 Pod 准备就绪,原始部署将缩减为零。 这提供了由 Flagger 作为实现细节管理的 deployment,并维护您的原始配置文件和工作流。 看到以下行后,一切都已设置:

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

除了托管部署之外,还创建了一些服务来协调应用程序的新旧版本之间的路由流量。 这些可以使用 kubectl -n test get svc 查看,应该如下所示:

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

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

Initialized
Initialized

开始推出

作为一个系统,Kubernetes resources 有两个主要部分:specstatus。 当 controller 看到 spec 时,它会尽其所能使当前系统的 statusspec 相匹配。 通过 deployment,如果任何 pod spec 配置发生更改,controller 将启动 rollout。 默认情况下,deployment controller 将协调(滚动更新)。

在这个例子中,Flagger 会注意到 deploymentspec 发生了变化, 并开始编排 canary rollout。 要启动此过程,您可以通过运行以下命令将镜像更新为版本:

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

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

更新时,金丝雀部署 (podinfo) 将 scaled up。 准备就绪后,Flagger 将开始逐步更新 TrafficSplit CRD。 配置 stepWeight10,每增加一次,podinfo 的权重就会增加 10。 对于每个周期,都会观察成功率,只要超过 99% 的阈值,Flagger 就会继续 rollout。 要查看整个过程,请运行:

kubectl -n test get ev --watch

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

Ongoing
Ongoing

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

Resource

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

watch kubectl -n test get canary

在幕后,Flagger 正在通过更新流量拆分 resource 来拆分主后端和金丝雀后端之间的流量。 要查看此配置在 rollout 期间如何更改,请运行:

kubectl -n test get trafficsplit podinfo -o yaml

每次 increment 都会增加 podinfo-canary 的权重并减少 podinfo-primary 的权重。 一旦部署成功,podinfo-primary 的权重将重新设置为 100, 并且底层金丝雀部署(podinfo)将被缩减。

指标

随着流量从 primary deployment 转移到 canaryLinkerd 提供了对请求目的地发生的事情的可见性。 这些指标显示后端实时接收流量并衡量成功率延迟吞吐量。 在 CLI 中,您可以通过运行以下命令来观看:

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

对于更直观的东西,您可以使用仪表板。 通过运行 linkerd viz dashboard 启动它, 然后查看 podinfo 流量拆分的详细信息页面。

Dashboard
Dashboard

浏览器

再次访问 http://localhost:8080。 刷新页面将显示新版本不同标题颜色之间的切换。 或者,运行 curl http://localhost:8080 将返回一个 类似于以下内容的 JSON 响应:

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

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

清理

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

kubectl delete -k github.com/fluxcd/flagger/kustomize/linkerd && \
  kubectl delete ns test