Contents
  1. 1. Aggregation Layer
  2. 2. metrics server
  3. 3. HPA
  4. 4. 结尾

HPA全称Horizontal Pod Autoscaling,是K8s实现pod自动水平扩容缩容的特性,这个特性使整个kubernetes集群马上高大上起来了。
要使用HPA也不是这么简单的,HPA api分v1、v2beta1、v2bate2三种,v1只支持通过CPU衡量扩缩容,v2bate1加入针对内存作为度量,v2bate2可以用customer metrics例如网络等,所以v2bate1开始才比较实用。

HPA能控制rc、deployment等resource

转自知乎-k8s开发与实践

要使用HPA必须要开启以下两个特性:

  • Aggregation Layer 聚合层,通过与核心的apiserver分离,实现自定义的扩展功能
  • metrics-server 数据收集,能够收集pod、node等实时运行指标(cpu、内存),给k8s集群使用,例如kubectl top命令、HPA

    比较老的版本使用heapster

Aggregation Layer

要打开Aggregation Layer,需要配置一下apiserver,增加相关认证证书。认证流程是client发起请求到apiserver,apiserver与aggergated apiserver建立tls安全链接,把请求proxy到aggergated apiserver,继续进行–requestheader-*参数的相关认证。

认证流程

转自k8s官方

需要生成aggregate使用的证书,参考cfssl生成证书方法,proxy-client-cert-file的CN需要与requestheader-allowed-names匹配。
在apiserver增加如下启动参数

1
2
3
4
5
6
7
8
9
--requestheader-client-ca-file=/etc/kubernetes/pki/agg-ca.pem
--proxy-client-cert-file=/etc/kubernetes/pki/aggregate.pem
--proxy-client-key-file=/etc/kubernetes/pki/aggregate-key.pem
--requestheader-allowed-names=aggregator
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
#如果kube-proxy没有在Master上面运行,还需要配置
--enable-aggregator-routing=true

参考:
k8s官方doc
解析kubernetes Aggregated API Servers

metrics server

从k8s 1.8开始,集群的资源使用情况都通过metrics api收集,例如容器CPU、内存。这些指标可用于kuberctl top或者k8s的HPA等特性。
metrice server可以在github找到并部署

1
2
3
git clone https://github.com/kubernetes-incubator/metrics-server
cd metrics-server
kubectl create -f deploy/1.8+/
  • 注1:metrics-server默认使用node的主机名,但是coredns里面没有物理机主机名的解析,一种是部署的时候添加一个参数: –kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP,第二种是使用dnsmasq构建一个上游的dns服务
  • 注2:kubelet 的10250端口使用的是https协议,连接需要验证tls证书。可以在metrics server启动命令添加参数–kubelet-insecure-tls不验证客户端证书
  • 注3:yaml文件中的image地址k8s.gcr.io/metrics-server-amd64:v0.3.3 需要梯子,需要改成中国可以访问的image地址,可以使用aliyun的。这里使用hub.docker.com里的google镜像地址 image: mirrorgooglecontainers/metrics-server-amd64:v0.3.3

成功运行kubectl top命令

1
2
3
4
5
6
ubuntu@k8s-dev-m1:~/k8sssl/agglayer$ kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-dev-node2 103m 5% 2696Mi 72%
k8s-dev-node3.bxr.cn 115m 2% 5312Mi 67%
k8s-dev-node4 57m 2% 2634Mi 70%
k8s-dev-node5 148m 7% 2443Mi 65%

如果出现下面的报错说明你的apiserver不能访问到metrics server,要么把master节点纳入k8s网络,使master能访问172.31.0.112,要么在metrics deploy加hostNetwork: true,把metrics暴露出来。

1
2
3
4
5
6
I0816 07:07:46.175439       5 controller.go:105] OpenAPI AggregationController: Processing item v1beta1.metrics.k8s.io
E0816 07:07:46.175696 5 controller.go:111] loading OpenAPI spec for "v1beta1.metrics.k8s.io" failed with: failed to retrieve openAPI spec, http error: ResponseCode: 503, Body: service unavailable
, Header: map[Content-Type:[text/plain; charset=utf-8] X-Content-Type-Options:[nosniff]]
I0816 07:07:46.175721 5 controller.go:119] OpenAPI AggregationController: action for item v1beta1.metrics.k8s.io: Rate Limited Requeue.
E0816 07:07:47.216915 5 available_controller.go:316] v1beta1.metrics.k8s.io failed with: Get https://172.31.0.112:443: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
E0816 07:08:12.230503 5 available_controller.go:316] v1beta1.metrics.k8s.io failed with: Get https://172.31.0.112:443: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

参考:
Kubernetes实录(13) Kubernetes部署metrics-server

HPA

有了metrics就可以开始使用HPA特性了。hpa有几个特点

  • deploy或者rs等需要设置resources才能使用hpa
  • 如果我们创建一个HPA controller,它会每隔15s(可以通过–horizontal-pod-autoscaler-sync-period修改)检测一次hpa定义的资源与实际资源使用情况,如果达到阀值就会调整pod数量。
  • HPA设置的阀值不是绝对的,允许设置一个浮动范围,–horizontal-pod-autoscaler-tolerance默认是0.1
  • pod调整算法 desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
  • scale有一个窗口期,期间每次变化会记录下来,选择最优的调整建议再进行scale,这样可以保证资源平滑变动,通过–horizontal-pod-autoscaler-downscale-stabilization设定,默认5分钟。
  • 通过hpa调整新增的pod不会马上ready,这时候收集的metrics就不准,为了减少影响,hpa一开始不会收集新pod的metrics。通过–horizontal-pod-autoscaler-initial-readiness-delay(默认30s)和 –horizontal-pod-autoscaler-cpu-initialization-period(默认为 5 分钟)调整

示例hpa.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: hpa-test
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 75
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 160

上面的示例包括cpu和memory指标,averageUtilization这个百分比是根据deployment的resources.requests计算的。例如有deployment限制requests是512Mi,replicas是2,实际pod1用了612Mi,pod2用了598Mi,计算公式是 (612+598)/2/512 = 118%

查看hpa的情况,targets第一个是memory,第二个是cpu指标,REPLICAS是根据计算后的当前pod数

1
2
3
ubuntu@k8s-m1:~/k8s/hpa$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-test Deployment/podinfo 120%/160%, 6%/75% 2 4 3 97m

本来想memory使用平均值target.averageValue,而不是百分比的,不过targets显示 /800Mi ,后续再测试

官方示例还包括packets-per-second、requests-per-second这些指标,需要进一步验证

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
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: AverageUtilization
averageUtilization: 50
- type: Pods
pods:
metric:
name: packets-per-second
targetAverageValue: 1k
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: main-route
target:
kind: 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/v1beta1
kind: Ingress
name: main-route
current:
value: 10k

官方doc

结尾

HPA的能力的确很吸引人,如果能自己根据业务特性开发出customer metrice那对运维来说就太方便了,从资源使用的角度来看如果未来HPA能实现node节点的上下架,结合国内云商使用,从资费上更能体现出自动化运维的价值。

Contents
  1. 1. Aggregation Layer
  2. 2. metrics server
  3. 3. HPA
  4. 4. 结尾