Flux CD Flux CD

使用 Flux 配置多集群

从一个仓库管理多个集群,包含共享基础设施和每个集群各自的差异。

12 min 中级

Flux 通过在每个集群中运行一套控制器来扩展到多集群,所有这些控制器在不同路径下跟随同一个 Git 仓库。没有需要注册集群的中心枢纽。本指南展示如何为 staging 和 production 规划单个仓库的布局、bootstrap 每个集群、在应用之前先部署基础设施,以及何时改用远程集群的配置方式。

一个仓库,每个集群一个路径

Flux 遵循一条简单的规则:每个集群都针对 clusters/ 之下它自己的文件夹进行 bootstrap。服务于两个集群的仓库如下所示:

fleet-infra/
├── clusters/
│   ├── staging/
│   │   ├── flux-system/        # created by bootstrap
│   │   ├── infrastructure.yaml
│   │   └── apps.yaml
│   └── production/
│       ├── flux-system/
│       ├── infrastructure.yaml
│       └── apps.yaml
├── infrastructure/
│   ├── base/                   # shared: ingress, cert-manager, monitoring
│   ├── staging/
│   └── production/
└── apps/
    ├── base/
    ├── staging/
    └── production/

共享定义放在 base/ 文件夹中,每个环境文件夹则存放描述差异的 Kustomize overlay(参见 overlay 指南)。

为每个集群 bootstrap

依次切换你的 kubectl 上下文到每个集群,并使用不同的路径针对同一个仓库执行 bootstrap:

kubectl config use-context staging
flux bootstrap github --owner=<user> --repository=fleet-infra \
  --branch=main --path=clusters/staging --personal

kubectl config use-context production
flux bootstrap github --owner=<user> --repository=fleet-infra \
  --branch=main --path=clusters/production --personal

现在每个集群都有自己的 Flux 安装,并在 Git 中有自己的 flux-system 文件夹。之后添加第三个集群,只需再用一个新路径执行一次 bootstrap 命令。

让每个集群指向它自己的 overlay

clusters/production/apps.yaml 应用 production 的 overlay:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  dependsOn:
    - name: infrastructure
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/production
  prune: true
  wait: true

clusters/staging/apps.yaml 与之相同,只是 path: ./apps/staging。infrastructure Kustomization 以同样的方式指向 ./infrastructure/<env>,并且带有 wait: true,这样应用只有在 ingress 控制器、证书管理器等组件就绪之后才会启动。dependsOn 字段正是用来强制这一顺序的。

跨集群验证

Flux 没有中央仪表板,因此请在每个集群各自的上下文中检查:

flux get kustomizations --context staging
flux get kustomizations --context production

两者都应显示 Ready。使用 flux tree 和 flux get all -A 比较 Git 所说的已部署内容与每个集群所报告的内容。对于整个集群队列的可见性,团队通常会把 Flux 的 Prometheus 指标收集到 Grafana 中。

从 staging 升级到 production

因为两个集群读取同一个仓库,升级就是一次提交。常见流程如下:

  1. 修改 apps/staging,让 Flux 将其应用到 staging 集群。
  2. 测试并验证。
  3. 在经过审查的拉取请求中,对 apps/production 做同样的修改,或者打一个 release 标签,让 production 的 GitRepository 跟踪它(参见 overlay 指南)。

替代方案:一个控制集群,多个远程集群

你也可以不在每个集群中运行 Flux,而是在一个地方运行它,让它的 Kustomization 和 HelmRelease 应用到其他集群。在资源上将 spec.kubeConfig 设置为一个保存远程集群 kubeconfig 的 Secret:

spec:
  kubeConfig:
    secretRef:
      name: production-kubeconfig

这样可以集中控制,但同时也会把每个集群的凭据放进控制集群。这与通常的 Flux 模型不同:通常凭据永远不会离开每个集群,被攻破的集群无法触及其他集群。除非有明确的理由要集中化(比如轻量级的边缘集群),否则应优先选择每个集群各自一套 Flux 安装。如果确实走这条路,在你的平台支持的情况下,请使用云工作负载身份,而不是长期有效的 kubeconfig;并可以了解用于大规模管理集群队列的 Flux Operator。

良好的习惯

  • 不要把每个集群的 flux-system 文件夹放进共享的 overlay。它由 bootstrap 掌管。
  • 使用 dependsOn,让基础设施、CRD 和控制器先于需要它们的应用安装。
  • 为每个集群提供各自的 SOPS 密钥(参见密钥指南),这样 staging 无法解密 production 的 Secret。
  • 一次升级一个集群的 Flux,从非生产集群开始,方法是用较新的 CLI 重新运行 flux bootstrap。

热门指南