你真的需要用Kubernetes吗?


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集群。我们只想要提供服务。
nuclear-kubernetes.jpg

鬼使神差

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的值并在你的job中将其暴露给LOG_LEVEL这个环境变量,同时也从Vault中读取键为secret/geo-api-key的值暴露为API_KEY。是不是很简单明了强大!

正因为它非常简单,Nomad也可以通过其API轻松扩展其他服务。例如可以标记job以进行服务发现。在trivago,我们使用trv-metrics标记所有公开指标的服务。这样,Prometheus可以通过Consul找到服务,并定期从/metrics端点收集获取新数据。同样的例子是通过集成Loki可以对日志进行操作 。

除此之外还有许多其他可扩展性方面的示例:
  • 使用webhook来触发Jenkins job,Consul监视并在服务配置变更时重新部署Nomad任务。
  • 使用Ceph将分布式文件系统集成到Nomad。
  • 使用fabio做负载平衡。


所有这一切使我们能够在没有太多前期承诺的情况下有机地发展我们的基础设施

友情提醒

没有任何一个系统是完美的。我建议你当前不要在生产中使用任何花哨的新功能,因为他们存在缺陷以及(可能)功能不全,而且Kubernetes也同样如此。

与Kubernetes相比,Nomad背后的势头要小得多。到目前为止,Kubernetes已经有大约75,000个提交和2000个贡献者,而Nomad大约是14,000个提交和300个贡献者。Nomad很难跟上Kubernetes的速度,但也许也没有必要!覆盖范围窄,较小的社区同样意味着与Kubernetes相比,接受PR会更容易些。

总结

不要仅仅因为其他人都使用Kubernetes你就要去用它,仔细评估你的需求并检查哪些工具能更符合场景。

如果你计划在大型基础架构上部署一系列同质服务,Kubernetes可能是一个正确选择,但请注意额外的复杂性和运营成本。使用Google Kubernetes EngineAmazon EKS等托管Kubernetes环境可以避免其中一些成本。

如果你只是在寻找一个易于维护和扩展的可靠的调度器,我觉得你可以尝试下Nomad,你可能会惊讶于它到底能给你带来多少惊喜。

如果说Kubernetes是一辆汽车,那么Nomad就是一辆摩托车。两者各有千秋,都有自己的存在权。

原文链接:Maybe You Don't Need Kubernetes(翻译:冯旭松)

0 个评论

要回复文章请先登录注册