设计决策

本文档收集了有关此仓库中 Helm chart 设计的推理和决策。

尝试获取有问题的配置

由于这些 chart 的复杂性及其灵活性水平,存在一些重叠,可能会产生导致不可预测或完全无功能部署的配置。为了防止已知有问题的设置组合,我们实施了模板逻辑,旨在检测和警告用户他们的配置将不起作用。

这样复制了弃用操作,但旨在确保功能配置。

通过弃用中断更改

在这些 chart 的开发过程中,我们偶尔会进行一些需要更改现有部署属性的改进。一个示例是集中配置 MinIO 的使用,另一个示例是将外部对象存储配置从属性迁移到 secret(根据我们的偏好)。

为了防止用户意外部署这些 chart 的更新版本,其中包括对无效配置的重大更改,我们选择实施弃用通知。

这些旨在检测已重新定位、更改、替换或完全删除的属性,然后通知用户需要对配置进行哪些更改。 这可能包括通知用户查看有关如何用 secret 替换属性的文档。 这些通知将导致 Helm installupgrade 命令因解析错误而停止,并输出需要解决事项的完整列表。 我们已经注意确保用户不会陷入错误、修复、重复的循环中。

必须解决所有弃用问题,才能成功部署。 我们相信用户更愿意收到通知,而不是遇到需要调试的意外行为或完全失败。

initContainer 中的 secret 优先于环境

许多容器生态系统都具有或期望通过环境变量进行配置的能力。这个配置实践源于 The Twelve-Factor App 的概念。这极大地简化了跨多个部署环境的配置,但仍然存在通过容器环境传递连接 secret(例如密码和私钥)的安全问题。 大多数容器生态系统都提供了一种简单的方法来检查正在运行的容器的状态,通常包括环境。以 Docker 为例,任何能够与守护进程通信的进程都可以查询所有正在运行的容器的状态。这意味着,如果您有一个特权容器,例如 dind,则该容器可以检查给定节点上任何容器的环境, 并公开其中包含的所有 secret。 作为完整的 DevOps 生命周期 的一部分,dind 经常用于构建将被推送到仓库并随后部署的容器。

这就是为什么我们决定更喜欢通过 initContainers 收集敏感信息的原因。

从全局 chart 部署子 chart

此仓库的所有子 chart 都设计为通过全局 chart 部署。 每个组件仍然可以单独部署,但使用全局 chart 提供的一组通用属性。

这个决定从整体上简化了仓库的使用和维护。

gitlab/* 的模板部分应该尽可能是全局的

gitlab/* 子 chart 的所有模板部分都应尽可能成为全局或 GitLab 子 chart templates/_helpers.tpl 的一部分。 派生 chart 中的模板将保留为这些 chart 的一部分。 这减少了派生项目的维护影响。

这样做的好处是直接的:

  • 增加 DRY 行为,从而更容易维护。当单个条目就足够时,没有理由在多个子图表中重复相同的功能。
  • 减少模板命名冲突。 所有 chart 中的部分都编译在一起,因此我们将它们视为全局行为。

派生 chart

以下 chart 已在仓库中派生或重新创建。

Redis

随着 GitLab Helm chart 的 3.0 版本,我们不再派生上游 Redis chart,而是将其作为依赖。

Redis HA

Redis-HA was a chart we included in our releases prior to 3.0. It has now been removed, and replaced with upstream Redis chart which has added optional HA support.

MinIO

我们的 MinIO chart 是从上游 MinIO 改变的。

  • 利用预先存在的 Kubernetes secret,而不是从属性创建新的 secret。
  • 删除通过环境提供敏感密钥。
  • 通过 defaultBuckets 代替 defaultBucket.* 属性自动创建多个存储桶。

registry

registry chart 是从上游的 docker-registry 改变的。

  • 自动启用 chart 内 MinIO 服务的使用。
  • 自动将身份验证挂接到 GitLab 服务。

NGINX Ingress

NGINX Ingress chart 是从上游 NGINX Ingress 改变的。

  • 添加功能以允许 TCP ConfigMap 位于 chart 外部
  • 添加功能以允许基于发布名称对 Ingress 类进行模板化

整个 chart 中使用的 Kubernetes 版本

为了最大限度地支持不同的 Kubernetes 版本,请使用比当前 Kubernetes 稳定版本低一个次要版本的 kubectl。 这应该允许支持至少三个,很可能更多的 Kubernetes 次要版本。