目录

kubernetes监控-基于自定义指标的HPA(一)

初步认识 Kubernetes HPA 可控弹性伸缩的功能.

认识 HPA

官方HPA相关文档:这里

HPA 结构

我们用一份 demo yaml 来介绍一下 HPA 的结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# apiVersion 各个版本的 kubernetes 并不相同,具体参考官网
apiVersion: autoscaling/v2beta2 
kind: HorizontalPodAutoscaler
metadata:
# HPA 的名称
  name: php-apache
spec:
# 指定作用的资源对象
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  # 副本数
  minReplicas: 1
  maxReplicas: 10
  metrics:
  # type 分三种类型
  - type: Resource
    resource:
      # 资源指标名称
      name: cpu
      target:
      # type 也分三种类型
        type: Utilization
        # 阈值
        averageUtilization: 50

资源度量指标

spec.metrics.type.resource.type 也称为:资源度量指标(resource metric)

三种类型:

  • 平均值(AverageValue):取所有 pod 的平均值

  • 平均使用率(Utilization):取所有 pod 的平均使用率

  • 裸值(Value):原始指标,是所有 pod 的指标总和

度量指标类型

spec.metrics.type 也称为:度量指标类型

上面的 demo ,度量指标类型是 Resource 度量指标

还有两种其他类型的度量指标,他们被认为是 custom metrics(自定义度量指标):

Pod 度量指标Object 度量指标

这些度量指标可能具有特定于集群的名称,并且需要更高级的集群监控设置。

Pod 度量指标

第一种可选的度量指标类型是 Pod 度量指标

这些指标从某一方面描述了 Pod, 在不同 Pod 之间进行平均,并通过与一个目标值比对来确定副本的数量。

它们的工作方式与资源度量指标非常相像,只是它们 仅 支持 target 类型为 AverageValue。

Pod 度量指标通过如下代码块定义:

1
2
3
4
5
6
7
type: Pods
pods:
  metric:
    name: packets-per-second
  target:
    type: AverageValue
    averageValue: 1k

Object 度量指标

第二种可选的度量指标类型是对象 Object 度量指标

这些度量指标用于描述在相同名字空间中的别的对象,而非 Pod。

请注意这些度量指标不一定来自某对象,它们仅用于描述这些对象。

对象度量指标支持的 target 类型包括 ValueAverageValue。

如果是 Value 类型,target 值将直接与 API 返回的度量指标比较, 而对于 AverageValue 类型,API 返回的度量值将按照 Pod 数量拆分, 然后再与 target 值比较。

下面的 YAML 文件展示了一个表示 requests-per-second 的度量指标。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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 将会计算每一个指标所提议的副本数量,然后最终选择一个最高值。

比如,如果你的监控系统能够提供网络流量数据,你可以通过 kubectl edit 命令将上述 Horizontal Pod Autoscaler 的定义更改为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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: <some-time>
  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 将会尝试确保每个 PodCPU 利用率在 50% 以内, 每秒能够服务 1000 个数据包请求, 并确保所有在 Ingress 后的 Pod 每秒能够服务的请求总数达到 10000 个。

基于更特别的度量值来扩缩

许多度量流水线允许你通过名称或附加的 标签 来描述度量指标。

对于所有非资源类型度量指标(PodObject 和后面将介绍的 External), 可以额外指定一个标签选择算符。

例如,如果你希望收集包含 verb 标签的 http_requests 度量指标,可以按如下所示设置度量指标块,使得扩缩操作仅针对 GET 请求执行:

1
2
3
4
5
type: Object
object:
  metric:
    name: http_requests
    selector: {matchLabels: {verb: GET}}

这个选择算符使用与 Kubernetes 标签选择算符相同的语法。

如果名称和标签选择算符匹配到多个系列,监测管道会决定如何将多个系列合并成单个值。

选择算符是可以累加的,它不会选择目标以外的对象(类型为 Pods 的目标 Pod 或者类型为 Object 的目标对象)。

外部度量指标(external metrics)

基于与 Kubernetes 对象无关的度量指标执行扩缩。

运行在 Kubernetes 上的应用程序可能需要基于与 Kubernetes 集群中的任何对象没有明显关系的度量指标进行自动扩缩, 例如那些描述与任何 Kubernetes 名字空间中的服务都无直接关联的度量指标。

Kubernetes 1.10 及之后版本中,你可以使用 外部度量指标(external metrics)

使用外部度量指标时,需要了解你所使用的监控系统,相关的设置与使用自定义指标时类似。

外部度量指标使得你可以使用你的监控系统的任何指标来自动扩缩你的集群。

你需要在 metric 块中提供 nameselector,同时将类型由 Object 改为 External

如果 metricSelector 匹配到多个度量指标,HorizontalPodAutoscaler 将会把它们加和。

外部度量指标同时支持 ValueAverageValue 类型,这与 Object 类型的度量指标相同。

例如,如果你的应用程序处理来自主机上消息队列的任务, 为了让每 30 个任务有 1 个工作者实例,你可以将下面的内容添加到 HorizontalPodAutoscaler 的配置中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
- type: External
  external:
    metric:
      name: queue_messages_ready
      selector:
        matchLabels:
          queue: "worker_tasks"
    target:
      type: AverageValue
      averageValue: 30

如果可能,还是推荐定制度量指标而不是外部度量指标,因为这便于让系统管理员加固定制度量指标 API。 而外部度量指标 API 可以允许访问所有的度量指标。 当暴露这些服务时,系统管理员需要仔细考虑这个问题。