为了更好地提升资源利用率和节省资源成本,容器计算服务 ACS(Container Compute Service)支持通过ack-kubernetes-cronhpa-controller组件来实现资源的定时伸缩CronHPA(Cron Horizontal Pod Autoscaler),从而减少资源浪费。本文介绍如何在ACS集群中实现容器的定时伸缩以及CronHPA兼容HPA的原理。
前提条件
已创建ACS集群。具体操作,请参见创建ACS集群。
已使用kubectl连接Kubernetes集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
背景信息
ack-kubernetes-cronhpa-controller是一个Kubernetes HPA Controller,按照类似Crontab的策略定时地对集群进行扩缩容。您可以将CronHPA使用于 Kubernetes中任何支持scale
子资源的对象(例如Deployment和StatefulSet)。详细信息,请参见kubernetes-cronhpa-controller。
以下示例对CronHPA的各个字段进行解释说明。
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: cronhpa-sample
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment-basic
excludeDates:
# exclude November 15th
- "* * * 15 11 *"
# exclude every Friday
- "* * * * * 5"
jobs:
- name: "scale-down"
schedule: "30 */1 * * * *"
targetSize: 1
- name: "scale-up"
schedule: "0 */1 * * * *"
targetSize: 3
runOnce: false
字段 | 说明 |
scaleTargetRef | scaleTargetRef指定扩缩容对象。如果对象支持Scale子资源,CronHPA即可支持。 |
excludeDates | excludeDates是日期数组。当遇到符合excludeDates描述的日期时任务将会被跳过。 说明 最小单位为天。
如您想在11月15日不运行任务,可像以下示例一样指定excludeDates。
|
jobs | 支持在一个
|
安装CronHPA组件
您可以通过以下方式安装CronHPA组件ack-kubernetes-cronhpa-controller。
登录容器计算服务控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在组件管理页面单击应用管理页签,找到ack-kubernetes-cronhpa-controller,单击安装,然后在弹出的对话框中,单击确认。
如果您无需使用容器定时伸缩功能,可以删除CronHPA组件。关于删除CronHPA组件ack-kubernetes-cronhpa-controller的具体步骤,请参见管理组件。
创建定时伸缩CronHPA任务
为应用创建和运行CronHPA之前,请确保集群中的CronHPA组件已正常运行,且当前应用只有一个HPA对象。关于CronHPA和HPA的兼容策略,请参见下文定时伸缩CronHPA兼容HPA。您可以通过以下两种方式创建CronHPA任务。
方式一:在创建应用时创建CronHPA任务
在创建应用的高级配置页面的伸缩配置区域,选中定时伸缩右侧开启为应用创建定时伸缩任务。关于创建应用的详细步骤,请参见创建无状态工作负载Deployment或者创建有状态工作负载StatefulSet。
ACS管理控制台会自动检查是否已安装CronHPA组件。如果CronHPA组件未被安装,页面提示点击安装。安装CronHPA组件后,页面显示定时伸缩任务的创建配置。配置参数的详细描述如下:
配置项 | 说明 |
定时任务名称 | 为定时任务定义名称。每个任务的名称是唯一的,不能与其他任务名称重复。 |
目标副本数 | 当到达设定计划时间时,应用副本数自动伸缩至该值。 |
调度周期 | 设置调度周期。 关于为定时伸缩任务设置调度周期的详细描述,请参见predefined-schedules。 |
方式二:为已有应用创建CronHPA任务
以下步骤以无状态应用为例,说明如何为已有应用创建CronHPA任务。
登录容器计算服务控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在无状态页面,单击应用右侧操作列下的详情。
单击容器伸缩页签,配置定时伸缩任务。
如果CronHPA组件未被安装,页面提示点击安装。单击点击安装后,进行以下步骤。
如果CronHPA组件已经安装,直接进行以下步骤。
单击定时伸缩(CronHPA)右侧的创建,然后在创建对话框中,设置定时伸缩任务的创建参数。
配置项说明如下:
配置项
说明
任务名称
为定时任务定义名称。每个任务的名称是唯一的,不能与其他任务名称重复。
目标副本数
当到达设定的计划时间时,应用副本数自动伸缩至该值。
调度周期
设置调度周期。关于为定时伸缩任务设置调度周期的详细描述,请参见predefined-schedules。
添加或修改定时伸缩任务
请参见上文创建定时伸缩CronHPA任务的步骤进入容器伸缩页面。
在容器伸缩页签的定时伸缩(CronHPA)区域,单击目标任务右侧操作下的任务添加或编辑。
在编辑对话框中,单击添加任务进行任务创建或者单击已有CronHPA任务进行修改,然后单击确定。
说明您可以通过下图所示的操作删除CronHPA任务。在编辑对话框中,单击任务名称右上角的删除图标,然后单击确定。
CronHPA和HPA的定义模板
CronHPA
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: cronhpa-sample
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment-basic
jobs:
- name: "scale-down"
schedule: "30 */1 * * * *"
targetSize: 1
- name: "scale-up"
schedule: "0 */1 * * * *"
targetSize: 11
HPA
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment-basic
minReplicas: 4
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
定时伸缩CronHPA兼容HPA
定时伸缩CronHPA和HPA作用的对象都是工作负载(例如Deployment或者StatefulSet等),在同一个工作负载上同时配置可能会导致冲突。为了解决这一问题,CronHPA支持将HPA作为其扩缩容的对象,以兼容HPA原有的功能。
对比CronHPA和HPA的定义模板,可以看出:
CronHPA和HPA都是通过
spec.scaleTargetRef
字段来获取伸缩对象。CronHPA通过
spec.jobs
的crontab规则定时伸缩副本数。HPA通过资源利用率判断伸缩的情况。
设想如果同时设置CronHPA和HPA,那么会出现CronHPA和HPA同时操作同一个scaleTargetRef的场景。因为CronHPA和HPA相互独立无法感知,所以就会出现两个Controller各自工作,后执行的操作会覆盖先执行的操作。
CronHPA和HPA的兼容解决方案
从上文可知,当CronHPA感知到HPA的当前状态就能解决冲突问题。为了让CronHPA能感知HPA的当前状态,ACS将CronHPA中的scaleTargetRef
设置为HPA对象本身而不是最终的工作负载对象。CronHPA在执行扩缩容操作时会先通过HPA对象来寻找真实的scaleTargetRef
,进而根据这个状态对工作负载对象进行相应调整,有效防止相互覆盖的情况发生,保证扩缩容操作的一致性和可预期性。
CronHPA兼容HPA的定义模板如下。
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: cronhpa-sample
spec:
scaleTargetRef:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
name: nginx-deployment-basic-hpa
jobs:
- name: "scale-down"
schedule: "30 */1 * * * *"
targetSize: 1
runOnce: false
- name: "scale-up"
schedule: "0 */1 * * * *"
targetSize: 3
runOnce: false
通过上述CronHPA的定义,CronHPA可以明确知晓HPA中的spec.minReplicas
、spec.maxReplicas
和status.desiredReplicas
的数值,但是同时也知晓HPA中spec.scaleTargetRef
所对应的当前Replicas值。CronHPA会通过调整HPA的方式感知HPA。CronHPA通过识别要达到的副本数与当前副本数两者间的较大值,判断是否需要扩缩容或修改HPA的上限;CronHPA通过识别CronHPA要达到的副本数与HPA的配置间的较小值,判断是否需要修改HPA的下限。
以下根据不同的场景,解释CronHPA兼容HPA的规则。
HPA(min/max) | CronHPA | Deployment | 扩缩容结果 | 兼容规则说明 |
1/10 | 5 | 5 |
| 当CronHPA中的目标副本数和当前副本数一致时,HPA中的最大和最小副本数,以及应用当前的副本数无需变更。 |
1/10 | 4 | 5 |
| 当CronHPA中的目标副本数低于当前副本数时,保留当前副本数。 |
1/10 | 6 | 5 |
|
|
5/10 | 4 | 5 |
|
|
5/10 | 11 | 5 |
|
|
表格中参数说明如下:
HPA(min/max):表示HPA定义中最小和最大的副本数值。
CronHPA:表示CronHPA设定的副本数。
Deployment:表示应该用扩缩前的副本数。
从上述看出,CronHPA不会直接调整Deployment的副本数目,而是通过HPA来操作Deployment,这样可以避免HPA和CronHPA的冲突问题。