部署 省钱之旅路漫漫, 论我在阿里云 k8s 的一次实践

jicheng1014 · 2021年09月11日 · 最后由 wikimo 回复于 2021年09月18日 · 740 次阅读

前置说明

如果你的业务在快速增长, 且你的技术栈比较单一(比如就只有 rails 和 前端 nginx), 请你直接忽略掉这篇文章 本文主要对象为: 业务较为稳定, 捉摸着省钱的, 开发任务不重的团队。 至于技术栈, 无所谓复杂不复杂

我花了两周的时间,才摸到了 k8s 的基本规则, 并理论验证了阿里云 k8s 在高可用的情况下做到省钱。 把我的痛苦经历写出来, 希望能对想碰这块的朋友做出一点贡献。

为啥想起来研究 k8s

想省钱。利用 k8s 的弹性扩容: 在低峰期开固定的资源, 之后在高峰期再怼临时资源, 高峰回落, 关闭多余资源。

虽然很多运维使用 k8s 的原因是因为他能隔离环境, 以及比较轻松就能实现的滚动更新, 但是对于我这种 单一技术栈 rails 的人来说, 意义反而不大。

依次遇到的困难

  1. k8s 知识的复杂度 这是最大的困难,概念太多。 我并非运维出生, 很多概念太多太复杂, 这里仅仅指出以下名词,这是我觉得必须要知道的

master worker node pod service ingress-controller

  1. 搭建 k8s 上我的选择

最开始的想法是自建 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 我主要研究了两种

  • ack 即 阿里云官方提供 master,我们提供 ECS 当 worker 节点即可。
  • ask 即 阿里云官方提供 master,以及虚拟的 worker 节点, 我们启动的 POD 会跑在一个叫做 ECI 的东西上, 而 ECI 就是个容器。
  1. 阿里云 托管 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 省钱省在哪里:

  1. 原来常驻的两台 4C8G 的 puma, 被 2 台 2C4G + 偶尔启动的 0.5C1G 的 ECI 代替了
  2. 原来的 跑 sidekiq 的主力机型 4C8G, 被偶尔启动的 ECI 以及 前面两台 2C4G 的机器跑完 puma 剩余的性能,代替了

但是 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 后, 最后觉得还是值了, 毕竟技多不压身, 祝各位坛友学富五车

云服务商推 k8s 的一个原因是赚钱吧,如果是买云主机,购买前得看着价格再三确认,如果是 k8s 改个配置就开了一堆计算单元,账单月底见。

另外 k8s 那个复杂度并不适合开发人员管理,面向开发者理想环境的应该是 heroku 或者 DigitalOcean app platform 那样的。国内目前只看见 ucloud 的 cube 有点像,但是它如何更新镜像文档写得不清楚。

投入 docker 我觉得是值得,解决了开发和生产环境依赖一致性和更新的问题。如果是部署在云主机,我相信很少人去更新系统依赖,除非不得已有安全漏洞。

因为 k8s 又贵又难用,我目前一个应用是单机用 docker swarm 部署,装多几台加入 swarm 也很简单。

Rei 回复

目前来看 阿里的 ACK 版本, 成本还是在可控范围内, 毕竟本质上还是跑在 ECS 下, 主要成本是 ECS, 额外开的 ECI 只跑弹性业务即可。

之前跟坛友吹牛, 坛友也是说 k8s 就是个 kpi 神器。

目前我的结论是 想纯粹从省钱的角度上来讲, 业务机器如果在 4 台以下, 哪怕不算运维人员成本, k8s 也需要非常精打细算才能省钱

jicheng1014 回复

你的经历和我差不多。

我之前的一个核心业务切换到 k8s。差不多折磨了 1 个月(历史原因,数据库跨可用区迁移)。

业务机器在 4 台一下,确实没必要。我这里是高峰期 4 台扛不住,低谷期 2 台即可。 使用 K8S,比较方便的是弹性伸缩。比如我有个报表计算任务,月初需要大量的计算资源,之前只能手动开服务器处理。现在计算 Pod 会自动伸缩,加速计算,无需人工干预。

K8s 给我带来最大改变,不再关心主机。需要的只是计算资源。计算资源逻辑化,比如我所有的 Rails 服务,都在一个集群中,只要限制单个 Pod 的资源,同时加上自动伸缩,必要时定时伸缩。

当然 K8s 并不适合 所有 Rails 服务,比如 日 PV 在 200 万一下,业务机器 <16 核。

自动扩容不怕被 D 吗?

账单哗啦哗啦的。。。

pynix 回复

可以设置最大值 另外 不要暴露 ip 该 cdn 就 cdn

k8s 还是适合有大规模的微服务需要管理的场景。

a112121788 回复

那日 PV200w 以下,< 16 核,一般如何部署,单机或者多台机器如何管理,通过脚本批量操作? 如何实现业务伸缩,使用阿里云自带伸缩服务?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号