本文介绍如何在 Kubernetes 集群中结合 Flux、Flagger 和 Istio,使用 GitOps 方式实现渐进式交付,并完成金丝雀发布与自动回滚的基础实践。
GitOps 的核心思路
GitOps 是一种持续交付方法,将 Git 作为基础设施配置和应用声明的唯一事实来源。在 Kubernetes 场景下,团队不再依赖手动执行 kubectl apply、kubectl delete 或 helm install/upgrade,而是通过提交 Git 变更来驱动集群状态更新。
在这套方案中,可以使用 GitHub 托管配置仓库,并通过 Flux 持续同步仓库内容与 Kubernetes 集群状态。
什么是渐进式交付
渐进式交付是一类更安全的发布策略总称,常见形式包括金丝雀发布和 A/B Testing。它的目标是将新版本变更逐步暴露给真实流量,以更细粒度控制发布影响范围,降低生产环境上线风险。
在本文场景中,Flagger 会结合 Prometheus 指标自动执行金丝雀分析,并在指标异常时触发回滚。
环境准备
开始之前,需要具备以下条件:
- Kubernetes 1.16 或更高版本
- 集群支持 LoadBalancer
- 测试环境可使用 2 CPU、4GB 内存的 minikube
安装 Flux CLI:
brew install fluxcd/tap/flux
如需其他平台,也可以直接下载对应二进制文件。
检查集群是否满足 Flux 的前置要求:
flux check --pre
安装常用工具:
brew install jq yq
随后 Fork 并克隆配置仓库:
git clone https://github.com//gitops-istiocd gitops-istio
使用 Flux 引导集群
通过 flux bootstrap git 可以在 Kubernetes 集群中安装 Flux,并让它开始从 Git 仓库拉取配置、管理自身以及管理后续工作负载。如果集群中已经存在 Flux 组件,bootstrap 也会在需要时执行升级。
示例命令如下:
flux bootstrap git --author-email= --url=ssh://git@github.com//gitops-istio --branch=main --path=clusters/my-cluster
该命令通常需要 SSH Agent 支持。执行过程中,Flux 会生成一对 SSH 密钥,并输出公钥。要让 Flux 能够与 Git 仓库同步,需要将该公钥添加到仓库的 Deploy Keys 中,并开启写权限。
在 GitHub 中可进入 Settings > Deploy keys,点击 Add deploy key,勾选 Allow write access 后保存。
集群同步时会发生什么
当 Flux 开始访问并同步仓库后,通常会按顺序完成以下工作:
- 安装 Istio Operator
- 等待 Istio 控制平面就绪
- 安装 Flagger、Prometheus 和 Grafana
- 创建 Istio 公共网关
- 创建生产命名空间
- 创建负载测试组件 Deployment
- 创建前端服务 Deployment 与 Canary
- 创建后端服务 Deployment 与 Canary
在使用 Istio 的场景下,资源的应用顺序非常关键。凡是需要注入 Istio Sidecar 的应用 Pod,都依赖 Istio 控制平面已先行启动并可用。
在 Flux v2 中,可以通过定义对象依赖关系来控制执行顺序。例如在 clusters/my-cluster/apps.yaml 中,让应用部署依赖于 istio-system:
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1kind: Kustomizationmetadata: name: apps namespace: flux-systemspec: interval: 30m0s dependsOn: - name: istio-system sourceRef: kind: GitRepository name: flux-system path: ./apps
查看 Kustomization 同步状态:
flux get kustomizations --watch
查看 Flux 的协调日志:
flux logs --all-namespaces --follow --tail=10
Istio 的定制与升级
Istio 的安装参数可以通过 istio/system/profile.yaml 中的 IstioOperator 资源进行调整,例如:
apiVersion: install.istio.io/v1alpha1kind: IstioOperatormetadata: name: istio-default namespace: istio-systemspec: profile: demo components: pilot: k8s: resources: requests: cpu: 10m memory: 100Mi
完成配置修改并推送到 Git 后,Flux 会自动将变更应用到集群中,Istio Operator 则会根据新的声明式配置重新调整控制平面。
如果有新的 Istio 版本可用,也可以通过自动化流程生成升级变更,在测试通过后合并到主分支,再由 Flux 在集群中完成升级。
应用初始化过程
当 Flux 将配置仓库同步到集群时,会创建前端与后端应用的 Deployment、HPA 以及对应的 Canary 资源。
Flagger 会根据 Canary 定义继续生成一系列对象,包括:
- Kubernetes Deployments
- ClusterIP Services
- Istio DestinationRules
- Istio VirtualServices
这些资源共同完成应用对外暴露、流量切分以及金丝雀分析与推广。
可以使用以下命令检查 Canary 是否初始化成功:
kubectl -n prod get canaries
示例输出:
NAME STATUS WEIGHTbackend Initialized 0frontend Initialized 0
当前端主版本 frontend-primary 上线后,Flagger 会将全部流量转发到主实例,并把金丝雀工作负载缩容到 0。
访问入口网关
可以通过以下命令查询 Istio Ingress Gateway 的地址:
kubectl -n istio-system get svc istio-ingressgateway -o json | jq .status.loadBalancer.ingress
将得到的地址放入浏览器后,即可访问前端界面。
金丝雀发布机制
Flagger 会持续执行控制循环,在逐步提高新版本流量占比的同时,持续检测关键指标。如果指标保持在预设阈值内,就继续推进发布;如果指标恶化,则终止推广并回滚。
查看所有命名空间中的 Canary 状态:
kubectl get canaries --all-namespaces --watch
示例输出:
NAMESPACE NAME STATUS WEIGHTprod frontend Progressing 100prod backend Succeeded 0
基于 Istio 指标的自动回滚
Flagger 会读取 Istio 遥测指标来验证金丝雀版本是否健康。以前端应用为例,分析定义中通常会包含错误率和延迟两个检查项:
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 错误:
watch curl -b 'type=insider' http:///status/500
持续制造高延迟:
watch curl -b 'type=insider' http:///delay/1
当失败次数达到分析阈值后,Flagger 会将流量重新切回主版本,把金丝雀副本缩容到 0,并将这次发布标记为失败。
扩展能力
除了 Prometheus 之外,Flagger 还支持接入其他指标来源,例如 Datadog 和 Amazon CloudWatch,也可以通过自定义指标扩展分析逻辑。
如果需要在金丝雀分析过程中接收告警,还可以配置消息通知,将结果发送到 Slack、MS Teams、Discord 或 Rocket.Chat 等平台。
整体来看,Flux 负责持续同步 Git 声明式配置,Istio 提供流量治理能力,Flagger 承担渐进式发布与回滚控制,三者结合后可以在 Kubernetes 中建立一套稳定、可审计、自动化程度较高的 GitOps 渐进式交付流程。
