Config Sync 的 Kubernetes GitOps 最佳做法
本页面的内容帮助您以此为起点,规划和设计 Kubernetes 的 CI/CD GitOps 流水线,从而充分利用 Config Sync。
GitOps 本身是组织按规模管理 Kubernetes 配置的通用最佳做法。但在构建该解决方案时,可以有多种选项。了解这些选项以及权衡这些决策的利弊有助于您避免将来重写架构。
您无需使用本页面中列出的所有最佳做法。您选择采用哪些最佳做法取决于您的独特情况。本页面旨在帮助您在设置 GitOps 架构时做出明智的决策。
使用集中式私有软件包库
使用存储公共或内部软件包(如 Helm 或 kpt
)的中央代码库可帮助团队更轻松地查找软件包。您可以使用 Artifact Registry 代码库或 Git 代码库等服务。
平台团队可以实行政策,要求应用团队只能使用中央代码库中的软件包。或者,他们可以将中央代码库用作一组经过审核的软件包。
您只能向少数工程师授予对代码库的写入权限。组织的其余部分可以授予读取权限。我们建议您实现将软件包提升到中央代码库并广播更新的流程。
下表列出了使用集中式私有软件包库的优势和缺点:
优势 |
缺点 |
|
|
创建湿代码库
使用与集群或命名空间的所需状态匹配的 YAML 输出创建代码库。使用差异比较应该可以轻松查看对湿代码库或全湿代码库的更改。最佳做法是通过查看流程(例如,在 GitHub 中,这将是拉取请求)仅更改湿代码库。
下表列出了创建湿代码库的优点和缺点:
优势 |
缺点 |
|
|
左移以验证配置
等待 Config Sync 开始同步以检查是否存在问题可能会导致不必要的 Git 提交和冗长的反馈循环。使用 kubeval 等 kpt
验证器函数,在将配置应用于集群之前,可以发现许多问题。
下表列出了在应用配置之前检查问题的优点和缺点:
优势 |
缺点 |
|
|
使用文件夹取代分支
针对配置变体使用文件夹而不是分支。对于文件夹,您可以使用 tree
命令查看变体。例如,使用分支时,您无法确定 pod 分支和 stage 分支之间的增量是即将发生的配置更改,还是 stage 和 prod 之间应有的永久性差异。
下表列出了使用文件夹取代分支的优点和缺点:
优势 |
缺点 |
|
|
尽可能减少使用 ClusterSelectors
借助 ClusterSelectors
,您可以将配置的某些部分应用于部分集群。您可以改为修改应用的资源或向集群添加标签,而不是配置 RootSync 或 RepoSync。但是,随着时间的推移,随着 ClusterSelectors
数量的增加,理解集群的最终状态可能会变得很复杂。
借助 Config Sync,您可以同时同步多个 RootSyncs
和 RepoSyncs
,这意味着您可以将相关配置添加到单独的代码库,然后将其同步到所需的集群。
下表列出了不使用 ClusterSelectors
的优点和缺点:
优势 |
缺点 |
|
|
避免使用 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 管理作业的优点和缺点:
优势 |
缺点 |
|
|
使用非结构化代码库
Config Sync 支持两种组织代码库的结构:非结构化和分层。建议使用非结构化方法,因为它可以让您以最方便的方式组织代码库。相比之下,分层代码库会强制采用特定结构。例如,CRD 必须位于特定目录中。在您需要共享配置时,这可能会导致出现问题。例如,如果一个团队发布包含 CRD 的软件包,则另一个需要使用该软件包的团队必须将 CRD 移至 cluster
目录,从而增加了流程的开销。
下表列出了使用非结构化代码库的优点和缺点:
优势 |
缺点 |
|
|
如需了解如何转换分层代码库,请参阅将分层代码库转换为非结构化代码库。
分离代码库和配置库
在单库扩容时,每个文件夹都需要一个特定的构建。处理代码的人员和处理集群配置的人员的权限和关注点通常不同。通过将代码库和配置库分开,每个库都可以拥有自己的权限和结构。
下表列出了分离代码库和配置库的优点和缺点:
优势 |
缺点 |
|
|
使用单独的库隔离更改
在单库扩容时,需要对不同文件夹拥有不同的权限。因此,分离库可以在安全性、平台和应用配置之间实现安全边界。将生产库和非生产库分开也是一个好方法。
下表列出了在单独的库中隔离更改的优点和缺点:
优势 |
缺点 |
|
|
固定软件包版本
无论是使用 Helm 还是 Git,您都应将配置软件包版本固定到一些没有明确发布就不会意外推进的对象上。
下表列出了固定软件包版本的优点和缺点:
优势 |
缺点 |
|
|
使用 Workload Identity
您可以在 GKE 集群上启用 Workload Identity,以允许 Kubernetes 工作负载以安全且可管理的方式访问 Google 服务。
下表列出了使用 Workload Identity 的优点和缺点:
优势 |
缺点 |
|
|
概要架构
概括来讲,您至少需要以下四种类型的库:
- 存储共享配置的软件包库。这也可能是存储在 Artifact Registry 中的 Helm 图表。
- 平台团队用于存储集群和命名空间的舰队级配置的平台库。
- 应用配置库。
- 应用代码库。
下图展示了这些库的布局:
下图显示了从应用代码库到应用配置库的配置流程。开发团队将应用代码和应用配置推送到库中。应用和配置的代码均存储在同一个位置,应用团队可以控制这些库。然后,应用团队可以将代码推送到某个版本中。