Kubernetes解决了一些非常实际的问题,但是这些问题真的是你所面临的吗?
在过去的几年里,Docker已经成为了一种非常流行的构建、发布和运行应用程序的方式。那些必须依赖服务器配置和其他外部因素的日子已经一去不复返了。只需为Docker构建一次你的应用,然后它就可以在任何地方运行了!
虽然这对我们开发软件的方式来说是一个巨大的飞跃,但它确实带来了一些新的挑战。首先,Docker容器和主机之间的互联是非常困难的。它与我们过去的传统网络方式有很大不同,需要一定程度的技巧才能掌握好它。
存储是另一个挑战。默认情况下,Docker卷是和它们的主机绑定在一起的。这意味着如果我们想要运行共享一个卷的多个服务实例,我们就必须设置复制集或是配置设置使用云存储服务。
感觉上来说,虽然Docker本身是一个很好的技术,但它缺少了一个将这一切联系在一起的组件。而Kubernetes正是这个组件。特别是在Azure、AWS和DigitalOcean等云平台提供的完全管理形式下,Kubernetes解决了所有这些问题,同时通过其所谓的概念从最终用户那里抽象出来。
Kubernetes,也被称为k8s,是谷歌为了解决他们在全球范围内运行数以万计的应用所面临的问题而创建的。虽然一开始被人诟病为太过主观,但它的普及率却在快速增长,越来越多的公司在寻找精通Kubernetes的工程师。
虽然Kubernetes的实施已经为Spotify、ING等公司带来了令人惊叹的效果,但它可能并不是每个公司的万能解决方案。在生产中运行Kubernetes也会带来一些严重的头痛问题。在这篇文章中,我们将探讨你在决定转向Kubernetes之前应该考虑的一些因素。
学习曲线
Kubernetes有自己的实现理念。它是围绕着一些概念设计的,熟悉其中的大部分概念是在生产中运行Kubernetes的必要条件。这引入了一个相当陡峭的学习曲线。不仅对系统管理员来说,对开发人员来说也是如此。
为了让你有个大概的了解,以下是Kubernetes架构的高级概述。
所有这些管理器、调度器和服务都负责全天候地运行你的应用程序,它们也是Kubernetes中的工作负载。它们各自有自己的职责,并实现了Kubernetes中的一个或多个概念。
如果你有Docker或更传统的系统管理经验,这些概念你也并不一定熟悉。每次你将一个新的应用部署到你的集群中,Kubernetes都会为你的应用创建以下最小量的对象来运行它。
一个代表你的应用程序的Deployment对象
一个ReplicaSet来扩展与部署相关联的Pod
一个或多个可以满足你的部署网络需求的Service(可选)
一个或多个代表实际容器的Pod
这就是Kubernetes架构中最细微的颗粒。
正如你所看到的,对于一个还不熟悉Kubernetes的人来说,这可能是一个很大的问题。更重要的是,每一个对象都可以通过无数种方式进行配置,从而极大地改变它们的行为。
要启动和运行Kubernetes并正确配置其所有组件,需要投入大量时间。管理型的Kubernetes服务商会抽象大量底层配置和集成,但其中的一些工作将不可避免地会渗入到开发人员身上,他们至少需要对Kubernetes有基本的熟练度才能正常完成工作。
你不需要Kubernetes来运行你的应用程序。它只是运行生产软件的众多选项之一。仔细考虑增加的学习曲线和配置开销,对比迁移到Kubernetes所带来的好处是否值得。
应用程序是否需要扩展?
Kubernetes的关键特性之一是能够对应用程序的部分进行扩展。流量在Pod之间自动路由和分配,如果配置好了,Kubernetes甚至可以为你自动扩展Pod。
如果一个应用程序有一个或多个热门组件,需要能够处理突发事件,那么这个功能是非常有价值的。比如说在线游戏的身份验证服务,每当有新的扩展或功能推出时,可能会看到登录请求突然增加。又或者,对于那些在推出后变得非常流行的游戏,需要快速扩展其基础设施,而无需担心网络、存储等问题。这类游戏的一个例子就是《Pokémon Go》,它在推出后不久就有大量玩家涌入。他们广泛使用Kubernetes来服务于全球大量的玩家。
然而对于大多数其他应用来说,单一的服务形成了整个格局的瓶颈,这个问题往往可以通过优化来解决,而不是通过扩展来解决。当然,你可以在这个问题上多加几个Pod,然后祈祷它消失。也就是说,直到你最终到达存储层的限制,在这一点上,简单地扩大你的Pod并不能解决这个问题。
不要误解我的意思,能够动态扩展你的部署是一个很大的好处。但在我所见过的绝大多数情况下,扩大部署规模以应对瓶颈是治标不治本。
此外,除了使用Kubernetes之外,还有更多的方法来扩展应用。Heroku、Azure和AWS都提供了动态运行和扩展应用的方法。比如说Azure Web App有水平扩展的选项,这与在Kubernetes中运行多个Pod并在它们面前放置一个负载均衡器的效果是一样的。
如果扩展的能力是吸引你到Kubernetes的原因,那就先仔细考虑一下其他的、较少维护的替代方案。
运行微服务
Kubernetes主要面向运行许多小的工作负载,这些工作负载共同构成了一个应用程序。它的关键特性之一是可以独立地扩展基础架构的一部分,而不需要将应用作为一个整体进行扩展,这一点在上一节中已经介绍过。
这些架构,通常被称为微服务架构,在Kubernetes上蓬勃发展。它的架构允许轻松地发现服务,以及在总体拓扑中的各个组件之间毫不费力地进行交互。
因此,这里要考虑的不是在Kubernetes上运行微服务是否是个好主意,而是微服务是否是给定应用的正确架构原则。虽然微服务架构通常比传统的单体架构更受青睐,但也给开发者带来了巨大的开销。
拥有各自定义了职责的独立服务是一种合理的体系架构选择。将这些职责划分为不同的服务似乎是一个合乎逻辑的续阶计划,但实际上并非如此。为了让开发人员分析和修复微服务架构中的bug,他们需要能够访问构成该环境的大部分(如果不是全部的话)服务。
这使得整个应用程序更加难以高效地工作。由于开发人员不会只在开发机器上运行应用程序,所以你需要引入一系列的工具,仅仅是为了能够排查问题。考虑每个环境的分布式日志记录、消息队列和性能监视。
这对开发者的生产力造成的影响不可谓不大。同样,这样做可能是值得的,特别是对于拥有许多开发团队的大型组织来说,每个开发团队都在他们自己的微服务上工作,将其作为大局的一部分。然而对于较小的公司和团队来说,微服务架构的代价是无限高的。而Kubernetes并不一定会让这些问题变得更容易处理。事实上,它甚至可能会让这些问题变得更糟。
如果说启用微服务架构是吸引你的原因,那么请仔细考虑一下,职责划分是否是一个可以在代码中解决的问题,而不是通过引入Kubernetes这样一个巨大的组件来解决这个问题。
结论
在考虑Kubernetes是否适合你的项目或组织时,我们已经讨论了一些需要考虑的因素。Kubernetes最初是由谷歌设计来解决谷歌的问题的。这些问题涉及到在生产环境中运行大量的工作负载,其伸缩需求对于我们这些普通人来说是不可想象的。
事实是,并非所有公司都是谷歌。虽然你可能会遇到与谷歌在设计Kubernetes时相同的问题,但你成功的机会很小。
在你决定实施Kubernetes作为你的业务基础之前,仔细考虑一下这对你的组织、开发团队以及平台的稳定性在很长一段时间内的影响是非常值得的。这项技术还比较新,精通Kubernetes的工程师相对来说比较难找。
这并不是说Kubernetes是错误的问题解决方案。我曾经参与过一些项目,这些项目依靠Kubernetes为终端用户提供价值,其规模之大是其他类似的技术所难以比拟的。关键的结论是,尽管Kubernetes背后的宣传非常真实,但在应用场景中采用Kubernetes是一个不应该掉以轻心的决定。
有些事物有时候很适合,但绝对不是一直都适合。