当我们决定使用Kubernetes时,会遇到八个问题
这篇文章是Itamar Turner-Trauring先生于2020年3月发布的“让我们使用Kubernetes!现在你有8个问题”一文的翻译转载。我们已获得作者的许可进行发布。
如果使用了Docker,接下来使用Kubernetes,也被称为K8s,似乎是自然的发展。这是在生产环境中的运行方式,对吗?
嗯,可能是这样的。专为500名软件工程师使用同一应用程序的解决方案与适用于50名软件工程师的解决方案完全不同。此外,它们也与专为5人团队设计的解决方案完全不同。
如果我所属的是一个小团队,那么Kubernetes可能并不适合这样规模较小的团队。因为它非常复杂,且几乎没有什么优势。
让我们解释一下原因吧。
每个人都喜欢移动的组件
在Kubernetes中,存在许多可动部件,如概念、子系统、进程、机器、代码等等…这也意味着同时存在许多问题。
多台机器
Kubernetes是一个分布式系统,它有一个控制工作机器的主要机器。工作被安排在不同的工作机器上。然后,每个机器都使用容器来执行工作。
为了实现某件事,我们正在谈论两台机器或虚拟机。然而,你只有一台机器。如果要实现扩展(这是关键),需要3到4台,或者17台虚拟机。
非常庞大的代码量
截至2020年3月初旬,Kubernetes的代码库中包含超过58万行的Go代码。这些代码是实际的代码,不包括注释和空行,并且不计算供应商提供的软件包。在2019年的安全审查中,对代码库做了以下描述。
「…Kubernetes的代码库还有改进的空间。这个代码库庞大且复杂,包含了关于Kubernetes外部系统的最基本文档以及很多依赖的代码段。有很多情况下需要重新实现代码库内的逻辑。将这个代码库统一到一个支持库中,可以减少复杂性,更容易应用补丁,减轻了在代码库不同领域之间的文档负担。」
从公平的角度来看,这与许多大型项目并无太大差异。这些代码都是要在应用程序不崩溃时进行操作的。
架构的复杂性、操作的复杂性、配置的复杂性以及概念的复杂性。
Kubernetes是一个具有多个不同服务、系统和组件的复杂系统。
在执行单一应用程序之前,需要像Kubernetes文档中所示的高度简化的架构。
K8s文档中的概念文档包含了许多与教育相关的信息。
在Kubernetes中,EndpointSlice包含对网络端点集的引用。当指定选择器时,EndpointSlice控制器会自动创建Kubernetes服务的EndpointSlices。这些EndpointSlices包含对与服务选择器匹配的Pod的引用。EndpointSlices通过唯一的服务和端口组合将网络端点分组。
默认情况下,由EndpointSlice控制器管理的EndpointSlices中,每个EndpointSlice都包含100个或更少的端点。如果低于这个规模,EndpointSlices将与端点和服务一对一映射,并提供类似的性能。
实际上我有一定程度的理解,但是我意识到了需要几个概念。具体来说,我需要了解EndpointSlice、Service、selector、Pod以及Endpoint这几个概念。
当然,大多数情况下,这些功能大多数都不是必需的,而且大多数情况下也不需要Kubernetes。
另一个随机选择:
默认情况下,发送到 ClusterIP 或 NodePort 服务的流量将被路由到服务的后端地址。Kubernetes 1.7 及更高版本可以将“外部”流量路由到接收流量的节点上运行的 Pod,但这在 ClusterIP 服务中不受支持,并且无法实现更复杂的区域路由等拓扑。服务拓扑功能解决这个问题,它允许服务创建者根据源节点和目标节点的节点标签来设置路由流量的策略。
先ほど述べたセキュリティレビューの内容は次のとおりです。
Kubernetes是一种非常复杂的大规模系统。评估团队认识到Kubernetes的配置和部署至关重要,特定组件具有复杂的默认设置,无法进行操作控制,并且具有隐含的安全控制。
软件开发的复杂性
随着对Kubernetes的信任增加,常规开发变得更加困难。要运行代码,需要掌握各种概念(如Pod、Deployment、Service等)。因此,我们需要启动一个完整的K8s系统,通过虚拟机或嵌套的Docker容器进行测试。
另外,由于在本地执行应用程序非常困难,因此开发变得更加困难。我们将本地进程代理到集群中(数年前创建了这个工具),将远程进程代理到本地机器等,形成了各种解决方案。
存在很多不完善的解决方案。但是最简单且最佳的解决方案就是不使用Kubernetes。
微服务(这个想法不太好)。
这个系统具有执行许多服务的能力,这是导致二次问题频繁出现的原因,而人们往往会不自觉地写入太多的服务。这是个不好的想法。
分散式应用程序是非常难以精确书写的。真的非常困难。可动部件越多,这些问题就会更多地发生。
分散应用程序的调试很困难。要理解不如从单体应用程序日志中得到的信息那样好,我们需要全新的仪器和日志记录类别。
微服务是组织的扩展技术。当有500名开发人员在一个活跃的网站上工作时,如果开发团队可以独立工作,支付大规模分布系统的费用是合理的。因此,将每个由5名开发人员组成的团队提供一个单独的微服务,让该团队认为其余的微服务是不可信的外部服务。
如果我們有一支由5人組成的團隊,並且有20個微服務,而且對分散式系統的需求不高,這樣的做法是錯誤的。因為與大型企業不同,我們公司每個服務的人數只有0.25人而已。
但是,这样方便吗?
缩放
Kubernetes对于需要大规模扩展的情况非常有帮助。现在让我们考虑一些选项。
-
- 最大416個のvCPUと8TiB RAMを搭載したクラウドVMを取得できます。これは、本当にありえないくらいの規模です。そうです!もちろん、かなり高価ですが、シンプルです。
- Herokuなどのサービスを使用すると、たくさんのシンプルなWebアプリケーションを非常に簡単にスケーリングできます。
当然,这就假定通过增加员工实际上会带来一些好处。
-
- ほとんどのアプリケーションは、そこまで拡張する必要はありません。 合理的な最適化で十分です。
- Webアプリケーションのスケーリングは、通常、Webワーカーではなくデータベースによるボトルネックがほとんどです。
可靠性
当动态部件增加时,错误发生的概率会增加。
Kubernetes提供的功能,如健康检查和滚动部署,非常容易实现,但很多情况下它们已经内置了。例如,Nginx可以执行工作进程的健康检查。此外,还可以使用docker-autoheal等工具自动重新启动这些进程。
如果你关心停机时间,你应该考虑的不是如何将部署停机时间从1秒减少到1毫秒,而是如何确保数据库架构变更无法回滚的方法,以防止发生失败。
另外,在不使用单一机器的情况下,有很多种方式可以绕过可信的Web工作者作为故障点,而不必使用Kubernetes。
在中文中,最佳实践是什么?
一般而言,并没有什么固定的最佳实践方法。确实针对特定情况会有最佳实践方法。单单因为某事受欢迎或者正流行着,并不能仅仅因此而成为对你来说最好的选择。
根据情况而定,Kubernetes是一个非常出色的工具。然而,有些人认为Kubernetes只是浪费时间,使用它也没有任何好处。
除非真正需要非常複雜的情況,否則可以使用各種工具進行單一機器上的Docker Compose、Hashicorp的Nomad用於編排、類似Heroku系統,以及用於計算管道的Snakemake。