如果你的业务在快速增长,且你的技术栈比较单一(比如就只有 rails 和 前端 nginx), 请你直接忽略掉这篇文章 本文主要对象为:业务较为稳定,捉摸着省钱的,开发任务不重的团队。至于技术栈,无所谓复杂不复杂
我花了两周的时间,才摸到了 k8s 的基本规则,并理论验证了阿里云 k8s 在高可用的情况下做到省钱。 把我的痛苦经历写出来,希望能对想碰这块的朋友做出一点贡献。
想省钱。利用 k8s 的弹性扩容:在低峰期开固定的资源,之后在高峰期再怼临时资源,高峰回落,关闭多余资源。
虽然很多运维使用 k8s 的原因是因为他能隔离环境,以及比较轻松就能实现的滚动更新, 但是对于我这种 单一技术栈 rails 的人来说,意义反而不大。
master worker node pod service ingress-controller
最开始的想法是自建 k8s。对于入门 k8s 的人来说,这简直是史诗级灾难,最后发现最简单的方式就是利用 rancher,先用一个 docker 跑起来,之后在 rancher 的指引下,新建一个集群,这种操作只用点鼠标以及拷贝命令执行,集群几乎就是点击就送。
但是,如果自建 k8s,除非你的 k8s 有完善的管理工具可以去开启或关闭你的 worker 节点,否则,k8s 本身的弹性伸缩 pod,对你是没有意义的,因为 pod 是跑在机器上的,pod 减少了,机器没减少,费用并不会减少,这点一定要想清楚。
rancher 这个 k8s 管理工具其实已经实现了 aws 的 EC2 以及 ALIYUN 的 ECS 的伸缩。但是这里有个问题,ECS 启动,是在是慢的抠脚,从 ECS 启动到 k8s 初始化完默认的 pods,最终能在这个 node 上跑自己的 pod,前前后后要 3-5 分钟。这种长时间的等待,是肯定没办法接受的。
另外,自建集群还有一个烦恼:如果你要实现高可用,那 master 就不能只有一台,且 master 是不能当 node 使用的。这就意味着,至少我得出两台 2C2U 的机器做 master 节点。
那么,我就走向了另一种方式,托管式的 k8s,因为我司使用的是 aliyun,所以我这就以阿里云的 托管 k8s 作为解说
阿里云的 k8s 我主要研究了两种
固定支出
咱先说啥都不干的情况下的费用
两个负载均衡:一个作为内网 API SERVER 的负载均衡,即你的 worker 之间的互相通信,这个没办法省。还一个是 ingress 使用的外网的负载均衡,如果你的集群是对外暴露服务,那也没办法省,二者这个还要被收流量费 忽略流量费,两个负载均衡都选最便宜的,总价大概是 0.12 * 24 * 30 = 86.4 流量是 8 毛 1G 咱估算一个月跑 100G 就 160 块
SNAT,用来 worker 节点上上网工作。这个费用是 0.24 每小时 再 加上个 CU 的计算。一个月算下地就是 172 + CU,咱估算成 200。但是,如果你有另外一台机器配了外网 IP,且你知道如何自建 SNAT 的话,这个钱可以省,只不过需要多算下这台机器的成本,比如你预估是 80 块
小破存储日志 可以几乎忽略,咱按 20 算
最终,固定支出是 160 + (200 | 80) + 20 = 380 | 260
工作节点支出
说到了重点,ASK 和 ACK 的重要差别,worker 节点的费用:
从维护性角度上来说,ask 明显更利于 管理,毕竟少了一层 worker 的管理。
但是,同志们,ASK 使用的 ECI 是史诗级的贵,ECI 只有 按量收费 一种模式,其中 CPU 的收费是接近 0.45/小时/1vCPU,内存是接近 0.05 每小时。也就是说,单纯的 1C1G 的 ECI,跑满一个月,收费是 150 元/月。同时我看了 ECS, 如果是包年包月,1C1G 大概是 30 块左右,如果是按量付费,大概是 80 块左右,所以在 1C1G 的情况下 ECI 的收费是 ECS 按量的 2 倍,包年包月的 4 倍
ASK 的模式是 所有的服务都会按照 ECI 来跑。比如我在 k8s 肯定是要跑 PUMA 提供服务的,比如我们现在的服务 www.admqr.com 的 puma 是跑了两台包年包月的 4C8G 的机器上的,那如果我要在 ASK 的 k8s 上跑,哪怕不算 k8s 的固定费用,我想打平 ECS 的成本,则只能开两个 1C2G 的 ECI,且不能有任何弹性扩充。这明显的感觉就是非常之不划算。
所以,阿里这种 ASK 的 k8s,应该重点是想解决土豪玩家解决部署难,运维难的问题,而不是穷玩家解决省钱的问题
那么 ACK 模式吧
ACK 模式的 k8s 是将 ECS 加入到工作节点,看起来似乎是 跟 私有部署 rancher 差不多的弹性扩展方式,然而,阿里云还是考虑到了这个扩容慢的问题,ACK 上,通过增加 virtual-kubelet-autoscaler 应用,就可以实现在 ACK 模式下,直接跑启动起来非常快的 ECI 了
等等,刚不是说 ECI 贵的抠脚么,咋还用?
重点来了,咱可以把常驻的 pod,跑在我们开的 ECS 上呀,而且,咱可以利用 k8s 开了的 SLB 对抗抢占式实例的释放风险,直接开抢占式实例的 ECS 来降低成本!
这里有个小技巧,阿里云在创建 ACK k8s 的时候会默认新建 ecs,此时非常坑的只能选择又贵又坑的实例,但是其实你可以向我一样,选择 加入已有实例,之后再在 ECS 面板上,开通两台抢占式实例,之后限制抢占式实例的最高限价为 按量收费,比如我这里开通的 2c4u 的服务器,目前的价格是 0.07 每小时,运气好的话一个月只要 50 块 最贵估计也不会超过 300
所以,在没有弹性的时候,运气最好的情况两台就是 100 块
virtual-kubelet-autoscaler 的作用就是,当你的 ecs 因为资源问题,没办法再添加新的 pod 的时候,他会帮你开启 pod 所需的能达到你 pod 硬件条件的 ECI,咱只需要这个 ECI 启动时间不超过 6 个小时,就相当于省下了 1C1G 不停运转的钱
最后 我拿 www.admqr.com 来规划下,ack 的使用情况 目前毛驴是使用了 2 台 4C8G 跑 puma ,和 1 个 sidekiq,1 台 4c8g 跑 4 个 sidekiq, 平时他们的 cpu 都不会超过 10% 高峰期出现在 9-11 点 晚 7-10 点 以及 0-1 点的 sidekiq 结算时间
于是乎,puma 我平时跑 0.25 CPU 最大 0.5 个 CPU 1G 的内存 cpu 超过 80,内存 80% 开始扩展 为了高可用,咱闲时就跑 2 个 pods 就好,估计第一个扩展 pod 开启都不需要 ECI。因为 sidekiq 本身不需要做高可用,所以就平时跑一个 0.5 CPU 1G 即可,需要时候再扩展都来得及。
压力时刻 ECI 会开启,根据之前的 pod 的性能约束,其实它最多也只会开启 0.5 1G 的那种 ECI 型号,因为之前咱算了下,高峰时间是 2 + 3 + 1 即 6 个小时。好处是,ECI 是按秒计费,估计实际时间应该在 5 个小时左右。咱按高峰时刻,会启动 2 个 0.5 CPU 1G 内存的机器,即 1C2G 的费用*6 个小时
综上所述,类似 www.admqr.com 这种项目跑在 k8s,
最终使用 ACK 的 worker 的估算成本,就是
100 + 1C2G 的小时费用* 6 小时 30 即 100 + (0.45 + 0.1) 30 = 100 ECS+ 16 弹性 ECI = 116 块
最终,咱再加上 K8S 在阿里的固定支出 300 左右(260 ~ 380), 最终 k8s 的全部支出估计在 500 左右
我们再回过头来看看 ACK 与现在 传统的 ECS 省钱省在哪里:
但是 k8s 多出了固定支出 SNAT + 2 个负载均衡。严格意义上来说,只是多了一个负载均衡,因为本质上,ecs 这种传统模式,最终还是要接一个负载均衡才能规避单点风险,另外 SNAT 收费这块,我真没经验到底会跑出多少钱,作为省钱小能手,我一般选择开一台机器做手动 SNAT
那么传统的,费用是多少呢?
三台 4c8g 虽然我们开的是包年包月,但是按照最省钱的方式的话,可以以抢占模式开通性能突发性能型,之后开启突破性能积分 目前华南 C 区是 0.18 / 小时 算下地就是 130, 再加上性能突破,咱按 150 算,即 3 台是 450 块,再加上一个 SLB,差不多就是 500 多了呗
当然这么便宜是有风险的,抢占式服务器,会有 3% 的几率释放,如果要完全避免这种风险,就可以用的倒霉的 包年包月计算型,ecs 的费用差不多就是 1200 元最后估计 1300
在想做到极致成本控制的情况下,其实 能弹性伸缩的 ACK 以最省钱的模式运行 和 传统的 ECS 以抢占式实例 + 性能突发 + 性能突破,最后的费用是差不多的。如果你之前是搞了 抢占式 + 性能突发,说实在话,单纯为了省钱折腾 k8s,没有太大意义。如果是其他方式运行的 ecs,则 k8s 能省点钱,但是需要你付出极大的运维代价(我被 k8s 折磨的死去火来的两个星期,现在天快亮了我还在含泪发帖),之后你还能收货常见的部署统一,滚动发布,进一步健壮系统的 k8s 带来的好处。
k8s 就算在坑爹的硬件条件下,还是可以保持了高可用,哪怕节点被回收,只要不是同时回收两个节点,系统都可以自行恢复。量突然增大,只要前面的 SLB 不倒,系统也可以做到自动扩展。
ecs 在 slb 的加持下可以做到某个 ecs 挂了还能残血支撑,但是性能就没办法自动恢复,需要人工参与,流量增大因为没弹性,就一点办法没有了。
k8s 真是太复杂了,经过大量折腾,最后得出这个结论,一度让我觉得我浪费了 2 周的时间。然而在跟 ruby-china 的朋友在群里吹牛 k8s 后,最后觉得还是值了,毕竟技多不压身,祝各位坛友学富五车