cloudops spot之ocean产品调研
背景
今天分享的是netapp旗下的商业化公司spot的产品ocean,他们专注于优化用户的cloudops,利用公有云本身的技术红利,帮助用户更好的使用云来降本增效。spot旗下的产品比较多,我们会重点关注几个和公共云弹性资源相关的产品,看看他们是如何利用弹性的云资源来做到降本增效的。
ocean介绍
ocean本质就是帮助用户管理k8s上的容器,主要也是通过优化计算资源的使用来达到节约成本。可以理解为k8s上的elastigroup+spot storage,只不过是围绕pod展开的,是container-driven auto scaling。
基本架构
- ocean controller: 每个node上搜集metric,汇报给ocean saas
- Ocean SaaS:应该也是会部署到k8s上的服务,本质是个决策中心,用于接受ocean controller汇报的metric。注意这里的ocean controller是高可用的,是属于ocean最核心的设施。
特性与概念
pod-driven scaling主要会去达成以下目标:
- 重新调度由于资源不足问题而调度失败的pod
- 确保频繁的pod scalling不需要等待实例启动
- 确保集群资源是充分利用的
spot ocean vs metric-based node autoscaling
一定要区分清楚是node还是pod层面的scaling。node based autoscaling不感知pod。metric-based node autoscaling会新增一个Node,但是上面没有任何pod运行,或者删除那些有重要pod运行的node。
scale up
ocean会监控podcondition,当podcondition为false并且reson为unscheduleable的时候,就可以触发scale up。
笔者补充:这个属于事后处理了,在对可用性要求高的场景其实不是最好的,即使文章提到了通过cluster headroom来加速这个schedule
affinity and anti-affinity
通过亲和性和反亲和性设置来做pod和node之间的绑定,例如让pod在多可用区均衡分布
scale down
本质是个bin-packing问题,通过调度pod到有剩余空间的node上,drain多余的node,然后保证整体的资源利用率最优。
scale down的流程
设计的PDB概念参考k8s文档。
阻止scale down
一些情况下可能需要避免一些node由于scale down而被缩减。ocean完成这个功能主要是通过标签控制:
- spotinst.io/restrict-scale-down:true: 可以在pod level进行配置,有这个pod运行的Node禁止参与scale down
- cluster-autoscaler.kubernetes.io/safe-to-evict: 表示可以正常evict然后remove node(参与scale down的也要显式标识)
此外也可以直接全局禁用scale down的能力:
virtual node group(vng)
将一组node可以通过设置标签定义成一个node group。一个vng本质是约定了这些node的启动配置,比如不同的操作系统等。
vng的常用应用场景:
- node需要不同的初始化镜像配置需求
- pod需要匹配不同specification的node,可以关联vng来达到
pod调度会根据vng label情况来调度,大致流程如下。其中内置或者默认的default vng由ocean提供,也是生成其他vng的模板,像eks大概会包含如下内容:
headroom
通过预留容量buffer,可以确保缩容时drain node可以快速完成。扩缩容的时候都要保证headroom值的维持。headroom可以配合vng使用,每个vng可以单独设置headroom
Pod topology spread constraints
pod拓扑分布约束和亲和性、反亲和性的功能比较接近。亲和性更加强调一定要绑定或者不能绑定到某些node,其实我们很多时候使用亲和性、反亲和性都是按照某种策略,实际想达到的是限制pod拓扑分布,这种应用场景在k8s 1.18以后,优先使用pod拓扑分布约束即可。
ocean使用拓扑分布约束要求每个拓扑域必须有一个node,这样才可以保证分配到某个拓扑域运行时一定可以运行成功,这个通过headroom即可配置。
k8s扩展资源的支持
k8s扩展资源允许用户定义node level的自定义资源,例如GPU或者其他资源类型。
resource limit
需要设置一个scale up的上限,无限制scale up可能耗尽用户的钱包。。。
自定义scalling配置
主要是对调整的粒度、headroom的预留的一些配置
cluster orientation(集群定位)
可以理解不同的集群定位,约定了这个集群上的一组配置。ocean分了三种。之所以分三种本质应该还是ocean自己也无法确定最优的配置到底是什么,默认提供的balanced不一定是最优的,用户也可以自己尝试更加激进的策略。
- balanced(default): 在可用性和成本上保持平衡
- cost: 以ocean认为的cost-effective方式来工作,比blanced会激进点。如果理论上产品scale做的非常好,非常有信心其实可以只提供cost的模式
- cheapest: 这个基本上就是为了成本服务,策略更加激进,例如spot实例选择就专门挑最便宜的,但是score不一定高
为无法scale down的node转向更低代价的node
有些情况无法scale down node,例如一些反亲和性的规则要求pod必须处在某个node,即使这个node利用率很低,或者由于headroom预留的需求,必须保留node,这种情况下ocean会尝试用更加廉价的node来做替换,来达到节约成本的目的。
healthcheck和auto-healing
ocean每间隔30秒回探测node的健康情况,包括:
- OutOfDisk
- Ready
- MemoryPressure
- DiskPressure
- NetworkUnavailable
返回的是个结果性的status,可选值是false、true、unknown。如果不健康了会触发replace
标签和污点
k8s高效调度pod会采用以下几种方式:
- Node Selector – Constrains pods to nodes with particular labels.
- Node Affinity – Constrains which nodes your pod is eligible to be scheduled on based on labels on the node. Spot supports hard and soft affinity (requiredDuringSchedulingIgnoredDuringExecution, preferredDuringSchedulingIgnoredDuringExecution).
- Pod Affinity and Pod Anti-Affinity – Schedules a Pod based on which other Pods are or are not running on a node.
- Pod Port Restrictions – Validates that each pod will have required ports available on the machine.
- Well-Known Labels.
cost analysis
ocean也提供了成本分析的系统,帮你分析k8s上所有资源的成本消耗。具体的计算逻辑可以参考ocean官方文档
elastic ip
有些情况需要将应用关联弹性IP,这个ocean也有支持。核心原理是设置一个EIP池的lauch specification。启动的时候instance会自动关联EIP。scale up/down的时候ocean会自动处理这些specification以及EIP
roll
这个可以理解是滚动发布了。做更改后可以定义一些滚动发布的规则。
right sizing
基本原理就是通过controller监控metric,然后按照workload执行动作。大致流程为:
- ocean controller每过5分钟,查询pod资源利用率(通过prometheus exporter),包括max和mean(这里我们以最大内存利用率和平均内存利用率为例)
- ocean会根据max,mean metric提供两种建议:
- 降低pod request: 比较最大资源利用率和request的资源。如果request的资源明显大于最大资源利用率,会尝试降低reuqest的值
- 提高pod request: 根据pod平均资源利用率metric和request的值比较,如果平均利用率明显高于request,则考虑scale up request值
right sizing主要是根据recommendation生成deployments、statefulset和daemonsets对象
shutdown hours
针对不需要7*24小时服务的集群,可以设置定时关闭