Kubernetes对应用开发者来说是不是太复杂了?

几周前,我参加了 KubeCon EU 大会,并发表了演讲。这是一个大约有 4700 人参加的大型活动,让我想起了 2014 年 11 月在巴黎举行的 OpenStack 峰会。同样是人潮涌动,厂商露脸,程序员派对……然而,我发现了一个根本性问题:我遇到的几乎是清一色的运维人员或 SRE 工程师。应用程序开发人员都去哪儿了?这些复杂的基础设施不是应该为这些人提供服务的吗?Kubernetes 社区是否真的关注用户的需求?于是我禁不住想:Kubernetes 是否太复杂了?它的复杂性会阻碍自身的发展吗?

我这样想似乎有点太过了,不过我不认为最终会出现这种情况。相比 OpenStack,Kubernetes 有自己独到的优势。首先,它具有更高的可扩展性,因此能够在拥有数千台服务器的环境中实现大规模集群调度。其次,三家主要云供应商已经推出了 Kubernetes 托管服务产品。在短短的四年时间里,Kubernetes 几乎成为云计算和基础设施领域的事实标准。不过,Kubernetes 的复杂性对大家来说仍然是一个问题。OpenStack 在 2014 年以后渐趋颓势,Kubernetes 会步入 OpenStack 的后尘吗?

Kubernetes对应用开发者来说是不是太复杂了?

大多数开发人员没有 Google 那样的规模问题

Kubernetes 的推出旨在解决类似 Google 那样规模的复杂性和问题。我们希望基础设施具有自我修复、水平伸缩和声明式配置(如基础设施即代码)能力。但问题是,绝大多数应用程序和应用程序开发人员不会面临这些问题。大多数应用程序只有适度的规模(包括项目规模和用户群),或者它们还处在市场产品研究的早期阶段。

在应用程序还没有达到规模化之前,通常没有必要增加这些复杂性。在这种情况下,单个数据库和应用程序服务器可能是更好的选择,只要它们能够处理你的流量负载。如果 99.5%的时间是可用的,并具有完备的运维警报,那么对于大部分应用程序和工作负载来说已经很不错了。建立分布式系统所带来的复杂性以及对上市时间造成的延迟只会让我们得不偿失。

对于全新的应用程序来说,它们最大的风险是找不到目标产品或市场。也就是说,这些应用程序虽然被部署了,但从未被使用过。它们的代码最终被遗弃,因为没有人想要使用这些应用程序。这是绝大多数应用程序的代码可能会面临的处境。在我的职业生涯中,大部分时间都花在了代码和功能的迭代上,并尝试找到正确的应用程序功能集。一旦找到了,就可以对其进行扩展,但在此之前所做的努力都只不过是不成熟的优化。

我认为 Kubernetes 的问题在于它对项目早期阶段的认知负载有很高的要求。在一开始就需要考虑很多事情,这对于启动项目和快速迭代来说是一种阻碍。在项目的早期阶段,功能开发速度和迭代速度是最重要的。我认为 Heroku 是一个理想的开发模型,可以一边使用 Postgres 托管数据库,一边通过 Git 推送来部署新代码并对外提供服务,不需要考虑太多的东西。它可能无法无限扩展,并且可能会很贵,但在应用程序达到规模化之前,根本不需要担心这些问题。

简单地说,Kubernetes 让简单的事情变复杂,让解决复杂的问题成为可能。如果 Kubernetes 想要取得真正的成功,需要让项目的早期阶段变得更简单,并降低应用程序开发人员的认知负担。要让开发者在某个时刻开始学习 Kubernetes 错综复杂的细节,这并不是什么问题,因为随着规模增长,一切事物都会变得复杂和棘手。但作为一个成功的开发平台,不应该在没有必要的情况下将这些决策压力放在开发者面前。Ruby on Rails 之父 David Heinemeier Hansson(网络代号 DHH) 在 RailsConf 2018 主题演讲中将这种情况称为“JIT Learning(即时学习)”。

我想用 Rails 作为例子:为什么 Rails 当时如此成功?并不是因为 Ruby 的流行(它当时只是来自日本的一门新的编程语言),也不是因为 Rails 和 Ruby 在动态网页方面的优异表现,而是因为它们可以提高开发人员的生产力。DHH 给大家介绍了如何用 15 分钟创建一个博客,这引起了 Java 和.NET 开发人员的注意,因为他们需要花几个星期甚至几个月才能做出同样的东西。开发人员选择 Rails 是因为他们可以更快地向用户发布功能,而这正是这些框架和基础设施能够提供的。

Rails 为开发者创建应用程序骨架,并生成脚手架和部分项目代码。开发人员不需要在项目开始时做出大量决策,比如应该如何组织应用程序代码、数据库模型应该放在哪里、应该定义怎样的 asset 管道、如何进行数据库迁移以及完成其他的任务和决策。

我认为 Kubernetes 也可以从这类生成器中受益。现在已经有一些特定的资源生成器,但还远远无法满足需求。如果有针对不同类型应用程序的模板,那就更好了。关系数据库、应用程序层、缓存服务器、消息队列和工作线程池的组合占到了构建应用程序的 90% 甚至更多,这种简单的结构可以扩展到令人难以置信复杂程度。模板或生成器可以生成开箱即用且具有 Kubernetes 组织结构的资源和代码,这将非常有用。

用于生成共公元素的脚手架生成器就很不错。需要一个 MySQL 数据库?可以使用类似下面的命令

kubectl scaffold mysql --generate

来创建一组有状态的服务和其他必需的东西。然后,只需一个命令就可以将脚手架部署到 k8s 环境中,然后再使用几个控制台命令即可拥有一个生产就绪的数据库。对于流行的应用程序框架、消息代理服务器以及我们能够想到的其他任何东西,都可以使用类似的方法。

或许 Operator 和 Helm 的组合就可以完成这些工作,但我认为这样还不够好。因为开发人员在 Kubernetes 之外还需要了解两个额外的工具。即使是了解简单的技术术语和安装新的命令行工具也需要额外的努力和思考。这些东西应该成为 Kubernetes 开箱即用体验的一部分,并可以直接通过 kubectl 来访问。

CNCF 的领地越来越广阔

CNCF 中的项目越来越多,这对 Kubernetes 来说算不上是特别的问题,但 CNCF 项目的格局非常庞大,以致于 KubeCon/CNCF 大会非常分散,一个大会就包含了 14 个主题。作为开发人员,我怎么知道哪些工具适合我的项目?看一下 CNCF 中的项目:

Kubernetes对应用开发者来说是不是太复杂了?

要了解图中所有的项目是不可能的。如果已经存在一组预选好的工具,那么应用程序开发者将会有更好的体验。如果他们想加入不同的工具,完全没问题,但至少不应该让他们在事先就去考虑这些问题。CNCF 日益增长的复杂性和广泛的影响力可能会淡化 Kubernetes 作为构建平台的品牌效应。我不确定结果会怎样,也不确定我是否在夸大其词,但是就我看来,它更像是一种工具大杂烩。当你费劲毕生精力来学习和构建基础设施工具时,还会有精力去解决用户的问题吗?

我想强调的是:基础设施的存在是为了帮助应用程序开发人员解决用户的实际问题,它们需要不断优化,提高交付的效率和能力。能够做到这一点的开放平台才会胜出。

必要的知识

在某些时候,开发人员需要更深入地学习基础设施工具。大多数在 AWS 工作的开发人员都熟悉 AWS 的一些组件,就像 Google Cloud Platform 或 Azure 开发人员熟悉他们的云一样。将 Kubernetes 作为基础层更有可能成功,因为开发人员只需要学习 Kubernetes,就能在任何公共云或私有云上使用。

不过 Kubernetes 的学习曲线并不平稳。作为一个生态系统,Kubernetes 需要满足应用程序开发人员的需求才能真正取得成功。毕竟,基础设施是解决用户问题的支持工具。提高应用程序开发人员的工作效率才是确保一个平台能够被广泛采用并取得成功的最佳途径。


上一篇:1.k8s介绍


下一篇:星环科技通过KCSP认证 成为CNCF官方认证的Kubernetes服务提供商