关于Kubernetes和GKE的一个损失巨大的错误
不幸的是,标题并没有夸张。作为免责声明,我首先要补充一点,这是一个非常愚蠢的错误,显示了我在管理自动伸缩部署方面缺乏经验。然而,这一切都始于一个没有答案的问题,我觉得有义务分享我的经验来帮助其他人避免类似的陷阱。
使用100x n1-standard-1(1 vCPU)VMs的Kubernetes集群与使用1x n1-standard-96(vCPU 96)或使用6x n1-standard-16 VMs(vCPU 16)的Kubernetes集群有什么区别?
这个问题我在Kubernetes社区问过很多次,没有人给出建设性的答案。如果你对答案不确定,那么你可以从我的经验中学到一些东西(如果没有耐心可以直接跳到答案部分)。
前提(序)
某一天,我半夜醒来,决定降低我们的基础设施成本。
我们正在运行一个大型Kubernetes集群。当然,“大”是相对的。在我们的例子中,正常工作时间是600个vCPU。这个数字在高峰时间翻倍,在晚上的某些时候接近于0。
上个月的发票是3500美元。
考虑到我们所获得的计算能力,这已经相当不错了,但是谷歌Kubernetes引擎(GKE)使成本管理变得非常简单:
-
我们使用最便宜的数据中心【europe-west2(London)就比europe-west4(Netherlands)贵15%】
-
我们为不同的部署使用不同的机器类型(偏重内存vs偏重CPU)
-
我们使用水平Pod自动调度器(HPA)和自定义指标来扩展部署
-
我们使用cluster-autoscaler来扩展节点池
-
我们使用可抢占的VM
使用专门可抢占的VM使我们能够保持低成本。为了说明节省的费用,对于在europe-west4中托管的n1-standard-1机器类型,专属VM和可抢占VM之间的差异是26.73美元/月和8.03美元/月,这样成本就降低了3.25倍。当然,可抢占的VM有其局限性,你需要熟悉和克服这些局限性,但这是一个完全不同的主题。
有了以上所有的条件,我觉得我们正在做所有正确的事情来保持低成本。然而,我总是有一种挥之不去的感觉,觉得事情不对劲,不吐不快。
主要的红色标志
关于那种烦人的情况:
每个节点的平均CPU使用量很低(10%-20%),这似乎是不对的。
我的第一个想法是我错误地配置了计算资源。所需的资源完全取决于正在运行的程序。因此,最好的方法是在没有资源限制的情况下部署程序,观察程序在空闲/常规负载和峰值负载期间的行为,并根据观察到的值设置请求/限制资源。
我将通过单个部署“admdesl”的示例来说明我的错误。
我们的使用情况是,所需资源是零星分布的:
其中,平均5m的Pod是“空闲”的:队列中有一个任务等待它们处理,但是我们正在等待某些(外部)条件清除后再继续。在这种特殊的部署情况下,这些Pod每分钟将在空闲/活动状态之间多次改变,并在空闲状态中花费70%以上的时间。
一分钟后,相同的Pod看起来就不一样了:
看到上面的内容,我认为有一个配置是有意义的,比如:
这意味着:
-
闲置的Pod消耗不超过20m
-
活跃(健康)的Pod在200m时达到峰值
然而,当我使用这个配置时,它使部署变得繁忙了。
每当一个新节点被加入/移出集群时都会发生这种情况(由于自动伸缩而经常发生这种情况)。
因此,我不断增加请求的Pod资源,直到我完成以下配置:
通过这种配置,集群可以顺利地运行,但这意味着即使是空闲的Pod也会预先分配比它们所需的更多的CPU时间。这就是每个节点的平均CPU使用量较低的原因。但是,我不知道解决方案是什么(减少请求的资源会导致繁忙的集群状态/中断),因此我为所有部署提供了一种慷慨的资源分配变体。
答案
回到我的问题:
使用100x n1-standard-1(1 vCPU)VMs的Kubernetes集群与使用1x n1-standard-96(vCPU 96)或使用6x n1-standard-16 VMs(vCPU 16)的Kubernetes集群有什么区别?
对于初学者来说,n1-standard-1和n1-standard-96之间没有单个vCPU的价格差异。因此,我认为使用具有较少vCPU的机器将使我能够更好地控制价格。
我考虑的另一个问题是集群自动伸缩的速度有多快,也就是说,如果突然出现激增,集群自动伸缩器为计划外的Pod提供新节点的速度有多快。不过,这并不是我们所关心的问题——我们对资源的需求是逐渐增加和减少的。
所以我用了1个vCPU节点,结果我在前提中已经描述过了。
回顾过去,这是一个明显的错误:使用单个vCPU在节点上分布Pod,在空闲和活动状态之间的单个部署更改时,不允许有效地利用资源。换句话说,在同一台机器上的vCPU越多,就可以将许多Pod打包得越紧,因为当一部分Pod超出了它们所需的配额时,就有现成的资源可供使用。
有效的工作是:
-
我切换到16-vCPU机器,因为它们提供了一种平衡的解决方案,可以在自动扩展集群时进行良好的资源控制,也可以在每台机器上提供足够的资源来实现对处于空闲/活动状态的Pod的严格调度。
-
我使用的资源配置请求仅比空闲状态所需的资源多一点点,但是有很大的限制。当大多数Pod处于空闲状态时,它允许在同一台机器上调度多个Pod,但仍然允许资源密集型突发事件。
-
我切换到n2机器类型:n2机器更贵,但是它们有2.8 GHz的基频(与n1-*机器可用的~2.2 GHz相比)。我们正在利用更高的时钟频率来尽可能快地处理资源密集型任务,并将Pod尽可能快地置于前面描述的空闲状态。
当前节点vCPU的平均使用率高达60%。这听起来是对的,需要一些时间才能得出节省了多少。然而,惊喜的是,今天我们使用的vCPU还不到昨天的一半。
原文链接:https://medium.com/@gajus/mistake-that-cost-thousands-kubernetes-gke-2212ea663e1f
基于Kubernetes的DevOps实战培训
基于Kubernetes的DevOps实战培训将于2019年12月27日在上海开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习 。本次培训包括:容器特性、镜像、网络;Kubernetes架构、核心组件、基本功能;Kubernetes设计理念、架构设计、基本功能、常用对象、设计原则;Kubernetes的数据库、运行时、网络、插件已经落地经验;微服务架构、组件、监控方案等,点击下方图片或者阅读原文链接查看详情。