互联网技术 / 互联网资讯 · 2024年1月7日

基于 Flux、Flagger、Istio 与 Kubernetes 的 GitOps 渐进式交付实践

本文介绍如何在 Kubernetes 集群中结合 Flux、Flagger 和 Istio,使用 GitOps 方式实现渐进式交付,并完成金丝雀发布与自动回滚的基础实践。

GitOps 的核心思路

GitOps 是一种持续交付方法,将 Git 作为基础设施配置和应用声明的唯一事实来源。在 Kubernetes 场景下,团队不再依赖手动执行 kubectl applykubectl deletehelm 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-istio
cd 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/v1beta1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  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/v1alpha1
kind: IstioOperator
metadata:
  name: istio-default
  namespace: istio-system
spec:
  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       WEIGHT
backend  Initialized  0
frontend 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     WEIGHT
prod      frontend Progressing 100
prod      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 渐进式交付流程。