NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 305% / 50% 1 10 7 3m
这时,由于请求增多,CPU利用率已经升至请求值的305%。可以看到,Deployment的副本数量已经增长到了7:
kubectl get deployment php-apache
你应该会看到与HorizontalPodAutoscaler中的数字与副本数匹配
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 7/7 7 7 19m
说明:有时最终副本的数量可能需要几分钟才能稳定下来。由于环境的差异,不同环境中最终的副本数量可能与本示例中的数量不同。
停止产生负载
要完成该示例,请停止发送负载。
在我们创建busybox容器的终端中,输入+C来终止负载的产生。
然后验证结果状态(大约一分钟后):
# 准备好后按 Ctrl+C 结束观察
kubectl get hpa php-apache --watch
输出类似于:
NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 11m
Deployment也显示它已经缩小了:
kubectl get deployment php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 1/1 1 1 27m
一旦CPU利用率降至0,HPA会自动将副本数缩减为1。
自动扩缩完成副本数量的改变可能需要几分钟的时间。
基于多项度量指标和自定义度量指标自动扩缩
利用autoscaling/v2API版本,你可以在自动扩缩php-apache这个Deployment时使用其他度量指标。
首先,将HorizontalPodAutoscaler的YAML文件改为autoscaling/v2格式:
kubectl get hpa php-apache -o yaml > /tmp/hpa-v2.yaml
在编辑器中打开/tmp/hpa-v2.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
status:
observedGeneration: 1
lastScaleTime:
currentReplicas: 1
desiredReplicas: 1
currentMetrics:
- type: Resource
resource:
name: cpu
current:
averageUtilization: 0
averageValue: 0
需要注意的是,targetCPUUtilizationPercentage字段已经被名为metrics的数组所取代。CPU利用率这个度量指标是一个resourcemetric(资源度量指标),因为它表示容器上指定资源的百分比。除CPU外,你还可以指定其他资源度量指标。默认情况下,目前唯一支持的其他资源度量指标为内存。只要metrics.k8s.ioAPI存在,这些资源度量指标就是可用的,并且他们不会在不同的Kubernetes集群中改变名称。
你还可以指定资源度量指标使用绝对数值,而不是百分比,你需要将target.type从Utilization替换成AverageValue,同时设置target.averageValue而非target.averageUtilization的值。
还有两种其他类型的度量指标,他们被认为是custommetrics(自定义度量指标):即Pod度量指标和Object度量指标。这些度量指标可能具有特定于集群的名称,并且需要更高级的集群监控设置。
第一种可选的度量指标类型是Pod度量指标。这些指标从某一方面描述了Pod,在不同Pod之间进行平均,并通过与一个目标值比对来确定副本的数量。它们的工作方式与资源度量指标非常相像,只是它们仅支持target类型为AverageValue。
pod度量指标通过如下代码块定义:
type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
第二种可选的度量指标类型是对象(Object)度量指标。这些度量指标用于描述在相同名字空间中的别的对象,而非Pods。请注意这些度量指标不一定来自某对象,它们仅用于描述这些对象。对象度量指标支持的target类型包括Value和AverageValue。如果是Value类型,target值将直接与API返回的度量指标比较,而对于AverageValue类型,API返回的度量值将按照Pod数量拆分,然后再与target值比较。下面的YAML文件展示了一个表示requests-per-second的度量指标。
type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
target:
type: Value
value: 2k
如果你指定了多个上述类型的度量指标,HorizontalPodAutoscaler将会依次考量各个指标。HorizontalPodAutoscaler将会计算每一个指标所提议的副本数量,然后最终选择一个最高值。
比如,如果你的监控系统能够提供网络流量数据,你可以通过kubectledit命令将上述HorizontalPodAutoscaler的定义更改为:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
target:
type: Value
value: 10k
status:
observedGeneration: 1
lastScaleTime:
currentReplicas: 1
desiredReplicas: 1
currentMetrics:
- type: Resource
resource:
name: cpu
current:
averageUtilization: 0
averageValue: 0
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
current:
value: 10k
这样,你的HorizontalPodAutoscaler将会尝试确保每个Pod的CPU利用率在50%以内,每秒能够服务1000个数据包请求,并确保所有在Ingress后的Pod每秒能够服务的请求总数达到10000个。
基于更特别的度量值来扩缩
许多度量流水线允许你通过名称或附加的标签来描述度量指标。对于所有非资源类型度量指标(Pod、Object和后面将介绍的External),可以额外指定一个标签选择算符。例如,如果你希望收集包含verb标签的http_requests度量指标,可以按如下所示设置度量指标块,使得扩缩操作仅针对GET请求执行:
type: Object
object:
metric:
name: http_requests
selector: {matchLabels: {verb: GET}}
这个选择算符使用与Kubernetes标签选择算符相同的语法。如果名称和标签选择算符匹配到多个系列,监测管道会决定如何将多个系列合并成单个值。选择算符是可以累加的,它不会选择目标以外的对象(类型为Pods的目标Pods或者类型为Object的目标对象)。
基于与Kubernetes对象无关的度量指标执行扩缩
运行在Kubernetes上的应用程序可能需要基于与Kubernetes集群中的任何对象没有明显关系的度量指标进行自动扩缩,例如那些描述与任何Kubernetes名字空间中的服务都无直接关联的度量指标。在Kubernetes1.10及之后版本中,你可以使用外部度量指标(externalmetrics)。
使用外部度量指标时,需要了解你所使用的监控系统,相关的设置与使用自定义指标时类似。外部度量指标使得你可以使用你的监控系统的任何指标来自动扩缩你的集群。你需要在metric块中提供name和selector,同时将类型由Object改为External。如果metricSelector匹配到多个度量指标,HorizontalPodAutoscaler将会把它们加和。外部度量指标同时支持Value和AverageValue类型,这与Object类型的度量指标相同。
例如,如果你的应用程序处理来自主机上消息队列的任务,为了让每30个任务有1个工作者实例,你可以将下面的内容添加到HorizontalPodAutoscaler的配置中。
- type: External
external:
metric:
name: queue_messages_ready
selector:
matchLabels:
queue: "worker_tasks"
target:
type: AverageValue
averageValue: 30
如果可能,还是推荐定制度量指标而不是外部度量指标,因为这便于让系统管理员加固定制度量指标API。而外部度量指标API可以允许访问所有的度量指标。当暴露这些服务时,系统管理员需要仔细考虑这个问题。
附录:HorizontalPodAutoscaler状态条件
使用autoscaling/v2格式的HorizontalPodAutoscaler时,你将可以看到Kubernetes为HorizongtalPodAutoscaler设置的状态条件(StatusConditions)。这些状态条件可以显示当前HorizontalPodAutoscaler是否能够执行扩缩以及是否受到一定的限制。
status.conditions字段展示了这些状态条件。可以通过kubectldescribehpa命令查看当前影响HorizontalPodAutoscaler的各种状态条件信息:
kubectl describe hpa cm-test
Name: cm-test
Namespace: prom
Labels:
Annotations:
CreationTimestamp: Fri, 16 Jun 2017 18:09:22 +0000
Reference: ReplicationController/cm-test
Metrics: ( current / target )
"http_requests" on pods: 66m / 500m
Min replicas: 1
Max replicas: 4
ReplicationController pods: 1 current / 1 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale the last scale time was sufficiently old as to warrant a new scale
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from pods metric http_requests
ScalingLimited False DesiredWithinRange the desired replica count is within the acceptable range
Events:
对于上面展示的这个HorizontalPodAutoscaler,我们可以看出有若干状态条件处于健康状态。首先,AbleToScale表明HPA是否可以获取和更新扩缩信息,以及是否存在阻止扩缩的各种回退条件。其次,ScalingActive表明HPA是否被启用(即目标的副本数量不为零)以及是否能够完成扩缩计算。当这一状态为False时,通常表明获取度量指标存在问题。最后一个条件ScalingLimitted表明所需扩缩的值被HorizontalPodAutoscaler所定义的最大或者最小值所限制(即已经达到最大或者最小扩缩值)。这通常表明你可能需要调整HorizontalPodAutoscaler所定义的最大或者最小副本数量的限制了。
量纲
HorizontalPodAutoscaler和度量指标API中的所有的度量指标使用Kubernetes中称为量纲(Quantity)的特殊整数表示。例如,数量10500m用十进制表示为10.5。如果可能的话,度量指标API将返回没有后缀的整数,否则返回以千分单位的数量。这意味着你可能会看到你的度量指标在1和1500m(也就是在十进制记数法中的1和1.5)之间波动。
其他可能的情况 以声明式方式创建Autoscaler
除了使用kubectlautoscale命令,也可以使用以下清单以声明方式创建HorizontalPodAutoscaler:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
使用如下命令创建autoscaler:
kubectl create -f https://k8s.io/examples/application/hpa/php-apache.yaml
horizontalpodautoscaler.autoscaling/php-apache created