kubernetes1.1.1中的自动扩容特性
最新一版的kubernetes release中我们看到了一个令人欣喜的特性:Autoscaling。它实现了replicationcontroller中pod的横向自动扩容。以下是摘自官方文档的相关内容:
自动扩容将通过一个新的resource(就像之前的pod,service等等)实现。目前只支持针对cpu使用度进行动态扩容。未来的版本中,将会实现基于另一个resource:metrics(这是说未来监控数据将会有一个更统一的展示?)
主要结构
1.Scale subresource
Scale subresource是一个虚拟的resource,用来记录扩容进度。其主要结构如下:
// represents a scaling request for a resource.type Scale struct { unversioned.TypeMeta api.ObjectMeta // defines the behavior of the scale. Spec ScaleSpec // current status of the scale. Status ScaleStatus}// describes the attributes of a scale subresourcetype ScaleSpec struct { // desired number of instances for the scaled object. Replicas int `json:"replicas,omitempty"`}// represents the current status of a scale subresource.type ScaleStatus struct { // actual number of observed instances of the scaled object. Replicas int `json:"replicas"` // label query over pods that should match the replicas count. Selector map[string]string `json:"selector,omitempty"`}
其中ScaleSpec.Replicas表示我们预定的集群实例数目标。ScaleStatus.Replicas表示当前实例数,ScaleStatus.Selector是一个选择器,选择对应的pods。
2.HorizontalPodAutoscaler
这个就是真正控制扩容的resource,其结构如下:
// configuration of a horizontal pod autoscaler.type HorizontalPodAutoscaler struct { unversioned.TypeMeta api.ObjectMeta // behavior of autoscaler. Spec HorizontalPodAutoscalerSpec // current information about the autoscaler. Status HorizontalPodAutoscalerStatus}// specification of a horizontal pod autoscaler.type HorizontalPodAutoscalerSpec struct { // reference to Scale subresource; horizontal pod autoscaler will learn the current resource // consumption from its status,and will set the desired number of pods by modifying its spec. ScaleRef SubresourceReference // lower limit for the number of pods that can be set by the autoscaler, default 1. MinReplicas *int // upper limit for the number of pods that can be set by the autoscaler. // It cannot be smaller than MinReplicas. MaxReplicas int // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; // if not specified it defaults to the target CPU utilization at 80% of the requested resources. CPUUtilization *CPUTargetUtilization}type CPUTargetUtilization struct { // fraction of the requested CPU that should be utilized/used, // e.g. 70 means that 70% of the requested CPU should be in use. TargetPercentage int}// current status of a horizontal pod autoscalertype HorizontalPodAutoscalerStatus struct { // most recent generation observed by this autoscaler. ObservedGeneration *int64 // last time the HorizontalPodAutoscaler scaled the number of pods; // used by the autoscaler to control how often the number of pods is changed. LastScaleTime *unversioned.Time // current number of replicas of pods managed by this autoscaler. CurrentReplicas int // desired number of replicas of pods managed by this autoscaler. DesiredReplicas int // current average CPU utilization over all pods, represented as a percentage of requested CPU, // e.g. 70 means that an average pod is using now 70% of its requested CPU. CurrentCPUUtilizationPercentage *int}
其中的ScaleRef是一个Scale subresource的引用,MinReplicas, MaxReplicas and CPUUtilization定义了自动扩容的配置(允许的最大实例数,最小实例数,以及cpu使用配额)。
3.HorizontalPodAutoscalerList
用于记录一个namespace下的所有HorizontalPodAutoscaler。本质上是一个结构数组。
自动扩容算法
官方文档给出的并不是算法, 而是实现步骤,整个自动扩容的流程是:
1.通过podselector找到要扩容的集群
2.收集集群最近的cpu使用情况(CPU utilization)
3.对比在扩容条件里记录的cpu限额(CPUUtilization)
4.调整实例数(必须要满足不超过最大/最小实例数)
5.每隔30s做一次自动扩容的判断(这个日后应该会成为一个扩容条件的参数)
CPU utilization的计算方法是用cpu usage(最近一分钟的平均值,通过heapster可以直接获取到)除以cpu请求(疑问:这个是是什么意思?)。未来k8s会开放一个api直接获取heapster收集到的监控数据。
真正的算法是:
A.
TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)
ceil()表示取大于或等于某数的最近一个整数
举个栗子:
我们有一个集群实例数是3 pods。cpu限额,即Target是每个pod分配1.1核,当cpu的使用度CurrentPodsCPUUtilization为1.1,1.4,1.3时,要扩容成多少个呢?
ceil((1.1+1.4+1.3)/1.1)= 4
所以扩容成四个实例。
B.
由于启动实例时cpu的使用度会陡增,所以自动扩容会等待一段时间以收集准确的运行时监控数据。每次扩容/缩容后冷却三分钟才能再度进行扩容,而缩容则要等5分钟后。这是因为自动扩容使用保守的方法,尽可能满足pods业务的正常使用,所以扩容的优先级要大于缩容。
C.
当满足:
avg(CurrentPodsConsumption) / Target >1.1 或 <0.9
时才会触发进行扩容/缩容。这也是为了避免出现频繁的扩容缩容。
扩容条件的相对与绝对度量
为了方便使用,建议采用相对(relative)的度量标准(如 90%的cpu资源)而不是绝对的标准(如0.6个cpu核心)来描述扩容条件。否则,当用户修改pods的请求资源时还需要去修改这些绝对值。比如:我们创建一个集群时,podtemplate中的resource里填入了cpu为1,即最多分配一个cpu核心给该pod,如果在扩容条件中采用绝对标准,我们必须填一个小于1的数,否则这个条件根本不会被触发。而当我们要修改分配的资源为0.8个核心时,又必须要修改扩容条件以确保其小于0.8。这就很麻烦了。
kubectl中的支持以及待支持
为了方便使用,在kubectl的cmd命令中加入了 creating/updating/deleting/listing 命令用来操作HorizontalPodAutoscaler
未来可能会加入像kubectl autoscale这样的命令,对一个已经在跑的集群实时进行动态扩容。