通过Helm进行缓慢的安装/升级(适用于Kubernetes)

时间:2018-10-26 12:10:40

标签: docker kubernetes kubernetes-helm

我们的应用程序由大约20个模块组成。每个模块都包含一个(Helm)图表,其中包含多个部署,服务和作业。其中一些作业定义为Helm预安装和预升级挂钩。总共大约有120个Yaml文件,最终导致大约50个正在运行的Pod。

在开发过程中,我们正在运行Windows版本2.0.0.0-beta-1-win75的Docker,以及Docker 18.09.0-ce-beta1和Kubernetes 1.10.3。为了简化Kubernetes yaml文件的管理,我们使用Helm 2.11.0。 Docker for Windows配置为使用2个CPU内核(共4个)和8GB RAM(共24GB)。

首次创建应用程序环境时,需要花费超过20分钟的时间。这似乎太慢了;我们可能在某个地方犯了一个重要错误。我们已尝试改善(重新)启动时间,但无济于事。对于改善情况的任何帮助或见解将不胜感激。

我们的启动脚本的简化版本:

#!/bin/bash

# Start some infrastructure
helm upgrade --force --install modules/infrastructure/chart

# Start ~20 modules in parallel
helm upgrade --force --install modules/module01/chart &
[...]
helm upgrade --force --install modules/module20/chart &

await_modules()

稍后再次执行相同的启动脚本以“重新启动”应用程序仍需要大约5分钟。据我所知,Kubernetes完全不会修改未更改的对象。赫尔姆只负责大约40个钩子。

使用docker run手动运行单个挂钩很快(〜3秒)。定期通过Helm和Kubernetes运行相同的钩子需要15秒或更长时间。

下面列出了我们发现并尝试过的一些东西。

Linux登台环境

我们的暂存环境由具有本机Docker的Ubuntu组成。 Kubernetes使用--vm-driver none通过minikube安装。

与我们的本地开发环境相反,登台环境通过(已弃用的)gitRepo卷检索几乎所有部署和作业的应用程序代码。可以理解,这似乎只会使问题恶化。首次启动环境需要25分钟以上的时间,重新启动环境大约需要20分钟。

我们尝试用Sidecar容器替换gitRepo卷,该容器将应用程序代码检索为TAR。尽管我们尚未修改整个应用程序,但初步测试表明这并不比gitRepo量特别快。

可以通过在部署和作业之间共享代码的替代类型的卷来改善这种情况。但是,我们宁愿不引入更多的复杂性,因此我们没有进一步探索这种途径。

Docker运行时

通过docker run alpine echo "test"执行一个空的高山容器大约需要2秒钟。这似乎是Windows上安装程序的开销。在我们的Linux登台环境中,该命令花费的时间少于0.5秒。

Docker卷共享

大多数容器-包括钩子-通过hostPath与主机共享代码。命令docker run -v <host path>:<container path> alpine echo "test"需要3秒钟才能运行。使用卷似乎可以将运行时间增加大约1秒。

并行或顺序

在启动脚本中顺序执行命令不会缩短启动时间。它也没有急剧恶化。

IO绑定了吗?

Windows taskmanager指示执行启动脚本时IO为100%。我们的钩子和应用程序代码完全不需要IO。因此,IO负载似乎源自Docker,Kubernetes或Helm。我们试图找到瓶颈,但无法查明原因。

通过虚拟磁盘减少IO

为测试进一步绑定IO的前提,我们在Linux登台环境中将/var/lib/docker与虚拟磁盘进行了交换。使用这种配置启动应用程序并没有明显更快。

1 个答案:

答案 0 :(得分:0)

要将Kubernetes与Docker进行比较,您需要考虑到Kubernetes在最后一步将或多或少地运行相同的Docker命令。在那之前,很多事情正在发生。 身份验证和授权过程,在etcd中创建对象,为Pod安排正确的节点以安排它们并提供存储。 根据图表的大小,Helm本身也会给流程增加开销。

我建议阅读One year using Kubernetes in production: Lessons learned。作者开始解释他们通过切换到Kubernetes所取得的成就以及开销上的差异:

  

成本计算

     

从成本上看,这个故事有两个方面。要运行Kubernetes,需要一个etcd集群以及一个主节点。尽管这些不一定要运行昂贵的组件,但是对于非常小的部署,此开销可能相对昂贵。对于这些类型的部署,最好使用托管解决方案,例如Google的Container Service。

     

对于大型部署,可以轻松节省大量服务器成本。在这些部署中,运行etcd和主节点的开销并不重要。 Kubernetes使在同一主机上运行多个容器变得非常容易,从而最大程度地利用了可用资源。这样可以减少所需服务器的数量,直接为您节省金钱。运行Kubernetes听起来不错,但是运行这样一个集群的操作方面似乎并不那么吸引人,有很多托管服务需要考虑,包括Cloud RTI,这是我的团队正在研究的。