笔记。 翻译。:GitLab 采用 Kubernetes 被认为是促进公司发展的两个主要因素之一。 然而,直到最近,GitLab.com 在线服务的基础设施还是建立在虚拟机上,大约一年前才开始向 K8s 迁移,目前还没有完成。 我们很高兴提供 GitLab SRE 工程师最近发表的一篇文章的翻译,介绍了这种情况是如何发生的以及参与该项目的工程师得出的结论。
大约一年来,我们的基础设施部门一直在将 GitLab.com 上运行的所有服务迁移到 Kubernetes。 在此期间,我们遇到的挑战不仅涉及将服务迁移到 Kubernetes,还涉及在过渡期间管理混合部署。 我们将在本文中讨论我们学到的宝贵经验教训。
从 GitLab.com 一开始,它的服务器就在云中的虚拟机上运行。 这些虚拟机由 Chef 管理并使用我们的安装
我们使用这种方法是因为体验社区普通成员在安装和配置 GitLab 副本时所经历的所有悲欢离合是极其重要的。 这种方法在一段时间内效果很好,但当 GitLab 上的项目数量超过 10 万时,我们意识到它不再满足我们扩展和部署的需求。
Kubernetes 和云原生 GitLab 的第一步
该项目创建于2017年
云原生和 Kubernetes 的推动使我们的工程师能够计划逐步过渡,在此期间我们放弃了应用程序对网络存储的一些依赖,同时继续开发新功能。 自从我们在 2019 年夏天开始计划迁移以来,许多限制已经得到解决,将 GitLab.com 迁移到 Kubernetes 的过程现在正在顺利进行!
Kubernetes 中 GitLab.com 的功能
对于 GitLab.com,我们使用单个区域 GKE 集群来处理所有应用程序流量。 为了最大限度地降低(已经很棘手的)迁移的复杂性,我们专注于不依赖本地存储或 NFS 的服务。 GitLab.com 主要使用整体 Rails 代码库,我们根据工作负载特征将流量路由到隔离到各自节点池中的不同端点。
就前端而言,这些类型分为对 Web、API、Git SSH/HTTPS 和注册表的请求。 在后端的情况下,我们根据不同的特征来拆分队列中的作业,具体取决于
所有这些 GitLab.com 服务都是使用未经修改的 GitLab Helm 图表进行配置的。 配置是在子图中进行的,随着我们逐步将服务迁移到集群中,可以选择性地启用子图。 尽管我们决定不在迁移中包含一些有状态服务,例如 Redis、Postgres、GitLab Pages 和 Gitaly,但使用 Kubernetes 使我们能够从根本上减少 Chef 当前管理的虚拟机数量。
Kubernetes 配置可见性和管理
所有设置均由 GitLab 本身管理。 为此,使用了三个基于 Terraform 和 Helm 的配置项目。 我们尝试尽可能使用 GitLab 本身来运行 GitLab,但对于操作任务,我们有单独的 GitLab 安装。 这是为了确保您在执行 GitLab.com 部署和更新时不依赖于 GitLab.com 的可用性。
尽管我们的 Kubernetes 集群管道在单独的 GitLab 安装上运行,但代码存储库的镜像可在以下地址公开获得:
-
k8s-工作负载/gitlab-com — GitLab Helm 图表的 GitLab.com 配置框架; -
k8s-工作负载/gitlab-helmfiles - 包含与 GitLab 应用程序不直接关联的服务的配置。 其中包括日志记录和集群监控的配置,以及 PlantUML 等集成工具; -
Gitlab-com-基础设施 — Kubernetes 和旧 VM 基础设施的 Terraform 配置。 您可以在此处配置运行集群所需的所有资源,包括集群本身、节点池、服务帐户和 IP 地址预留。
进行更改时会显示公共视图。
对于 SRE,该链接会导致 GitLab 安装中的详细差异,该安装用于生产且访问受到限制。 这使得员工和社区无需访问运营项目(仅对 SRE 开放)即可查看建议的配置更改。 通过将代码的公共 GitLab 实例与 CI 管道的私有实例相结合,我们维护了单一工作流程,同时确保配置更新独立于 GitLab.com。
我们在迁移过程中发现了什么
在迁移过程中,我们获得了应用于 Kubernetes 中新迁移和部署的经验。
1. 可用区之间的流量导致成本增加
GitLab.com 上 Git 存储库群的每日出口统计信息(每天字节数)
谷歌将其网络划分为多个区域。 这些又被划分为可访问区域 (AZ)。 Git托管与大量数据相关,因此控制网络出口对我们来说很重要。 对于内部流量,只有在同一可用区域内,出口才是免费的。 截至撰写本文时,我们在一个典型工作日中提供大约 100 TB 的数据(这仅适用于 Git 存储库)。 在基于 VM 的旧拓扑中,驻留在同一虚拟机中的服务现在在不同的 Kubernetes Pod 中运行。 这意味着之前位于虚拟机本地的一些流量可能会传输到可用区域之外。
区域 GKE 集群允许您跨越多个可用区以实现冗余。 我们正在考虑可能性
2. 限制、资源请求和扩展
在registry.gitlab.com 上处理生产流量的副本数量。 世界标准时间 (UTC) 左右的流量高峰期为 15:00。
我们的迁移故事始于 2019 年 XNUMX 月,当时我们将第一个服务 GitLab 容器注册表迁移到 Kubernetes。 这种关键任务、高流量的服务是第一次迁移的不错选择,因为它是一个无状态应用程序,几乎没有外部依赖项。 我们遇到的第一个问题是由于节点内存不足而导致大量 pod 被驱逐。 因此,我们必须更改请求和限制。
人们发现,在内存消耗随时间增加的应用程序的情况下,低请求值(为每个 Pod 保留内存)加上“慷慨”的使用硬限制会导致饱和 (饱和) 节点和高水平的驱逐。 为了解决这个问题,
3. 指标和日志
基础设施部门重点关注延迟、错误率和已安装的饱和度
在过去的一年里,基础设施部门的关键事件之一是监控和与 SLO 合作的改进。 SLO 使我们能够为迁移过程中密切监控的各个服务设定目标。 但即使可观察性得到提高,也并不总是能够使用指标和警报立即发现问题。 例如,通过关注延迟和错误率,我们并没有完全涵盖正在迁移的服务的所有用例。
在将一些工作负载迁移到集群后几乎立即发现了这个问题。 当我们必须检查请求数量很少但具有非常具体的配置依赖性的函数时,它变得尤其尖锐。 迁移的主要教训之一是不仅需要在监控时考虑指标,还需要考虑日志和“长尾” (这是关于
在旧的虚拟机基础设施和新的基于 Kubernetes 的基础设施上并行服务相同的请求提出了独特的挑战。 与直接迁移不同 (将应用程序“按原样”快速转移到新的基础设施;可以阅读更多详细信息,例如,
4. 将流量切换到新集群
对于 GitLab.com,部分服务器专用于
在迁移的情况下,这意味着对内部项目的请求首先发送到 Kubernetes,然后我们通过 HAProxy 改变后端的权重来逐渐将其余流量切换到集群。 在从虚拟机迁移到 Kubernetes 的过程中,很明显,有一种简单的方法可以在新旧基础设施之间重定向流量,从而使旧基础设施在迁移后的最初几天内做好回滚的准备。
5. Pod 的储备容量及其使用
几乎立即就发现了以下问题:Registry 服务的 pod 启动很快,但启动 Sidekiq 的 pod 需要花费
在这个案例中,我们得到的教训是,虽然 Kubernetes 的 Horizontal Pod Autoscaler (HPA) 可以很好地处理流量增长,但考虑工作负载的特征并向 Pod 分配备用容量(特别是当需求分布不均匀时)也很重要。 在我们的例子中,作业突然激增,导致快速扩展,从而导致 CPU 资源在我们有时间扩展节点池之前就饱和。
总是有一种诱惑,即从集群中挤出尽可能多的资源,但是,由于最初遇到了性能问题,我们现在从慷慨的 pod 预算开始,然后减少预算,密切关注 SLO。 Sidekiq 服务的 pod 启动速度显着加快,现在平均需要约 40 秒。
结论
迁移每个服务后,我们对在生产中使用 Kubernetes 的好处感到高兴:更快、更安全的应用程序部署、扩展和更高效的资源分配。 此外,迁移的优势不仅仅限于 GitLab.com 服务。 官方 Helm 图表的每一项改进都会让用户受益。
我希望您喜欢我们的 Kubernetes 迁移冒险故事。 我们继续将所有新服务迁移到集群。 更多信息可在以下出版物中找到:
译者PS
另请阅读我们的博客:
- «
Kubernetes 投入生产 3 年:这是我们的理解 “; - «
使用 Kubernetes 时的 10 个常见错误 “; - «
Kubernetes 在生产中的成功案例。 第 3 部分:GitHub “; - «
Tinder 过渡到 Kubernetes “。
来源: habr.com