为什么要使用 Kubernetes?聚焦API,而非服务器

在这篇博客中,我将讨论如何通过专注于 Kubernetes 的 API 来释放其潜力,同时尽量避免可能遇到的复杂性。了解如何以及是否可以让 Kubernetes 为您发挥作用。

译自 Why Kubernetes? Focus on the API, not the servers。作者 Tibo Beijen 。

随着我们从 2023 年进入 2024 年,现在是进行反思的好时机。无可争议,去年最大的话题之一是 AI 的兴起。但是离我的日常工作更近一些,有一些事件特别引人注目:

  1. 亚马逊 Prime 从无服务器微服务转向“单体”的博文。随后有大量的温吞吞的点击诱导文和“我的技术栈比你的好”类型的讨论。从 Jeremy Daly 的这篇文章开始,挑选关于这个主题的一些必读和避免的文章。
  2. 社交媒体就是社交媒体: 关于几乎所有技术主题的辩论,包括“Kubernetes 单枪匹马让我们的行业倒退了十年”,正如 Kelsey Hightower 所说。或者 37signals 退云并避开 Kubernetes 的举动
  3. Datadog 的宕机。由多种因素共同导致,可以用关键词概括: Kubernetes、Cilium、eBPF、Systemd、OS 更新。Gergely Orosz(The Pragmatic Engineer)对此进行了很好的解释

使用并喜欢Kubernetes,阅读所有上述内容,很容易会反思这个问题“我卷入了什么?”。或者在更广泛的意义上: “我们这个行业卷入了什么?”。

在我看来,讨论Kubernetes的价值和成本不应仅仅局限于“服务器与无服务器”或“简单与复杂”。而应该关注在什么时候(假设这一点确实存在),Kubernetes的好处开始超过其带来的挑战。

因此,让我们关注Kubernetes现状,它的优势,并寻找避免其复杂性的方法。

声明: 出现一些供应商的名称或标志。我不为任何厂商效力,也不应将其解释为建议优于可能存在的类似解决方案。

多功能性

Kubernetes无所不在: 它可以促进各种工作负载在各种环境中运行:

Kubernetes无所不在

如上图所示,可以在从大型云到小型云,再到内部数据中心甚至边缘计算的各种环境中运行Kubernetes。

关注工作负载类型,Kubernetes可以做很多事情。但也存在Kubernetes可能不特别适合的工作负载类型。在单体方面,可以想象(遗留)的大型机。或难以容器化的基于VM的应用程序。

大型云平台提供大量托管服务,包括数据库、内存存储、消息组件以及专注于AI/ML和大数据的服务。对于这些服务,你_可以_在Kubernetes内运行与云和平台无关的原生云替代方案。但这需要更多前期工作,潜在收益因情况而异。

然后在微的另一端,大型云平台提供“无服务器”: 函数即服务,通常与 API 网关等组件紧密集成,并具有用于事件驱动架构的构建块。例如,可以决定在 Kubernetes 中运行这些函数,使用 Knative。但这需要先设置和支持这些组件,而在这方面,云更容易上手。另外,无服务器以快速扩展和缩放到零作为区别特征。

Kubernetes 可以为其用户提供标准化的工作方式(大致是:将 YAML 放入集群),为平台团队提供统一的方式来支持工程团队(大致是:帮助拟定适当的 YAML 并帮助将 YAML 放入集群)。它可以通过利用和集成大型云平台的托管服务来做到这一点,而不是试图替换它们全部。

关于这种标准化我将在后面详细说明。

为什么以及如何

作为一个组织,重要的是要很好地理解为什么选择一个(技术)策略以及期望是什么。

如本博客文章的标题所示,明确回答“我们为什么使用 Kubernetes?”这个问题很重要。但如果“Kubernetes”是组织面临的各种挑战的逻辑答案,那么这可能会更好。例如:

  • 我们如何有效运行大量容器化的工作负载?
  • 我们如何让一个云专家团队通过提供黄金路径和防护栏来赋能许多工程团队?
  • 我们如何以与我们已经有的软件交付流程保持一致的方式在边缘运行应用程序?
  • 我们如何允许工程团队在我们内部的数据中心部署应用程序?
  • 我们如何在为我们重要的地方提供灵活性的同时,标准化我们的工作方式?
  • 我们如何确保我们投资的知识和工具尽可能广泛适用(例如不限于单一云供应商)?

是的,最后一点听起来有“多云”和“供应商锁定”的意思。明确一点: 仅仅因为其他地方计算更便宜就切换云,几乎从不划算。仅仅为了“多云”而使用多云的公共部分,也几乎从不划算。供应商锁定无处不在,不仅仅是在选择云时。但是,从多年的时间跨度来看,组织可能会看到专注于跨供应商边界适用的技术的优势。

建造摩天大楼

采用 Kubernetes 的过程中,在 Kubernetes 开始产生价值之前,需要设置很多东西。我们正在建造一个平台。让我们用物理世界建筑的类比来说明:

建立平台

在底部,我们找到了基础。它之所以在那里,是因为它需要在那里,但没有人单纯为了有个基础而建立基础。在 Kubernetes 的术语中,基础包括网络(CNI)、存储(CSI)、容器运行时(CRI)、虚拟机或裸机服务器以及操作系统等组件。

接下来是地下室。与基础类似,这不是最终目标(除非你在建地下停车场且上面是一个公园)。它容纳了你通常认为理所当然的东西。设备、维护间、管道等等。在 Kubernetes 中,这对应于在上线之前需要的一些基本要求: 可观测性和安全性。证书管理。可能是一个策略引擎。

最后,我们进入地面以上。这就是我们要建造的: 有目的的建筑!在 Kubernetes 的术语中,这些显然是被部署的应用程序。但也包括增强我们平台能力的组件。例如 ArgoCD/Flux(使用 GitOps 进行高效部署)、Argo Workflows(工作流引擎)和 KEDA(更智能的扩展)。

现在,对于每个组件,可以争论它是基础、地下室还是建筑。也许 ArgoCD 和 KEDA 更像地下室而不是建筑。可能 CSI 也是地下室,而不是基础,因为你可以相对容易地添加或删除存储类。

重要的是,从地下向地面以上,我们可以观察到组件:

  • 变得越来越明显
  • 一般来说随着时间的推移变得更容易适应
  • 从只是成本变为产生价值

关注点: 不要无处不在

组织需要小心,不要花费大量时间在基础和地下室上,同时缺乏资源在地面以上建造好东西。

与此同时,你只能在坚实的基础之上建造。地下室也不应该坍塌。

我们需要关注点。如果在大型云中运行,所有基础组件以预制的方式存在。我们应该首先考虑这些。

同样,在地下室层面,我们可以花很多时间建立一个可观测性平台。但存在各种 SaaS 解决方案或云提供商提供的解决方案。安全性也是如此。如果预制组件不满足要求,仔细检查这些要求。我们确定拟议的更简单的解决方案是否“足够好”吗?我们能否现在满足于一些简单的东西,以后再改进?

在边缘运行时,关注操作系统和网络至关重要:我们需要能够在不破坏网络和锁定自己的情况下安全地更新远程设备。另一方面,在云中运行时,优先考虑云供应商提供的解决方案,就此打住。

在私有环境运行时,我们可能需要高性能的存储解决方案和有状态工作负载的备份解决方案。但是在云中运行时,我们不需要在Kubernetes中自己搭建数据库。考虑使用托管数据库,提供您需要的所有大小调整选项和点时恢复。使用与S3兼容的对象存储来存储文件。使用SaaS进行可观测性,避免存储所有日志,指标和追踪。这样可以使存储需求最小化,使我们的设置保持简单。

复杂性预算

向集群添加的任何自定义或组件都会增加复杂性。它需要第1天的设置和第2天的维护,并且通过这种方式,它需要资源。这意味着我们可以承受的复杂性数量是有限的。

尽管根据您询问的人,定义的边界可能会有所不同,但我们可以将我们平台上的每项自定义或添加视为资本支出: 这是我们希望从中获得投资回报的前期费用。

只要我们在资本支出上的花费最终减少或者至少稳定我们的整体运营支出,我们的运营就是可持续的。如果不是,如果运营支出占了上风,我们就会遇到问题。

能力

这并不意味着我们永远不应该向我们的平台添加任何组件。当我们的运营范围扩大时,复杂性也会增加。我们需要应对这一点的方法。顺便说一句,这不仅仅是Kubernetes所特有的。

这确实意味着我们应该考虑什么时候添加组件以及它们对未来的整体工作量有何影响。

API 飞轮效应

当避开了地表以下的一些复杂性陷阱时,Kubernetes 提供的统一 API 和工作方式就可以开始产生回报。让我们举个例子:

挑战: 我们有一个 Kubernetes 设置。团队正在部署应用程序。然而,我们注意到工作负载有时无法承受重新调度。此外,一致的标记也有点问题。

改进: 我们添加了一个策略引擎。这有助于我们实施良好的实践。

新状态: 团队将 YAML 放入集群。集群有时会说不。

挑战: 我们注意到我们开始有很多部署流水线。而且它们都略有不同。我们越来越难以将我们集群中应运行的内容与这些流水线关联起来,而这些流水线主要由各个工程团队管理。

改进: 我们添加了 GitOps。我们现在有一个单一的窗口,基于拉取请求的工作流程来部署更新。我们已经有基于 PR 的工作流程,所以这很合适。当然,我们可以自动化某些更新,以避免不必要的拉取请求。同样值得注意的是,通过分离 CI 和 CD 流水线,我们的流水线可以变得非常简单

新状态: 团队将 YAML 放入 git。GitOps 将 YAML 放入集群。集群机制使事情发生。

挑战: 一些团队注意到他们需要比基于 CPU 的工作负载缩放更“智能”的东西。

改进: 平台团队设置 KEDA。由于已经有了一个策略引擎,所以很容易为 KEDA 缩放器配置设置一些防护栏。

新状态,就像以前一样: 团队将 YAML 放入 git。GitOps 将 YAML 放入集群。集群机制使事情发生。

挑战: 平台团队注意到大多数需要为工程团队完成的更改归结为相同的事情:为新服务提供命名空间、工件存储库、数据库、Redis、流水线、IAM 标识或队列。

改进: 在 POC 之后,平台团队决定设置 Crossplane,调整策略引擎以允许一组受控的 Crossplane 资源,并提供防护措施。现在,团队可以自己设置资源。与此同时,平台团队可以继续关注提供和维护这种能力,而不会被“大量类似任务”淹没。

新状态,就像以前一样: 团队将 YAML 放入 git。GitOps 将 YAML 放入集群。集群机制使事情发生。

挑战: 平台团队注意到跟踪组件更新需要越来越多的努力。

改进: 在 POC 之后,他们设置了 Renovate。现在,平台团队不再需要检查平台中运行的每个组件的发布页面。

新状态,与以前非常相似: Renovate 将 YAML 放入 git。GitOps 将 YAML 放入集群。集群机制使事情发生。

上述更改不是一夜之间就能实现的。此外,它们有时涉及改变一个组织中的工作方式,这通常比技术部分更难。然而,它们确实展示了,在一个地方谨慎地承担额外的复杂性,可以减少组织内的整体运营工作量。

API 思维方式

在采用 Kubernetes 时,根据组织、经验和文化的不同,可能会有不同的视角:

  • 自下而上: “我们运行服务器,并在其上面部署 Kubernetes”
  • 自上而下: “我们运行 Kubernetes,碰巧需要服务器”

前者倾向于避免更改并专注于正常运行时间。

后者将频繁的受控更改视为满足各种需求的一种手段。

这是一个细微的区别,但你可能已经猜到了,在使用 Kubernetes 时,自上而下的思维方式更合适。长期来看,它将带来一个更易于维护的平台。一些例子:

不要: 设置对服务器的 shell 访问以用于管理目的。

而要: 关注如何避免登录(生产)服务器的需要。我们需要发送出什么可观测性数据?我们如何在实验室设置中重现错误场景?

不要: 研究如何就地修补节点,以及伴随而来的整个编排、检查和重启过程。

而要:考虑不可变的基础设施。经常用打了补丁的节点简单替换旧节点。这是一个易于重现(在非生产环境中测试)和可逆的过程。额外收益: 混沌工程

不要: 使用Ansible在服务器上“做事情”

而要: 关注不可变基础设施和cloud-init,执行绝对必要的少量安装步骤。

不要: 使用可观测性代理、EDR代理等扩展VM镜像

而要: 更青睐daemonsets,根据需要具有安全上下文,来运行这些进程。记住飞轮效应:我们已经有方法可以轻松地将工作负载放入集群,并具备监控组件的所有可观测性。此外,Renovate 将帮助我们保持组件的更新。

上述的重点是,我们需要避免最终落入十年前的状况(管理大量VM),另外,还要管理大量Kubernetes的移动部件。我们需要利用Kubernetes使VM管理部分变得更容易,或完全消除。这将留出空间来关注平台和开发人员体验。

结论(也称 TL;DR)

在一定规模下,随着团队数量的增加,组织将面临以下挑战:

如何提供防护栏而不会最终造就门槛?

合规、安全、成本效益、性能和灾难恢复等主题都需要解决。将这些问题委托给每个团队处理既没有效率,对团队也是一个干扰,而且要求每个团队对这些主题有足够的知识。因此,组织需要一种方法来整合这些知识,并将其应用于所有团队。简而言之,这就是为什么“DevOps”这个流行词语现在被“平台工程”所取代的原因。

大规模运行时,Kubernetes在2024年也可以成为构建这种平台工程的合适技术栈。但风险很高:可能带来巨大回报,但在开始回馈之前需要前期投入。这对进入构成了一定的风险和障碍。

比较技术栈

如上图所示,在技术栈之间,存在收支平衡点。请注意,这是概括性的: 是否存在以及收支平衡点在哪里取决于组织是否成功控制总体工作量在限定范围内。我们可以了解到的是,由于其本质,Kubernetes非常适合缩放初始工作量到许多团队。

如果不主要关注规模: 在边缘运行时,Kubernetes可能会成为一个有趣的选择,它自然地集成到您运行集中式应用程序的方式中。

然而,Kubernetes可能根本不适合您的组织:

  • 需要在云中运行“一些”应用程序的创业公司?除非您对此有明确目标,否则不要首先构建 Kubernetes。
  • 没有集中式平台团队的自治团队?您需要_一些东西_来避免每个团队稍微不同地重造 DevOps 车轮。可以是 Kubernetes。
  • 实际上并没有运行太多容器,而是使用无服务器?太棒了,建立您的组织以持续改进_那个_技术栈。不要因为“人们正在使用 Kubernetes”而考虑 Kubernetes。

明智地花费您的复杂性预算。选择 Kubernetes 时,关注 API,您甚至可能会忘记服务器。

只要避免陷入表面以下而忘记享受阳光即可。

  1. 避免过滤泡沫,过滤无意义的噪音和仅为了引发互动的随机事物列表,社交媒体上仍有许多洞见和观点可以获取。
  2. 幸运的是,现在有足够的工具可以满足任何人对纯 YAML、模板化 YAML、编程 YAML 或转换为 YAML 的 JSON 的偏好。
  3. 查看团队拓扑,当我提到“平台团队”或简单的“团队”时,它们分别指“平台团队”和“流一致型团队”。
  4. 罪过,去过那里。与管理 daemonset 相比,扩展 AWS AMI 非常麻烦。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注