Flux CD Flux CD

推送与拉取:Flux 如何向 Kubernetes 交付

为什么基于拉取、由 Git 驱动的交付会改变你部署、保障安全和恢复集群的方式。

8 min 初级

大多数团队开始向 Kubernetes 部署的方式都一样:CI 系统构建镜像,然后对集群运行 kubectl apply 或 helm upgrade。这在一开始行得通,直到应用和集群的数量增长。本指南解释当集群内部的代理(例如 Flux)改为从 Git 拉取期望状态时,会发生什么变化,以及随之而来的权衡。

推送模型及其吃力之处

在推送式流水线中,CI 任务是唯一接触集群的组件:

  1. 一次提交触发测试和镜像构建。
  2. 任务用新的镜像标签更新清单。
  3. 任务对集群运行 kubectl apply(或 helm upgrade)。

随着规模扩大,会出现三个问题:

  • 凭据位于集群之外。 每条流水线都需要 kubeconfig 或云凭据,并且随着应用和集群的增多而成倍增加。
  • 它只发生一次。 任务完成之后,没有任何东西再监视集群。两周前某人的一次 kubectl edit 是不可见的,直到它引发一次事故。
  • “现在部署了什么?”没有简单的答案。 你必须检查集群本身,因为流水线的最近一次运行并不是可靠的记录。

反转方向:拉取

在拉取模型中,一个运行在集群内部的代理监视 Git 仓库,将其中声明的内容与实际运行的内容进行比较,并应用差异。Flux 就是这样的代理。它由若干小型控制器组成,每个控制器只做一件事:

控制器作用
source-controller获取 Git 仓库、Helm 仓库、OCI 制品和 bucket,并让其他控制器可以使用它们
kustomize-controller从某个 source 构建并应用 Kubernetes 清单(纯 YAML 或 Kustomize overlay)
helm-controller安装、升级、测试和回滚 Helm release
notification-controller发送告警(Slack、Teams 等)并接收 webhook
image-reflector / image-automation 控制器可选。扫描容器镜像仓库,并把新的镜像标签提交回 Git
Developer ─▶ App repo ─▶ CI (test, build) ─▶ Image registry
                            │
                            └─ commits new image tag ─▶ Config repo
                                                            ▲
                                          Flux (in cluster) ┘ pulls, compares, applies
                                                │
                                                ▼
                                            Kubernetes

集群凭据永远不会离开集群,因为唯一应用变更的是运行在集群内部的代理。工程师和 CI 系统只需要 Git 的写权限。

四条 GitOps 原则

OpenGitOps 工作组用四条原则定义 GitOps。Flux 实现了所有这些原则:

  1. 声明式。 系统用 YAML 描述,而不是脚本。
  2. 有版本且不可变。 Git 是唯一的事实来源。每一次变更都是可审计、可回退的提交。
  3. 自动拉取。 获批的变更由集群获取,而不是推送给它。
  4. 持续调谐。 代理比较期望状态与实际状态,并修正漂移。

Flux 管理自身

Flux 的一个独特功能是 bootstrap。flux bootstrap 命令将 Flux 安装到集群中,并把 Flux 自己的清单提交到你的 Git 仓库,然后配置 Flux 从同一个仓库同步。从第零天起,即使是 GitOps 工具本身也是通过 Git 管理的。下一篇指南会带你走一遍。

将应用代码与配置放在不同的仓库中

通常的建议是使用两个仓库:一个放应用源代码,一个放 Kubernetes 配置(Deployment、Service、HelmRelease 等)。

配置有它自己的变更节奏。编辑一个 Service 或 ConfigMap,不应该为未改动的代码触发完整的构建与测试流水线。有了两个仓库,CI 流水线的最后一步变成”把新的镜像标签提交到配置仓库”,之后由 Flux 接手。这也清晰地划分了职责:开发者负责 CI,平台或运维团队负责交付。

Flux 为你提供了两种把新镜像标签送入配置仓库的方式:

  • 由 CI 提交。 流水线中的脚本更新 YAML 中的标签并推送。这适用于任何 CI 系统。
  • 由 Flux 提交。 可选的镜像自动化控制器监视镜像仓库,并自己把标签变更推送到 Git。参见本系列中的镜像自动化指南。

让 Git 成为唯一入口:漂移修正

Flux 按间隔进行调谐。当实时集群与 Git 不同时,Flux 会再次应用 Git 的版本,所以手动修改会被还原。这会带来一些实际影响:

  • 每一次变更都有提交、作者,通常还有经过审查的拉取请求,这为你提供了审计轨迹。
  • 权限转移到了 Git。许多人可以提交拉取请求;只有少数人可以合并。
  • 在生产环境里临时用 kubectl edit 改一下,不再是悄无声息的持久变更。

回滚与恢复变成 Git 操作

因为期望状态有版本记录,回到已知的良好状态只需 git revert,Flux 会让集群收敛到该状态。恢复同理:如果集群丢失,你只需创建新集群,针对同一个仓库和路径运行 flux bootstrap,工作负载就会从 Git 重新创建。不在 Git 中的内容,例如持久化数据或你在别处管理的 Secret,仍然需要各自的备份方案。

Flux 不能替代什么

Flux 是交付工具包,而不是构建工具。你仍然需要 CI 来测试代码、构建镜像并推送到镜像仓库。它专用于 Kubernetes,因此其他部署目标需要其他工具。而且它并非唯一的 GitOps 控制器:Argo CD 以不同的设计实现了同样的原则,本系列中的比较指南会介绍。本系列的其余部分以 Flux 为前提,并从安装它开始。完整参考请见 Flux 官方文档。

热门指南