在 Kubernetes 中借助 GitOps、FluxCD 和 Istio 实现渐进式交付|Flagger

🚀 引言

如果你正在寻找一种使在 Kubernetes 上运行的应用程序的发布过程更加自动化且风险更低的方法,那么 Flagger 绝对是一个很不错的答案。

Flagger 就像是 Kubernetes 世界的一位自动化魔法师,他的任务是让你的发布过程更轻松、更安全,就像给你的应用程序穿上了一套自动化的护甲。

在这场发布的游戏中,Flagger 是你的得力助手,让你不再为发布的风险而头疼,而是享受整个过程的自动流程和安心体验。

因此,如果你希望让 Kubernetes 上的应用程序发布变得更加容易,Flagger 可能是你一直在寻找的答案。

在本篇文章中,我将向你介绍一款出色的渐进式交付工具Flagger,旨在通过诸如金丝雀部署、A/B 测试和蓝/绿部署等技术,为开发人员提供在自动化生产发布过程中的信心。

Flagger 就像是一个为开发人员量身打造的信心大师,他的任务是通过金丝雀部署、A/B 测试和蓝/绿部署等技术,让你在自动化生产发布中充满信心。

就像给开发者提供了一副放心的技能大礼包,让他们在发布的道路上畅行无阻。所以,如果你想要摆脱发布时的紧张,Flagger 可能是你一直在寻找的那个得心应手的助手。

我将围绕 Flagger 探讨其关键特性,包括金丝雀部署、灵活的流量路由、集成的 Webhooks 和 GitOps 集成,所有这些都旨在降低在生产环境引入新软件版本的风险。

Flagger 的特性就像是一份精心准备的技能菜单,其中包括金丝雀部署,让你可以小心翼翼地引入新版本;灵活的流量路由,使得你可以自如地掌控流量的走向;集成的 Webhooks,为你提供更多与其他工具协同的可能性;以及 GitOps 集成,让你在版本控制方面更加得心应手。

所有这些功能的目标都是为了降低在生产环境引入新软件版本时的风险。在这场 Flagger 的特色探秘之旅中,你将会发现让发布变得更加从容和可控的秘诀。 🔍

什么是GitOps?

GitOps是一种进行持续交付的方式,它通过将Git作为声明性基础设施和工作负载的真实来源来实现。

对于Kubernetes来说,这意味着使用git push而不是kubectl apply/deletehelm install/upgrade

🎩✨GitOps就像是一场魔法表演,通过将Git作为 '真实之源',实现声明式基础设施和工作负载的管理。

在Kubernetes的世界里,这意味着你可以用git push的方式,而不是kubectl apply/deletehelm install/upgrade来管理你的应用程序。

这就像是告别了手动的麻烦,转而享受一场自动化的表演,让你的应用程序按照你在Git中定义的规则自动展开。所以,GitOps不仅是一种方式,更是一种舒适、自动、可靠的生态体系。

在本文中,我们将使用GitHub作为配置存储库的托管平台,并使用Flux作为GitOps交付解决方案。

🎭💃这就像是为我们的 GitOps 表演选择了一副优质的舞台和一支专业的舞蹈队。

GitHub 是我们的配置存储库的家,而 Flux 就是我们在这个舞台上翩翩起舞的舞者。

通过将配置存储在 GitHub 上,我们可以充分利用其协作和版本控制的优势。

而 Flux,就像是我们的技能大师,通过不断地 '舞蹈',将我们的配置同步到 Kubernetes 集群中。

这一切就如同一场高质量的 GitOps 演出,将我们的应用程序部署和管理变得轻松愉快。

什么是渐进式交付?

渐进式交付是一种高级部署模式的总称,例如金丝雀部署、功能标志和A/B测试。

渐进式交付技术旨在通过为应用程序开发人员和SRE团队提供对爆发半径的精细控制,降低在生产环境引入新软件版本的风险。

🌞🌂这就像是一把遮阳伞,将高级部署模式如金丝雀部署、功能标志和A/B测试等技术聚合在一起。

渐进式交付的目标是通过为开发人员和SRE团队提供对发布影响范围的精细控制,减少引入新软件版本的风险。

这就如同给开发人员和SRE团队提供了一把遮阳伞,让他们在发布的阳光下更加从容自在。

在这个演示的 Demo中,将使用Flagger、Istio和Prometheus来自动进行应用程序的金丝雀发布和A/B测试。

🎭这就像是在一场技术盛宴中,Flagger是你的渐进式交付舞伴,Istio是你的演出舞台,而Prometheus则是为你照明的灯光。

通过这个强大的组合,你可以自动进行金丝雀发布和A/B测试,就像是在技术的舞台上展开一场精彩的表演

所以,让 Flagger 在Istio 的指导下,借助 Prometheus 的监控能力,为你的应用程序带来一场自动化的金丝雀之旅和A/B测试。

关于 flagger

Flagger是一款渐进式交付工具,它自动化了在Kubernetes上运行的应用程序的发布过程。

通过逐渐将流量转移到新版本,并在测量指标和运行一致性测试时,降低了在生产环境引入新软件版本的风险。

🔧Flagger使用服务网格(App Mesh、Istio、Linkerd、Kuma、Open Service Mesh)或入口控制器(Contour、Gloo、NGINX、Skipper、Traefik、APISIX)来实现多种部署策略(金丝雀发布、A/B测试、蓝/绿镜像)以进行流量路由。

在发布分析方面,Flagger可以查询Prometheus、InfluxDB、Datadog、New Relic、CloudWatch、Stackdriver或Graphite,并在警报方面使用Slack、MS Teams、Discord和Rocket。

Flagger就像是一台精密的发布控制中枢,通过多种部署策略和与不同工具的集成,使得在Kubernetes上运行的应用程序的发布变得更加智能、自动化和可靠。

Flagger可以通过Kubernetes自定义资源进行配置,并与为Kubernetes制作的任何CI/CD解决方案兼容。

由于Flagger是声明性的并对Kubernetes事件做出反应,因此它可以与Flux、JenkinsX、Carvel、Argo等工具一起在GitOps流水线中使用。

Flagger是云原生计算基金会项目,并且是Flux GitOps工具家族的一部分。

🛠️Flagger就像是一位灵活的工具演员,可以与各种CI/CD解决方案和GitOps工具如Flux、JenkinsX、Carvel、Argo等无缝合作。

作为云原生计算基金会项目,它是Flux GitOps工具家族中的一员,为Kubernetes生态系统提供了更多的自动化和灵活性。

开始部署

你需要一个支持LoadBalancer的Kubernetes集群,版本为v1.23或更新。

为了测试目的,你可以使用Minikube,并配置为具有2个CPU和4GB的内存:

ini 复制代码
minikube start --cpus='2' --memory='4g'

如果使用Minikube,请在一个单独的终端窗口/选项卡中运行以下命令,以便在整个实验过程中使用:

minikube tunnel

这会为istio-gateway服务分配一个外部IP,并允许helm install成功完成。

使用Homebrew安装jq、yq和flux CLI:

bash 复制代码
brew install jq yq fluxcd/tap/flux

验证你的集群是否满足先决条件:

sql 复制代码
flux check --pre

Fork 这个仓库并 clone 下:

bash 复制代码
git clone https://github.com/<YOUR-USERNAME>/Flagger-istio
cd Flagger-istio

集群部署:

使用 flux bootstrap 命令,你可以在Kubernetes集群上安装Flux,并配置它从一个Git仓库中进行自我管理。

如果在集群上存在Flux组件,bootstrap 命令将根据需要执行升级。

通过指定你的GitHub仓库分支URL,引导Flux:

ini 复制代码
flux bootstrap git \
  --author-email=<YOUR-EMAIL> \
  --url=ssh://git@github.com/<YOUR-USERNAME>/Flagger-istio \
  --branch=main \
  --path=clusters/my-cluster

上面的命令需要ssh-agent,如果你使用的是Windows,请参阅flux bootstrap github文档。

在引导过程中,Flux会生成一个SSH密钥并打印出公钥。

为了将你的集群状态与git同步,你需要复制公钥并在GitHub仓库上创建一个带有写入访问权限的部署密钥

在GitHub上转到 Settings > Deploy keys,点击 Add deploy key,勾选 Allow write access,粘贴Flux的公钥并点击 Add key。

当Flux访问你的仓库时,它将执行以下操作:

  • 使用Istio base、istiod和gateway Helm charts安装Istio
  • 等待Istio控制平面准备就绪
  • 安装Flagger、Prometheus和Grafana
  • 创建Istio公共网关
  • 创建prod命名空间
  • 创建负载测试器部署
  • 创建前端部署和金丝雀
  • 创建后端部署和金丝雀

在使用Istio引导集群时,控制安装顺序非常重要。为了使应用程序的Pod被注入Istio sidecar,必须在应用程序之前启动并运行Istio控制平面。

在Flux v2中,你可以通过定义对象之间的依赖关系来指定执行顺序。例如,在 clusters/my-cluster/apps.yaml 中,我们告诉Flux,应用程序的协调取决于 istio-system 的协调:

yaml 复制代码
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 30m0s
  dependsOn:
    - name: istio-system
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps

首先观看Flux安装Istio,然后观看demo:

arduino 复制代码
watch flux get kustomizations

你可以使用以下命令跟踪Flux的协调日志:

css 复制代码
flux logs --all-namespaces --follow --tail=10

列出Flux管理的所有Kubernetes资源,包括:

perl 复制代码
flux tree kustomization flux-system

Istio 定制化:

你可以使用位于istio/system/istio.yaml的Flux HelmReleases 来自定义Istio安装:

yaml 复制代码
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: istio-gateway
  namespace: istio-system
spec:
  dependsOn:
    - name: istio-base
    - name: istiod
  # source: https://github.com/istio/istio/blob/master/manifests/charts/gateway/values.yaml
  values:
    autoscaling:
      enabled: true

在修改Helm发布值后,你可以将更改推送到git,Flux将根据你的更改重新配置Istio控制平面。

你可以使用以下命令监控Helm升级:

sql 复制代码
flux -n istio-system get helmreleases --watch

要排除升级故障,你可以使用以下命令检查Helm版本:

sql 复制代码
kubectl -n istio-system describe helmrelease istio-gateway

Istio 控制平面升级:

Istio升级使用GitHub Actions和Flux实现自动化。

当有新的Istio版本可用时,update-istio GitHub Action workflow工作流将打开一个拉取请求,其中包含升级Istio所需的清单更新。

新的Istio版本会在Kubernetes Kind上通过e2e工作流进行测试,当将PR合并到主分支时,Flux将在生产集群上升级Istio。

应用部署

当Flux同步Git仓库与你的集群时,它会创建前端/后端部署、HPA和一个金丝雀对象。

Flagger使用金丝雀定义创建一系列对象:Kubernetes部署、ClusterIP服务、Istio目标规则和虚拟服务。

这些对象在网格上公开应用程序,并驱动金丝雀分析和推广。

bash 复制代码
# applied by Flux
deployment.apps/frontend
horizontalpodautoscaler.autoscaling/frontend
canary.flagger.app/frontend
# generated by Flagger
deployment.apps/frontend-primary
horizontalpodautoscaler.autoscaling/frontend-primary
service/frontend
service/frontend-canary
service/frontend-primary
destinationrule.networking.istio.io/frontend-canary
destinationrule.networking.istio.io/frontend-primary
virtualservice.networking.istio.io/frontend

检查Flagger是否已成功初始化金丝雀:

arduino 复制代码
kubectl -n prod get canaries
NAME       STATUS        WEIGHT
backend    Initialized   0
frontend   Initialized   0

frontend-primary 部署上线时,Flagger会将所有流量路由到主要Pod,并将 frontend 部署扩展为零。

使用以下命令查找Istio入口网关地址:

sql 复制代码
kubectl -n istio-system get svc istio-ingressgateway -ojson | jq .status.loadBalancer.ingress

打开浏览器并导航到入口地址,将看到前端用户界面。

Flagger实现了一个控制循环,逐渐将流量转移到金丝雀版本,同时测量关键性能指标,如HTTP请求成功率、请求平均持续时间和Pod的健康状况。

基于对关键性能指标的分析,金丝雀版本要么被推广,要么被中止,而分析结果会被发布到Slack。

金丝雀分析由以下任何对象的更改触发:

  • 部署的 PodSpec(容器镜像、命令、端口、环境变量等)
  • 作为卷挂载的ConfigMaps和Secrets,或映射到环境变量中

对于没有持续流量的工作负载,Flagger可以配置一个Webhook。当调用此Webhook时,它将为目标工作负载启动一项负载测试。金丝雀配置可以在apps/backend/canary.yaml中找到。

🕵️‍♂️这就像是在没有持续观众的小剧场上设置了一支随时可以开启的舞蹈队。

一旦调用了Webhook,就像是掀起了一场意外的表演,Flagger会立即开始为目标工作负载进行负载测试,以确保即使在低流量时期,你的应用程序也能在发布时保持优雅而稳定的表现。

从 Github 中拉取更改:

css 复制代码
git pull origin main

要触发后端应用的金丝雀部署,需要凹凸容器镜像:

ini 复制代码
yq e '.images[0].newTag="6.1.1"' -i ./apps/backend/kustomization.yaml

提交和推送更改:

sql 复制代码
git add -A && \
git commit -m "backend 6.1.1" && \
git push origin main

告诉Flux拉取更改或等待一分钟,让Flux自己检测更改:

bash 复制代码
flux reconcile source git flux-system

观看Flux使集群与最新提交保持一致:

arduino 复制代码
watch flux get kustomizations

几秒钟后,Flagger检测到部署版本已更改,并开始新的卷展栏:

sql 复制代码
$ kubectl -n prod describe canary backend
Events:
New revision detected! Scaling up backend.prod
Starting canary analysis for backend.prod
Pre-rollout check conformance-test passed
Advance backend.prod canary weight 5
...
Advance backend.prod canary weight 50
Copying backend.prod template spec to backend-primary.prod
Promotion completed! Scaling down backend.prod

在分析过程中,可以使用Grafana来监控金丝雀的进展。您可以使用端口转发访问控制面板:

bash 复制代码
kubectl -n istio-system port-forward svc/flagger-grafana 3000:80

Istio仪表板URL为:http://localhost:3000/d/flagger-istio/istio-canary?refresh=10s&orgId=1&var-namespace=prod&var-primary=backend-primary&var-canary=backend

注意,如果在金丝雀分析期间对部署应用了新的更改,Flagger将重新启动分析阶段。

A/B 测试

除了加权路由之外,Flagger还可以配置根据HTTP匹配条件将流量路由到金丝雀版本。

在A/B测试的场景中,你将使用HTTP头部或cookie来针对用户的特定部分。这对于需要会话亲和性的前端应用程序尤其有用。

👥这就像是在为你的流量定制了一套特殊的引导程序,通过HTTP头部或cookie的巧妙组合,将流量引导到金丝雀版本。

这对于那些需要保持会话亲和性的前端应用程序来说,是一种特别有效的方式。就像是在一场A/B测试中,你可以根据用户的特定特征将他们引导到你的金丝雀版本,以便更全面、更精准地评估新功能或版本的效果。

还可以通过指定HTTP匹配条件和迭代次数来启用A/B测试:

yaml 复制代码
analysis:
    # schedule interval (default 60s)
    interval: 10s
    # max number of failed metric checks before rollback
    threshold: 10
    # total number of iterations
    iterations: 12
    # canary match condition
    match:
      - headers:
          user-agent:
            regex: ".*Firefox.*"
      - headers:
          cookie:
            regex: "^(.*?;)?(type=insider)(;.*)?$"

上述配置将对使用Firefox浏览器的用户以及带有insider cookie的用户进行为期两分钟的分析。

前端配置可以在apps/frontend/canary.yaml中找到。

🔬👀这就像是在你的分析实验室中设置了一台高级仪器,通过精心配置,你可以对使用特定浏览器或携带特定cookie的用户进行为期两分钟的详细分析。

apps/frontend/canary.yaml配置文件中,就像是在你的实验室手术台上进行了微调,让你能够更加精确地观察和评估金丝雀版本的性能和用户体验。

通过更新前端容器镜像触发部署:

sql 复制代码
yq e '.images[0].newTag="6.1.1"' -i ./apps/frontend/kustomization.yaml
git add -A && \
git commit -m "frontend 6.1.1" && \
git push origin main
flux reconcile source git flux-system

Flagger检测到部署版本已更改,并开始A/B测试:

sql 复制代码
$ kubectl -n istio-system logs deploy/flagger -f | jq .msg
New revision detected! Scaling up frontend.prod
Waiting for frontend.prod rollout to finish: 0 of 1 updated replicas are available
Pre-rollout check conformance-test passed
Advance frontend.prod canary iteration 1/10
...
Advance frontend.prod canary iteration 10/10
Copying frontend.prod template spec to frontend-primary.prod
Waiting for frontend-primary.prod rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down frontend.prod

可以通过以下方式监控所有金丝雀:

r 复制代码
$ watch kubectl get canaries --all-namespaces
NAMESPACE   NAME      STATUS        WEIGHT
prod        frontend  Progressing   100
prod        backend   Succeeded     0

基于Istio指标的回滚

Flagger使用Istio遥测提供的指标来验证canary工作负载。前端应用分析定义了两个指标检查:

yaml 复制代码
metrics:
      - name: error-rate
        templateRef:
          name: error-rate
          namespace: istio-system
        thresholdRange:
          max: 1
        interval: 30s
      - name: latency
        templateRef:
          name: latency
          namespace: istio-system
        thresholdRange:
          max: 500
        interval: 30s

这是用于检查错误率和延迟的Prometheus查询位于flagger-metrics.yaml

将前端版本转储到,然后在金丝雀分析期间,您可以生成HTTP 500错误和高延迟来测试Flagger的回滚。

生成HTTP 500错误:

perl 复制代码
watch curl -b 'type=insider' http://<INGRESS-IP>/status/500

生成延迟:

perl 复制代码
watch curl -b 'type=insider' http://<INGRESS-IP>/delay/1

当失败的检查次数达到金丝雀分析阈值时,流量将被路由回主要节点,金丝雀被调整为零,并且部署被标记为失败。

sql 复制代码
$ kubectl -n istio-system logs deploy/flagger -f | jq .msg
​
New revision detected! Scaling up frontend.prod
Waiting for frontend.prod rollout to finish: 0 of 1 updated replicas are available
Pre-rollout check conformance-test passed
Advance frontend.prod canary iteration 1/10
...
Advance frontend.prod canary iteration 10/10
Copying frontend.prod template spec to frontend-primary.prod
Waiting for frontend-primary.prod rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down frontend.prod

参考资料:

我希望这篇文章能让你更好地理解如何管理应用程序机密。

感谢您的阅读!!🙌🏻📃

相关推荐
YCyjs13 小时前
K8S群集调度二
云原生·容器·kubernetes
Hoxy.R13 小时前
K8s小白入门
云原生·容器·kubernetes
景天科技苑1 天前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge1 天前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇1 天前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
昌sit!1 天前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis1 天前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
北漂IT民工_程序员_ZG1 天前
k8s集群安装(minikube)
云原生·容器·kubernetes
2301_806131362 天前
Kubernetes的基本构建块和最小可调度单元pod-0
云原生·容器·kubernetes
SilentCodeY2 天前
containerd配置私有仓库registry
容器·kubernetes·containerd·镜像·crictl