当 Kubernetes 集群里的应用从几个涨到几十个,靠 kubectl apply 手工发布迟早会翻车。Flux CD 是一套基于 GitOps 理念的持续部署工具:把 Git 仓库当成集群状态的「唯一真相源」,每一个 Deployment、每一个 ConfigMap 都由控制器自动从 Git 拉取并调和(reconcile)。本文用一套可复制的最小实践,带你从零把 Flux CD 在生产集群跑起来。
一、为什么需要 GitOps
传统 CI/CD 的末端往往是「构建完镜像 → 推到集群」,发布动作由人触发,集群状态与代码仓库很容易发生漂移。GitOps 的反转在于:Git 是唯一可信源,集群只是 Git 状态的镜像。任何变更都必须先提交到 Git,Flux CD 持续比对实际状态与期望状态,发现偏差就自动纠正。
同样走声明式交付,ArgoCD GitOps 实战 与 Flux CD 是最常被拿来比较的两套方案,核心差异如下:
| 维度 | Flux CD | ArgoCD |
|---|---|---|
| 架构形态 | 多 Controller 组合,无中心 UI | 单体应用 + 强大 Web UI |
| 配置方式 | 纯 YAML,Git 即配置 | YAML + 可选 UI 操作 |
| 镜像自动更新 | 内置 Image Automation | 需配合 Image Updater |
| 学习曲线 | 偏 CLI,概念分散 | UI 直观,上手快 |
| 适用团队 | 偏好「全 Git 驱动、自动 PR」 | 需要可视化审计与人工审批 |
二、Flux CD 核心架构
Flux CD 由一组独立运行的 Controller 组成,各管一摊,彼此通过 CRD 协作:
- Source Controller:对接 Git 仓库、Helm 仓库、OCI 制品,产出可被调和的「源」。
- Kustomize Controller:消费 Kustomize 目录,把资源配置应用到集群。
- Helm Controller:通过
HelmRelease管理 Helm Chart 的部署与升级。 - Image Automation Controller:监听镜像仓库,自动更新 Git 里的镜像 tag。
- Notification Controller:把调和结果、健康状态推送到 Slack / Webhook。
三、环境准备
你需要一个可用的 K8s 集群(本地可用 k3s 实战 快速起一个)、一个 GitHub 账号,以及本地安装好 kubectl 与 flux CLI。Flux CD 要求集群版本 ≥ 1.28。
# 校验环境是否满足 Flux 安装前置条件
flux check --pre
# 安装 flux CLI(macOS 示例)
brew install fluxcd/tap/flux
四、用 bootstrap 把集群交给 Git
flux bootstrap 是一步到位的初始化:它会在集群里创建 flux-system 命名空间与所有 Controller,同时把一份最小配置提交到你指定的 Git 仓库,之后这份仓库就成为集群的真相源。
export GITHUB_TOKEN=xxxx
flux bootstrap github \
--owner=your-org \
--repository=cluster-gitops \
--branch=main \
--path=./clusters/production
执行后,Git 仓库会多出 clusters/production/flux-system 目录;以后你在 path 下新增任何 Kustomize 或 Helm 配置,Flux 都会自动调和。推荐用如下目录结构组织:
clusters/production/
├── flux-system/ # bootstrap 自动生成
├── apps/
│ ├── web.yaml # Kustomization 指向 web 应用
│ └── redis.yaml
└── infrastructure/
└── ingress.yaml # Traefik 等基础组件
五、第一个应用:用 Kustomization 部署
先在 Git 里定义「源」与「调和对象」。下面两段 YAML 放在 apps/web.yaml:
# 1) 声明 Git 源
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: web-app
namespace: flux-system
spec:
interval: 1m
url: https://github.com/your-org/web-app
ref:
branch: main
---
# 2) 声明 Kustomization,把仓库内容应用到集群
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: web-app
namespace: flux-system
spec:
interval: 5m
path: "./deploy/overlays/production"
sourceRef:
kind: GitRepository
name: web-app
prune: true # 删除 Git 中已移除的资源
wait: true # 等待健康后再标记成功
prune: true 保证 Git 里删掉的配置,集群也会跟着删;wait: true 让 Flux 等待 Pod 进入 Ready 再判定成功。镜像构建应交给 GitHub Actions 流水线:CI 负责构建并推送镜像,Flux CD 负责把新镜像部署到集群,二者职责清晰、互不越界。
六、用 HelmRelease 管理 Helm 应用
对已有 Helm Chart 的组件,不必手写 Kustomize,直接用 HelmRelease:
# 声明 Helm 仓库源
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: bitnami
namespace: flux-system
spec:
interval: 1h
url: https://charts.bitnami.com/bitnami
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: redis
namespace: redis
spec:
interval: 30m
chart:
spec:
chart: redis
version: "18.x"
sourceRef:
kind: HelmRepository
name: bitnami
interval: 1h
values:
auth:
enabled: false
master:
persistence:
size: 8Gi
Helm Controller 会按 interval 定时比对 Chart 版本与 values,发现新版或配置变更就自动升级,同时保留 Helm 的回滚能力,无需人工介入。
七、镜像自动更新:提交 PR 而不是改集群
GitOps 的精髓是「只改 Git」。配合 Image Automation Controller,新镜像推送到仓库后,Flux 会自动向 Git 提交一个把镜像 tag 改掉的提交,再由调和环节部署,全程不碰 kubectl。
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: web-app
namespace: flux-system
spec:
imageRepositoryRef:
name: web-app
policy:
semver:
range: "1.x" # 只允许 1.x 的递增
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: web-app
namespace: flux-system
spec:
interval: 5m
git:
checkout:
ref:
branch: main
update:
path: ./clusters/production
strategy: Setters
八、密钥、多环境与可观测性
Git 里不该放明文 Secret。可以用 External Secrets Operator 把云厂商密钥同步进集群,Flux 只负责引用 Secret 名,敏感值始终留在密钥管理系统里。
多环境用目录隔离即可:clusters/staging 与 clusters/production 各 bootstrap 一次,分别对应两套集群或同集群不同命名空间。基础网络层可交给 Cilium 做 Zero-Trust,入口流量用 Traefik 暴露;节点弹性不足时,Karpenter 能按需扩缩节点。
调和状态要看得见。把 Flux 的告警接到 Prometheus + Grafana,一旦某个 Kustomization 长时间未 Ready,立刻在仪表盘与 IM 里亮红灯。
九、生产落地检查清单
| 检查项 | 建议做法 |
|---|---|
| 仓库权限 | bootstrap 用的部署密钥仅授予目标仓库,遵循最小权限 |
| 目录隔离 | staging / production 分目录或分仓库,互不影响 |
| prune & wait | 均开启,保证 Git 删除即集群删除、部署可等待健康 |
| 镜像策略 | ImagePolicy 锁定 semver 范围,避免误升大版本 |
| 密钥管理 | 用 External Secrets Operator,禁止明文入库 |
| 告警 | 接 Prometheus/Grafana + IM 通知,调和失败可感知 |
| 备份 | 定期备份 Git 仓库与 etcd,灾难可重建 |
十、常见误区与排障
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 资源一直 Unknown/NotReady | 仓库地址或 token 错、网络不通 | flux get sources git 看 Message |
| 改了 Git 集群没变 | interval 未到 / 调和被暂停 | flux reconcile kustomization <name> --with-source |
| HelmRelease 卡住 | Chart 版本不存在或 values 不合法 | 看 flux get hr <name> 的 Conditions |
| 自动更新不提交 | ImagePolicy 范围无匹配 / 无写库权限 | 检查 policy.range 与部署密钥写权限 |
| 误删生产资源 | prune 误伤 | 先 staging 验证,配合 Git 历史回滚 |
十一、进阶方向:多集群与渐进式交付
当集群不止一个,可以用 Flux 的 Kustomization 通过 kubeConfigRef 指向其他集群的 kubeconfig(建议由 External Secrets Operator 注入),实现「一个 Git 仓库编排多套环境」。更进一步的渐进式交付,可以叠加 Flagger:它监听 Flux 部署的新版本,自动做金丝雀分析(基于 Prometheus 指标),指标达标才全量,不达标自动回滚——把发布风险交给自动化判断,而不是赌运维手速。
另一个常见组合是「CI 不动、CD 交给 Flux」。CI 阶段只负责编译、测试、推送带唯一 tag 的镜像;Flux 侧的 ImagePolicy 监听到新 tag 后,自动把 Git 里的镜像引用改成新版本并提交。这样开发者的提交记录里看不到部署噪音,而集群状态始终能在 Git 里一键审计、随时回滚到任意历史提交。
十二、哪些场景暂时不适合 GitOps
GitOps 不是银弹。对需要秒级弹性伸缩的临时批处理作业、或强依赖外部工单审批的金融核心链路,纯 Git 驱动的自动调和反而会增加摩擦与等待。这类场景更稳妥的做法是保留人工触发入口,或用 ArgoCD 的 Web UI 做「同步前人工确认」。先想清楚变更频率与审计要求,再决定是否把控制权完全交给 Git。
小结
Flux CD 把「发布」这个动作从一次人工操作,变成了一条由 Git 驱动、自动调和、可回溯的流水线。它和 ArgoCD 的思路一致,但更偏向「控制器组合 + Git 提交自动化」的轻量哲学。当你管理的不再是三五个工作负载,而是跨多环境、多集群的一整片基础设施时,GitOps 会从「可选项」变成「必选项」。




