通过结合 Linkerd
和 Flagger
来根据服务指标自动金丝雀(canary
)发布,从而降低部署风险。
Linkerd 2.10 中文手册持续修正更新中:
Linkerd
的流量拆分(traffic split
)功能允许您在服务之间动态转移流量。
这可用于实施低风险部署策略,如蓝绿(blue-green
)部署和金丝雀(canaries
)。
但简单地将流量从一个服务版本转移到下一个版本只是一个开始。
我们可以将流量拆分与
Linkerd
的自动黄金指标(golden metrics
)遥测相结合,
并根据观察到的指标推动流量决策。例如,我们可以逐渐将流量从旧部署转移到新部署,
同时持续监控其成功率。如果在任何时候成功率下降,
我们可以将流量转移回原始部署并退出发布。
理想情况下,我们的用户始终保持快乐(remain happy
),没有注意到任何事情!
在本教程中,我们将引导您了解如何将 Linkerd
与
Flagger 结合使用,
后者是一种渐进式交付工具,
可将 Linkerd
的指标和流量拆分绑定在一个控制循环中,
从而实现全自动、指标感知的金丝雀部署。
Linkerd
及其 Viz
扩展。Linkerd
指南进行操作。Flagger
的安装依赖于 kubectl
1.14 或更新版本。Linkerd
将管理实际的流量路由,
而 Flagger
会自动执行创建新 Kubernetes
资源(resources
)、
观察指标(watching metrics
)和逐步将用户发送到新版本的过程。
要将 Flagger
添加到您的集群并将其配置为与 Linkerd
一起使用,请运行:
kubectl apply -k github.com/fluxcd/flagger/kustomize/linkerd # customresourcedefinition.apiextensions.k8s.io/alertproviders.flagger.app created # customresourcedefinition.apiextensions.k8s.io/canaries.flagger.app created # customresourcedefinition.apiextensions.k8s.io/metrictemplates.flagger.app created # serviceaccount/flagger created # clusterrole.rbac.authorization.k8s.io/flagger created # clusterrolebinding.rbac.authorization.k8s.io/flagger created # deployment.apps/flagger created
此命令添加:
RBAC
授予 Flagger
修改它需要的所有资源的权限,例如部署(deployments
)和服务(services
)。Linkerd
控制平面交互的控制器。要观察直到一切正常运行,您可以使用 kubectl
:
kubectl -n linkerd rollout status deploy/flagger # Waiting for deployment "flagger" rollout to finish: 0 of 1 updated replicas are available... # deployment "flagger" successfully rolled out
该 demo
由三个组件组成:负载生成器(load generator
)、部署(deployment
)和前端(frontend
)。
部署会创建一个 pod
,该 pod
会返回一些信息,例如名称。
您可以使用响应(responses)来观察随着 Flagger
编排的增量部署。
由于需要某种活动流量才能完成操作,因此负载生成器可以更轻松地执行部署。
这些组件的拓扑结构如下所示:
要将这些组件添加到您的集群并将它们包含在 Linkerd
数据平面中,请运行:
kubectl create ns test && \ kubectl apply -f https://run.linkerd.io/flagger.yml # namespace/test created # deployment.apps/load created # configmap/frontend created # deployment.apps/frontend created # service/frontend created # deployment.apps/podinfo created # service/podinfo created
通过运行以下命令验证一切是否已成功启动:
kubectl -n test rollout status deploy podinfo # Waiting for deployment "podinfo" rollout to finish: 0 of 1 updated replicas are available... # deployment "podinfo" successfully rolled out
通过在本地转发前端服务并通过运行在本地的
http://localhost:8080 来打开检查它:
kubectl -n test port-forward svc/frontend 8080
我这里,为方便看到真实的一个 demo,直接加个 IngressRoute
。
ingress-route.yaml
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: podinfo-dashboard-route namespace: test spec: entryPoints: - websecure tls: secretName: hacker-linner-cert-tls routes: - match: Host(`podinfo.hacker-linner.com`) kind: Rule services: - name: frontend port: 8080
你可以直接访问 https://podinfo.hacker-linner.com。
流量转移发生在连接的客户端而不是服务器端。
来自网格外部的任何请求都不会被转移,并且将始终被定向到主后端。
LoadBalancer
类型的服务将表现出这种行为,因为源不是网格的一部分。
要转移外部流量,请将入口控制器添加到网格中。
在更改任何内容之前,您需要配置发布应如何在集群上推出(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 控制器正在监视这些定义(definitions),并将在集群上创建一些新的资源。
要观察这个过程,运行:
kubectl -n test get ev --watch
将创建一个名为 podinfo-primary
的新部署,
其副本数量与 podinfo
具有的副本数量相同
一旦新 Pod 准备就绪,原始部署将缩减为零。
这提供了由 Flagger 作为实现细节管理的部署,并维护您的原始配置文件和工作流。
看到以下行后,一切都已设置:
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
此时,拓扑看起来有点像:
本指南没有涉及 Flagger 提供的所有功能。
如果您有兴趣将 Canary 版本与 HPA 相结合、
处理自定义指标或进行其他类型的版本发布
(例如 A/B 测试),请务必阅读文档。
作为一个系统,Kubernetes resources 有两个主要部分:spec 和 status。
当控制器看到 spec 时,它会尽其所能使当前系统的 status 与 spec 相匹配。
通过部署,如果任何 pod 规范配置发生更改,控制器将启动 rollout。
默认情况下,部署控制器(deployment controller)将协调滚动更新(rolling
update)。
在这个例子中,Flagger 会注意到部署的规范(spec)发生了变化,
并开始编排金丝雀部署(canary rollout)。
要启动此过程,您可以通过运行以下命令将镜像更新为新版本:
kubectl -n test set image deployment/podinfo \ podinfod=quay.io/stefanprodan/podinfo:1.7.1
对 pod 规范的任何修改(例如更新环境变量或annotation)都会导致与更新 image 相同的行为。
更新时,金丝雀部署 (podinfo
) 将扩大(scaled up)。
准备就绪后,Flagger 将开始逐步更新 TrafficSplit CRD。
配置 stepWeight 为 10,每增加一次,podinfo
的权重就会增加 10。
对于每个周期,都会观察成功率,只要超过 99% 的阈值,Flagger 就会继续推出(rollout)。
要查看整个过程,请运行:
kubectl -n test get ev --watch
在发生更新时,资源和流量在较高级别将如下所示:
更新完成后,这张图会变回上一节的图。
您可以在 1.7.1
和 1.7.0
之间切换 image 标签以再次开始发布(rollout)。
canary resource 会更新当前状态和进度,你可以通过运行以下命令来查看:
watch kubectl -n test get canary
在幕后,Flagger 正在通过更新流量拆分 resource 来拆分主后端和金丝雀后端之间的流量。
要查看此配置在推出期间如何更改,请运行:
kubectl -n test get trafficsplit podinfo -o yaml
每次增加都会增加 podinfo-canary
的权重并减少 podinfo-primary
的权重。
一旦部署成功,podinfo-primary
的权重将重新设置为 100,
并且底层金丝雀部署(podinfo
)将被缩减。
随着流量从主要部署转移到金丝雀部署,Linkerd 提供了对请求目的地发生的事情的可见性。
这些指标显示后端实时接收流量并衡量成功率(success rate
)、延迟(latencies
)和吞吐量(throughput
)。
在 CLI 中,您可以通过运行以下命令来观看:
watch linkerd viz -n test stat deploy --from deploy/load
对于更直观的东西,您可以使用仪表板。
通过运行 linkerd viz dashboard
启动它,
然后查看 podinfo 流量拆分的详细信息页面。
再次访问 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
我是为少 微信:uuhells123 公众号:黑客下午茶 加我微信(互相学习交流),关注公众号(获取更多学习资料~)