Maybe You Don't Need Kubernetes

Matthias Endler

也许你并不需要 Kubernetes

原文由 Matthias Endler 发布,订阅该博客

一位骑着踏板车的女性
一位骑着踏板车的女性
来源:插图由 freepik 创作,Nomad 徽标来自 HashiCorp

Kubernetes 是容器编排领域当之无愧的巨无霸。
它支撑着全球一些规模最大的部署,但也代价不菲。

对于小团队来说,维护它既耗时,学习曲线又十分陡峭。对于我们这个四人小团队在 trivago 想要实现的目标而言,它的额外开销太大了。于是我们开始寻找替代方案——最终爱上了 Nomad

需求清单

我们团队运行着一批用于监控和性能分析的常规服务:用 Go 编写的指标 API 接口、Prometheus exporter、Logstash 或 Gollum 这类日志解析器,以及 InfluxDB 或 Elasticsearch 等数据库。这些服务都各自运行在独立的容器中。我们需要一个简单的系统来让这些任务持续稳定地运行。

我们为容器编排列出了一份需求清单:

  • 能够在多台机器上运行一组服务。
  • 能够总览所有正在运行的服务。
  • 允许服务之间相互通信。
  • 服务异常退出时能够自动重启。
  • 小团队也能轻松维护。

除此之外,以下几点算是锦上添花,但并非硬性要求:

  • 能够按机器能力打标签(例如,给配备高速磁盘的机器打上标签,以运行 I/O 密集型服务)。
  • 这些服务能够脱离编排系统独立运行(例如在开发环境中)。
  • 有一个可以共享配置和密钥的公共位置。
  • 提供用于指标和日志的接口。

为什么 Kubernetes 不适合我们

在用 Kubernetes 搭建原型时,我们发现为了运行服务,不得不不断叠加越来越复杂的逻辑层。而且我们开始在不知不觉中依赖这些逻辑。

举个例子,Kubernetes 允许通过 ConfigMaps 来嵌入服务配置。尤其是在合并多个配置文件或向同一个 Pod 中添加更多服务时,很快就会变得相当混乱。Kubernetes——或者说 helm——允许动态注入外部配置,以实现关注点分离。但这会导致你的项目与 Kubernetes 之间产生紧密而隐蔽的耦合。Helm 和 ConfigMaps 都是可选功能,你完全可以不用。你大可以直接把配置复制到 Docker 镜像里。然而,走上那条路的诱惑很大,很容易构建出一些不必要的抽象,之后反而会给自己挖坑。

除此之外,Kubernetes 生态仍在飞速演进。要跟上最佳实践和最新工具,就得投入相当多的时间和精力。Kubectl、minikube、kubeadm、helm、tiller、kops、oc——名单还能一直列下去。入门 Kubernetes 并不需要用到所有这些工具,但很难判断哪些是必需的,所以你至少得对它们都有所了解。正因如此,它的学习曲线相当陡峭。

什么时候该用 Kubernetes

就 trivago 而言,许多团队都在使用 Kubernetes,而且用得很满意。不过,这些集群是由 Google 或 Amazon 来托管的,它们有能力做到这一点。

Kubernetes 带来了一些出色的功能,让大规模的容器编排变得更可控:

  • 细粒度的 权限管理
  • 自定义控制器可以把业务逻辑带入集群。它们本质上就是与 Kubernetes API 交互的程序。
  • 自动扩缩容!Kubernetes 可以按需自动扩容或缩容你的服务。它利用服务指标,无需人工干预即可完成。

问题在于,你是否真的需要所有这些功能。你不能指望这些抽象开箱即用;你必须了解底层到底发生了什么

尤其是我们团队,大部分服务都运行在本地自建机房(因为与 trivago 的核心基础设施紧密相连),我们不想为自建 Kubernetes 集群付出成本;我们只想把服务交付上线。

重磅观点:五年后没人会在乎 Kubernetes。—— 来自 Corey Quinn 的一条推文

不含电池

Nomad 只做了服务编排中 20% 的事,却能帮你完成 80% 的工作。它所做的就是管理部署:负责你的版本发布,并在出错时重启容器,仅此而已。

Nomad 的核心设计理念就是做得更少:它不包含细粒度的权限管理或高级网络策略,这是刻意为之。这些能力要么作为企业版功能提供,要么由第三方提供——要么干脆没有。

我认为 Nomad 在易用性和表达能力之间找到了一个恰到好处的平衡点。它很适合那些规模较小、彼此相对独立的服务。如果你需要更强的控制力,就得自己去实现,或是换用别的方式。Nomad 仅仅是一个编排器。

Nomad 最棒的一点在于它很容易被替换。几乎不存在厂商锁定,因为它提供的功能可以很轻松地集成到任何其他服务管理系统中。它只是在集群中的每台机器上以一个普通的单文件二进制程序的形式运行,仅此而已!

由松耦合组件构成的 Nomad 生态

Nomad 真正的强大之处在于它的生态。它能与 Consul(键值存储)或 Vault(用于密钥管理)等其他完全可选的产品很好地集成。在你的 Nomad 配置文件中,你可以加入从这些服务拉取数据的配置段:

template {
  data = <<EOH
LOG_LEVEL="{{key \"service/geo-api/log-verbosity\"}}"
API_KEY="{{with secret \"secret/geo-api-key\"}}{{.Data.value}}{{end}}"
EOH

  destination = "secrets/file.env"
  env         = true
}

这段配置会从 Consul 读取 service/geo-api/log-verbosity 键,并将其作为 LOG_LEVEL 环境变量暴露在你的任务中。同时,它还会把 Vault 中的 secret/geo-api-key 作为 API_KEY 暴露出来。简单,却很强大!

正因为如此简单,Nomad 还可以通过 API 轻松与其他服务扩展集成。例如,可以为任务打标签以实现服务发现。在 trivago,我们给所有暴露指标的服务都打上 trv-metrics 标签。这样,Prometheus 就能通过 Consul 发现这些服务,并定期抓取 /metrics 接口的新数据。日志也可以用类似的方式,比如集成 Loki 来实现。

还有许多其他可扩展性的例子:

  • 通过 webhook 和 Consul watches 触发 Jenkins 任务,在服务配置变更时重新部署 Nomad 任务。
  • 使用 Ceph 为 Nomad 添加分布式文件系统。
  • 使用 fabio 进行负载均衡。

所有这些都让我们能够让基础设施有机地生长,而无需太多的前期投入。

友情提示

没有哪个系统是完美的。我建议你暂时不要在生产环境中使用那些花哨的新功能。当然,Nomad 也有 缺陷缺失的功能——但 Kubernetes 同样如此

与 Kubernetes 相比,Nomad 背后的发展势头要小得多。迄今为止,Kubernetes 已有约 75,000 次提交和 2000 名贡献者,而 Nomad 大约只有 14,000 次提交和 300 名贡献者。Nomad 很难跟上 Kubernetes 的发展速度,但也许它根本不需要!它的范围要窄得多,而更小的社区也可能意味着你的 pull request 更容易被接受,相比 Kubernetes 而言。

总结

结论是:不要因为别人都在用 Kubernetes,你就跟着用。要仔细评估自己的需求,看看哪款工具真正适合你。

如果你计划在大规模基础设施上部署一组同构服务,Kubernetes 可能是合适的选择。只是要注意随之而来的额外复杂性和运维成本。其中一部分成本可以通过使用托管的 Kubernetes 环境来避免,比如 Google Kubernetes EngineAmazon EKS

如果你只是想要一个可靠、易于维护且可扩展的编排器,何不试试 Nomad?你可能会惊讶于它能带你走多远。

如果把 Kubernetes 比作汽车,那么 Nomad 就是一辆踏板车。有时你更偏爱前者,有时则更青睐后者。两者都有其存在的价值。

本文章由 muse-spark-1.2-contributor 进行翻译

评论