Paul Butler – Kubernetes 仇恨者指南

在某些技术中,Kubernetes 被认为是一种不必要的复杂时间消耗,初创公司应该避免。 在小团队中使用 Kubernetes 被视为过度设计的表现。

我有罪 简洁的刺拳 我。

尽管我尖酸刻薄,“伟大的技术”确实是真诚的; 在那篇文章发表时我有 最近写的 关于 Kubernetes 的复杂性对于它的工作来说有多少是必要的。

我们已经在生产环境中运行 Kubernetes 几年了 插头,我发现了一个很好的流程。 Kubernetes 的宁静已在内部实现。 这其中的一个重要关键是 切出一小块 Kubernetes 的功能,并假装其余功能不存在。

这篇文章最初是作为我们使用 Kubernetes 方式的内部指南,因此它并不意味着适用于每个初创公司; 尽管如此,我认为这是一个很好的起点,可以避免 Kubernetes 浩瀚海洋中的许多沙洲。

为什么要使用 Kubernetes?

在我看来,如果您想要同时满足以下三点,Kubernetes 是最佳选择:

  1. 运行多个进程/服务器/计划作业。
  2. 冗余地运行它们并在它们之间进行负载平衡。
  3. 将它们以及它们之间的关系配置为代码。

从最基本的角度来看,Kubernetes 只是一个抽象层,让您可以将计算机池想象为一台(无头)计算机。 如果这是您的用例,并且您可以避免其中的其他部分,那么您可以走得很远。

有些人告诉我,#2 太过分了,初创公司不应该专注于零停机部署或高可用性。 但我们经常每天进行多次部署,当我们的产品出现故障时,我们客户的产品也会出现故障 他们的 用户。 即使是一分钟的停机也会有人注意到。 滚动部署让我们有信心轻松、频繁地进行部署。

我们如何使用 Kubernetes

对于背景, 插头 是一项用于动态启动 Web 应用程序可以与之对话的进程的服务。 有点像 AWS Lambda,但进程生命周期绑定到 WebSocket 连接而不是单个请求/响应。

我们使用 Kubernetes 来运行支持该功能所需的长时间运行的进程。 API服务器、容器注册表、控制器、日志收集器、一些DNS服务、指标收集等。

有几件事我们 使用 Kubernetes 来:

  • 短暂的过程本身。 我们很早就做了一个热门的一分钟,但我们很快发现它的局限性(稍后会详细介绍)。
  • 静态/营销网站。 我们用 韦尔塞尔 对于那些。 它更昂贵,但小型初创公司一小时工程时间的机会成本也更高,而 Vercel 为我们节省的费用比它的成本还要多。
  • 任何直接存储数据的东西我们都会很难过失去。 我们确实使用一些持久卷来缓存或派生数据,但除此之外,我们还使用集群和 blob 存储之外的托管 Postgres DB。

还值得注意的是,我们自己不管理 Kubernetes——使用 Kubernetes 的主要优点是我们可以外包它的基础设施级别的操作! 我们对 Google Kubernetes Engine 非常满意,同时 谷歌域名惨败 虽然动摇了我对 Google Cloud 的信心,但我至少可以睡个好觉,因为我知道迁移到 Amazon EKS 会相对简单。

我们容易使用的东西

我们会毫不犹豫地使用几种类型的 k8s 资源。 我在这里仅列出我们明确创建的资源; 这些资源中的大多数都隐式地创建了其他资源(例如 Pod),我不会提及这些资源,但我们当然会(间接)使用它们。

  • 部署:我们的大多数 Pod 都是通过部署创建的。 对我们的服务功能至关重要的每个部署都有多个副本和滚动更新。
  • 服务: 具体来说, ClusterIP 用于内部服务和 LoadBalancer 对于外部的。 我们已经避免了 NodePortExternalName 服务,更喜欢我们的 DNS 配置位于 Kubernetes 之外。
  • 定时任务:用于清理脚本之类的事情。
  • 配置映射秘密:用于将数据传递到上述资源。

我们谨慎使用的东西

  • 有状态集持续成交量索赔:我们使用了一些 StatefulSet。 配置比部署稍微复杂一些,但它们可以在重新启动时拥有持久卷。 我们更喜欢将重要数据保存在 k8s 之外的托管服务中。 我们没有针对卷的硬性规则,因为有时在服务重新启动时保留例如缓存是很好的,但我会尽可能避免使用它们,因为它们可能与滚动部署进行不良交互(死锁)。
  • RBAC:我们在一些地方使用了它,例如授予服务刷新秘密的权限。 它给我们的小集群增加了足够的复杂性,我基本上避免使用它。

我们积极避免的事情

  • 手写 YAML。 YAML 有 足够的脚枪 我尽可能避免它。 相反,我们的 Kubernetes 资源定义是通过 TypeScript 创建的 缅甸语
  • 非内置资源和运算符。 我有 之前写过 关于如何 控制回路 模式是一把双刃剑:它是使 K8s 健壮的核心思想,但它也是间接性和复杂性的根源。 这 操作符模式定制资源 允许第三方软件使用 Kubernetes 强大的基础设施来实现自己的控制循环,这在理论上是一个好主意,但我发现在实践中很笨拙。 而不是 证书管理器, 我们用 球童的 证书自动化。
  • 。 由于操作符和没有 YAML 规则,Helm 是不行的,但我也认为使用非结构化字符串模板来生成机器可解析的东西意味着引入脆弱性而没有任何好处。 nindent 对我来说就像黑板上的钉子一样,对不起。
  • 名称中带有“mesh”的任何东西。 我想它们对某人有用,但对我没用,也不对 这家伙 任何一个。
  • 入口资源。 我没有因为这些而留下任何战斗伤痕,而且我知道有些人有效地使用它们,但我们成功使用 Kubernetes 的一个主题是避免添加不必要的间接层。 配置 Caddy 对我们来说很有效,所以我们就这样做。
  • 尝试在本地复制整个 k8s 堆栈。 我们不使用 k3s 或 kind 之类的东西来精确复制生产,而是使用 Docker Compose 或我们自己的脚本来启动我们当前真正关心的系统子集。

人类不应该等待 Pod

上面我提到了这样一个事实:我们在 Kubernetes 上简短地运行了短暂的、交互式的、会话存活的进程。 我们很快意识到 Kubernetes 的设计目标是在容器启动时间上实现稳健性和模块化。 一般来说,我的看法是,当您想要冗余地运行一些长时间运行的进程时,Kubernetes 非常适合,但如果有人一直在等待 pod 启动, Kubernetes 是错误的选择

我承认我在这里谈论的是我的书,但至少它是一本开源书:我们使用一个 MIT 许可的 Rust 编排器,名为 飞机 我们专门为交互式工作负载(即有人等待的工作负载)快速调度和运行进程而设计。

更高层次的抽象

为了完整起见,我还应该提到一些已经出现的 Kubernetes 替代品非常好。 特别是如果您不想要或不需要我最初列表中的要求#3(将基础设施指定为代码的能力)。 我们的产品之一,我们选择使用 铁路 而不是我们的 k8s 集群,主要用于预览环境。 一些我非常尊敬的朋友发誓 使成为 (我已经涉足过,但个人认为 Railway 的环境模型更干净。)我也偏向 飞行控制系统 自带云方法。

对于许多 SaaS 类型的应用程序,您可能会在这些方面取得很大的进展。 但是,如果您满足本文开头列出的三个需求,并且采取严格的方法来实现,请不要让任何人告诉您您对 Kubernetes 还为时过早。


1709494852
#Paul #Butler #Kubernetes #仇恨者指南
2024-03-03 16:44:05

Leave a Reply

Your email address will not be published. Required fields are marked *

近期新闻​

编辑精选​