4. Source Controller 详解:GitRepository 与 OCIRepository CRD、认证方式与轮询策略

Source Controller 是 Flux 控制平面中负责拉取、校验和缓存制品(Artifact)的核心组件。它通过两种自定义资源(CRD)——GitRepository 和 OCIRepository——来声明式地定义制品来源,并内置了多种认证机制与自动拉取策略。本章将深入剖析这两个 CRD 的字段结构、认证配置以及轮询调度原理。

4.1 GitRepository CRD:声明式 Git 仓库源

GitRepository 用于从 Git 仓库(支持 GitHub、GitLab、Bitbucket、自建 Git 等)拉取代码或配置。其核心字段如下:

字段路径 类型 说明
spec.url string Git 仓库地址,支持 https://、ssh://、git@ 格式
spec.ref object 分支、标签、提交 SHA 或 SemVer 范围
spec.secretRef object 引用包含 SSH 密钥或 HTTPS 凭据的 Kubernetes Secret
spec.interval duration 轮询间隔,例如 1m、5m
spec.timeout duration 单次拉取超时时间,默认 60s
spec.ignore string 基于 .gitignore 语法的路径排除规则
status.artifact object 拉取成功后生成的制品元数据(URL、Digest、LastUpdateTime)
关键行为:Source Controller 每次轮询成功后,会将仓库内容打包为 tar.gz 制品,并存储在内部缓存中。KustomizeController 或 HelmController 通过 status.artifact 的 URL 直接引用该制品,避免重复拉取。

4.1.1 GitRepository 认证方式

GitRepository 支持三种主流认证方式,配置均通过 spec.secretRef 指向的 Kubernetes Secret 实现:

  • SSH 密钥认证:Secret 中必须包含 identity(私钥)和 known_hosts(可选,用于主机验证)字段。适用于私有仓库或企业 Git 服务器。
  • HTTPS + 认证:Secret 中包含 username 和 password 字段。对于 GitHub/GitLab,password 通常填写 Personal Access 。
  • HTTPS 无认证:公开仓库无需配置 secretRef,直接使用 https:// 地址即可。
最佳实践:生产环境推荐使用 SSH 密钥或 认证。避免在 Git URL 中直接嵌入密码,始终通过 Secret 引用。

4.2 OCIRepository CRD:容器镜像仓库作为配置源

OCIRepository 是 Flux v2 引入的新 CRD,允许将 OCI 制品(如 Helm Chart、Kubernetes 清单、策略文件)直接存储在容器镜像仓库中。其核心字段如下:

字段路径 类型 说明
spec.url string OCI 仓库地址,格式 oci://registry.example.com/repo:tag
spec.ref object 支持 tag、semver、digest 三种引用方式
spec.secretRef object 引用包含 registry 凭据的 Secret(dockerconfigjson 类型)
spec.interval duration 轮询间隔
spec.layerSelector object 指定从 OCI 制品的哪个层(layer)中提取配置,支持 mediaType 过滤
spec.verify object Cosign 签名验证配置,确保制品完整性
注意:OCIRepository 要求容器镜像仓库支持 OCI 制品规范(OCI Distribution Spec v1.0+)。主流仓库如 Docker Hub、GHCR、Harbor、AWS ECR 均已支持。

4.2.1 OCIRepository 认证方式

OCIRepository 的认证通过 spec.secretRef 引用 kubernetes.io/dockerconfigjson 类型的 Secret 实现。该 Secret 包含 .dockerconfigjson 字段,内容为 Docker 客户端认证格式的 JSON 字符串。

# 创建 OCI 仓库认证 Secret 示例
kubectl create secret docker-registry oci-auth \
  --docker-server=registry.example.com \
  --docker-username=myuser \
  --docker-password=mytoken \
  --namespace=flux-system

对于公有云托管仓库(如 AWS ECR、Azure ACR、GCR),通常使用 IAM 角色或服务账户进行认证,此时可以省略 secretRef,由 Source Controller 通过节点角色自动获取临时凭据。

4.3 自动拉取与轮询策略

Source Controller 采用 基于间隔的轮询(Interval-based Polling) 策略,而非事件驱动。每个 Source CR(GitRepository 或 OCIRepository)独立维护一个定时器,到期后触发拉取操作。

Source Controller 轮询与制品缓存流程 定时器 (Interval) 轮询触发 拉取制品 制品缓存 (tar.gz) 消费者 (Kustomize/Helm) 更新 Status 说明: • 轮询间隔由 spec.interval 定义,最小建议 30s,避免对 Git/OCI 仓库造成压力。 • 拉取成功后,Source Controller 会更新 status.artifact,并通知所有关联的消费者。 • 若拉取失败,Source Controller 会记录错误到 status.conditions,并等待下一个轮询周期重试。

4.3.1 轮询策略关键参数

参数 默认值 说明
spec.interval 1m 轮询间隔,支持 30s、5m、1h 等格式
spec.timeout 60s 单次拉取超时,超时后标记为失败,等待下一周期
spec.recurseSubmodules false GitRepository 专用,是否递归拉取子模块
status.observedGeneration — 记录最后一次成功同步的 generation,用于判断是否发生变更

4.3.2 轮询与事件驱动的对比

Flux 选择轮询而非 Webhook 事件驱动,主要基于以下考虑:

  • 声明式一致性:轮询确保集群状态与源仓库最终一致,不受网络抖动或 Webhook 丢失影响。
  • 简化运维:无需暴露集群 Webhook 端点,无需配置防火墙或反向代理。
  • 可预测性:轮询间隔固定,便于容量规划和审计。
优化建议:对于需要快速响应的场景,可以配合 Flux 的 Image Automation 组件或外部 Webhook 转发器(如 Flux Webhook Receiver)来缩短延迟。但核心同步仍以轮询为兜底机制。

4.4 GitRepository 与 OCIRepository 选型对比

维度 GitRepository OCIRepository
源类型 Git 仓库(代码、配置) OCI 制品(Chart、清单、策略)
认证方式 SSH 密钥 / HTTPS Docker Registry 凭据 / IAM
制品格式 tar.gz(仓库快照) OCI 层(Layer)
签名验证 不支持原生签名 支持 Cosign 签名验证
适用场景 GitOps 配置仓库、Kustomize 清单 Helm Chart 分发、策略即代码
拉取性能 依赖 Git 协议,大仓库较慢 基于 OCI 分发,支持镜像加速
选型建议:如果团队已深度使用 Git 作为单一事实来源,且配置量不大,优先选择 GitRepository。如果涉及 Helm Chart 分发、需要制品签名验证或追求更快的拉取速度,OCIRepository 是更优选择。两者可以混合使用,互不冲突。