Config Sync 的 Kubernetes GitOps 最佳做法

本页面的内容帮助您以此为起点,规划和设计 Kubernetes 的 CI/CD GitOps 流水线,从而充分利用 Config Sync。

GitOps 本身是组织按规模管理 Kubernetes 配置的通用最佳做法。但在构建该解决方案时,可以有多种选项。了解这些选项以及权衡这些决策的利弊有助于您避免将来重写架构。

您无需使用本页面中列出的所有最佳做法。您选择采用哪些最佳做法取决于您的独特情况。本页面旨在帮助您在设置 GitOps 架构时做出明智的决策。

使用集中式私有软件包库

使用存储公共或内部软件包(如 Helm 或 kpt)的中央代码库可帮助团队更轻松地查找软件包。您可以使用 Artifact Registry 代码库或 Git 代码库等服务。

平台团队可以实行政策,要求应用团队只能使用中央代码库中的软件包。或者,他们可以将中央代码库用作一组经过审核的软件包。

您只能向少数工程师授予对代码库的写入权限。组织的其余部分可以授予读取权限。我们建议您实现将软件包提升到中央代码库并广播更新的流程。

下表列出了使用集中式私有软件包库的优势和缺点:

优势

缺点

  • 可以按定义的节奏注入公共软件包,这有助于避免因连接或上游停用问题而产生中断。
  • 可以查看和扫描共享软件包。
  • 可以轻松了解正在使用和支持的内容。例如,团队可以更轻松地找到存储在中央代码库中的标准 Redis 部署。
  • 可以更改上游软件包,以确保它们符合默认值、添加标签和容器映像库等内部标准。
  • 必须有人维护中央代码库。
  • 为应用团队增加了更多的流程。

创建湿代码库

使用与集群或命名空间的所需状态匹配的 YAML 输出创建代码库。使用差异比较应该可以轻松查看对湿代码库或全湿代码库的更改。最佳做法是通过查看流程(例如,在 GitHub 中,这将是拉取请求)仅更改湿代码库。

下表列出了创建湿代码库的优点和缺点:

优势

缺点

  • 可以更轻松地查看差异比较。
  • 无需处理即可查看配置的预期状态。
  • 全湿配置可能会导致重复的 YAML。

左移以验证配置

等待 Config Sync 开始同步以检查是否存在问题可能会导致不必要的 Git 提交和冗长的反馈循环。使用 kubevalkpt 验证器函数,在将配置应用于集群之前,可以发现许多问题。

下表列出了在应用配置之前检查问题的优点和缺点:

优势

缺点

  • 在更改请求中显示配置更改有助于防止错误进入代码库。
  • 减少问题在共享配置中的影响。
  • 必须向提交流程添加工具和逻辑,以帮助捕获问题。

使用文件夹取代分支

针对配置变体使用文件夹而不是分支。对于文件夹,您可以使用 tree 命令查看变体。例如,使用分支时,您无法确定 pod 分支和 stage 分支之间的增量是即将发生的配置更改,还是 stage 和 prod 之间应有的永久性差异。

下表列出了使用文件夹取代分支的优点和缺点:

优势

缺点

  • 文件夹比分支更容易浏览。
  • 使用许多 CLI 和 GUI 工具都可以对文件夹执行差异比较,而分支差异比较在 Git 提供商之外不太常见。
  • 使用文件夹可以更轻松地区分永久差异和未提升的差异。
  • 您可以在一个更改请求中向多个集群和命名空间发布更改,而分支需要向不同的分支发出多个更改请求。
  • 无法使用更改请求将配置更改提升到同一文件。

尽可能减少使用 ClusterSelectors

借助 ClusterSelectors,您可以将配置的某些部分应用于部分集群。您可以改为修改应用的资源或向集群添加标签,而不是配置 RootSync 或 RepoSync。但是,随着时间的推移,随着 ClusterSelectors 数量的增加,理解集群的最终状态可能会变得很复杂。

借助 Config Sync,您可以同时同步多个 RootSyncsRepoSyncs,这意味着您可以将相关配置添加到单独的代码库,然后将其同步到所需的集群。

下表列出了不使用 ClusterSelectors 的优点和缺点:

优势

缺点

  • 可以更轻松地将集群上即将出现的配置汇编到文件夹中,而不是在集群上做出该决定。
  • 减少了解什么将实际应用于集群的心理负担。
  • 标签是一种向集群添加特征的简洁方法,但创建新的 `RepoSync` 更为复杂。

避免使用 Config Sync 管理作业

虽然 Config Sync 可以为您应用作业,但作业并不适合 GitOps 部署,原因如下:

  • 不可变字段:许多 Job 字段是不可变的。如需更改不可变字段,必须删除并重新创建对象。但是,Config Sync 不会删除您的对象,除非您将其从来源中移除。

  • 意外运行作业:如果您将作业与 Config Sync 同步,然后该作业从集群中删除,Config Sync 会考虑这种偏差并重新创建该作业。如果您指定作业存留时间 (TTL),系统会自动删除作业,而 Config Sync 会自动重新创建作业,重启作业,直到您从可信来源中删除作业为止。这通常不是您想要的结果,因为 Config Sync 会再次运行该作业。

  • 协调问题:Config Sync 在应用对象后通常会等待对象完成协调。不过,作业开始运行时会被视为已协调。这意味着 Config Sync 不会等到作业完成后再继续应用其他对象。但是,如果 Job 之后失败,则会被视为未能协调。在某些情况下,这可能会阻止其他资源同步,并导致错误,直到您解决此问题。在其他情况下,同步可能成功,但只是协调失败。

出于这些原因,我们建议不要将作业与 Config Sync 同步。

在大多数情况下,作业和其他情景任务应由处理其生命周期管理的服务进行管理。然后,您可以使用 Config Sync(而不是作业本身)管理该服务。

下表列出了不使用 Config Sync 管理作业的优点和缺点:

优势

缺点

  • 提高 GitOps 兼容性。由于作业字段不可变,因此作业不适用于 GitOps 的声明式、版本控制的方法。
  • 减少意外后果。消除 Config Sync 自动重新创建已删除的作业(可能会导致这些作业意外运行)的风险。
  • 同步错误较少。避免可能发生的同步冲突和由失败的作业触发的错误。
  • 手动作业管理。您需要寻找其他服务来管理作业。

使用非结构化代码库

Config Sync 支持两种组织代码库的结构:非结构化和分层。建议使用非结构化方法,因为它可以让您以最方便的方式组织代码库。相比之下,分层代码库会强制采用特定结构。例如,CRD 必须位于特定目录中。在您需要共享配置时,这可能会导致出现问题。例如,如果一个团队发布包含 CRD 的软件包,则另一个需要使用该软件包的团队必须将 CRD 移至 cluster 目录,从而增加了流程的开销。

下表列出了使用非结构化代码库的优点和缺点:

优势

缺点

  • 您可以重复使用共享配置软件包,即使其中包含 CRD 或其他集群级定义也是如此。
  • 如果没有流程或准则,代码库结构可能因团队而异,因此更难以实现舰队级工具。

如需了解如何转换分层代码库,请参阅将分层代码库转换为非结构化代码库

分离代码库和配置库

在单库扩容时,每个文件夹都需要一个特定的构建。处理代码的人员和处理集群配置的人员的权限和关注点通常不同。通过将代码库和配置库分开,每个库都可以拥有自己的权限和结构。

下表列出了分离代码库和配置库的优点和缺点:

优势

缺点

  • 避免“循环”提交。例如,提交到代码库可能会触发 CI 请求,这可能会生成映像,然后需要提交代码等。
  • 您可以为处理应用代码和集群配置的人员使用不同的权限。
  • 减少应用配置的发现,因为它与应用代码不在同一库中。
  • 管理多个库可能非常耗时。

使用单独的库隔离更改

在单库扩容时,需要对不同文件夹拥有不同的权限。因此,分离库可以在安全性、平台和应用配置之间实现安全边界。将生产库和非生产库分开也是一个好方法。

下表列出了在单独的库中隔离更改的优点和缺点:

优势

缺点

  • 在拥有平台、安全和应用团队的组织中,更改的节奏和权限有所不同。
  • 权限保留在代码库级层。CODEOWNERS 文件让组织可以限制写入权限,同时仍允许读取权限。
  • Config Sync 支持每个命名空间进行多次同步,这可实现多个代码库的“混合效果”。
  • 管理多个代码库本身是一项任务。因此,如果您为每个集群创建一个新代码库,则集群的设置/清理问题现在需要包含代码库管理。

固定软件包版本

无论是使用 Helm 还是 Git,您都应将配置软件包版本固定到一些没有明确发布就不会意外推进的对象上。

下表列出了固定软件包版本的优点和缺点:

优势

缺点

  • 如果软件包版本未固定,则共享配置更新可能会产生比预期更大的影响。
  • 发布作业需要检查共享软件包的更新时间。

使用 Workload Identity

您可以在 GKE 集群上启用 Workload Identity,以允许 Kubernetes 工作负载以安全且可管理的方式访问 Google 服务。

下表列出了使用 Workload Identity 的优点和缺点:

优势

缺点

  • 降低使用密文和密码的复杂性和减少潜在问题。
  • Google Cloud 外部的服务(如 GitHub 和 GitLab)不支持 Workload Identity。

概要架构

概括来讲,您至少需要以下四种类型的库:

  1. 存储共享配置的软件包库。这也可能是存储在 Artifact Registry 中的 Helm 图表。
  2. 平台团队用于存储集群和命名空间的舰队级配置的平台库。
  3. 应用配置库。
  4. 应用代码库。

下图展示了这些库的布局:

流入应用配置库和应用代码库的软件包和平台库的建议架构。

下图显示了从应用代码库到应用配置库的配置流程。开发团队将应用代码和应用配置推送到库中。应用和配置的代码均存储在同一个位置,应用团队可以控制这些库。然后,应用团队可以将代码推送到某个版本中。

建议的应用构建,其中显示推送到构建的应用代码和应用配置。

后续步骤