前言
应用资源的使用率通常和业务特性密切相关,其会有高峰和低谷的时候。如何削峰填谷、如何提高集群的整体资源利用率、如何让service中的Pod个数进行自动调整呢?
这就得依赖于Horizontal Pod Autoscaling(HPA控制器)了!
1、系统扩展浅谈
随着业务的快速发展,我们都会从以下两个维度来思考如何扩展系统,从而保证业务的稳定性:
1、 提升系统的单机处理能力 :又称垂直扩展
1、 增强单机硬件性能,例如:增加CPU的核数,由8核扩展到16核;升级更好的网卡,由千兆网卡升级到万兆网卡;升级更好的硬盘,如SSD;扩展硬盘的容量,如由500G升级到10T;扩展系统内存,如由16G升级到64G等。
2、提升单机架构的性能,例如:引入缓存机制Redis来减少IO次数;引入消息队列机制,来削峰填谷,用异步处理来增加单服务的吞吐量;用轻量级架构来减少服务的处理时间等等。
2、提升系统的横向扩展能力 :又称为水平扩展
系统单机的处理能力总是有极限的,我们可以通过增加服务器数量的方式,来线性扩充系统的性能。
3、下面我们看看kubernetes体系中的扩展。
1.水平伸缩
K8S基础资源级别的水平伸缩,其有以下3个api版本,主要是kubernetes基础原生资源的水平伸缩
HPA(Horizontal Pod Autoscaling):
autoscaling/v1:仅支持cpu采样
autoscaling/v2beta1:额外增加支持custom metrics(kubernetes1.6+)
autoscaling/v2beta2:额外增加支持external metrics,multiple metrics和metrics APIs(kubernetes1.6)
K8S集群级别的水平伸缩:CA(Cluster Autoscaler)则是计算资源的水平伸缩,比如新增一个node节点
CA(Cluster Autoscaler):通过集成云计算的相关资源申请接口,达到集群级别的动态弹性伸缩效果。
2、垂直伸缩
VPA(Vertical Pod AutoScaler):提升单个Pod的request的处理能力
AR(Addon Resizer:垂直伸缩工具):根据实际状态,弹性调整pod的request和limit配置
2、HPA简介
根据对应的autoscaling/API版本,HPA可以获得监控指标并结合replication controller, deployment, replica set或者stateful set自动扩展Pod
注意:DaemonSets对象是不支持HPA的。
3、HPA组件交互图
如图所示,用户可以通过CMD,显示申明一个HPA控制器,然后HPA控制器根据指标自动调整RS/Deployment控制器指标,从而达到自动扩缩容Pod的效果。
自动伸缩demo命令:
kubectl autoscale deployment foo --min=2 --max=5 --cpu-percent=80
4、开始之前的操作
使用前,需要make sure以下两点:
1、K8S集群version 1.2 or later
2、metrics-server/Prometheus
metrics-server部署的时候需要注意修改~/deploy/对应版本下的/metrics-server-deployment.yaml,新增command段的配置
containers:
- name: metrics-server
image: k8s.gcr.io/metrics-server-amd64:v0.3.3
imagePullPolicy: Always
volumeMounts:
- name: tmp-dir
mountPath: /tmp
command:
- /metrics-server
- --kubelet-preferred-address-types=InternalIP
- --kubelet-insecure-tls
否则会碰到如下报错信息:
unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:mywork: unable to fetch metrics from Kubelet mywork (mywork): Get https://mywork:10250/stats/summary/: dial tcp: i/o timeout, unable to fully scrape metrics from source kubelet_summary:marktest: unable to fetch metrics from Kubelet marktest (marktest): Get https://marktest:10250/stats/summary/: dial tcp: i/o timeout]
相应的,如果想集成prometheus的SD,需要在K8S基础资源中进行声明:
annotations:
# based on your Prometheus config above, this tells prometheus
# to scrape this pod for metrics on port 80 at "/metrics"
prometheus.io/scrape: "true" #允许prometheus自动发现,并抓取数据
prometheus.io/port: "80" #数据端口
prometheus.io/path: "/metrics" #数据uri
5、实战-autoscaling/v1
1、创建压测服务myapp.yaml,并apply
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp
image: registry.cn-hangzhou.aliyuncs.com/aaron89/myapp:v1
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 50m
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
labels:
app: myapp
namespace: default
spec:
selector:
app: myapp
ports:
- name: http
port: 80
targetPort: 80
type: NodePort
2、创建HPA控制器,并检查
我们定义的HPA为:cpu利用率大于1%就进行扩容,扩缩容的最大范围是deployment下pod的最终数量为1-5个节点
[root@centos-1 dingqishi]# kubectl autoscale deployment myapp --min=1 --max=5 --cpu-percent=1
horizontalpodautoscaler.autoscaling/myapp autoscaled
[root@centos-1 dingqishi]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
myapp Deployment/myapp 0%/1% 1 5 2 3s
3、由于CPU利用率不足1%,pod已经进行了缩容
[root@centos-1 dingqishi]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-d48f86cd4-d8nt5 1/1 Running 0 21m
4、这时,我们需要达到扩容的展示效果,需要在客户端启动压测命令
while true; do curl http://192.168.0.104:30502;sleep ...1.;done
5、我们发现pod已经进行了扩容,虽然扩容后的cpu利用率还是大于1%,但是我们定义最大pod数量是5,所以就不会再扩容了,和预期效果一致。
[root@centos-1 dingqishi]# kubectl top pod
NAME CPU(cores) MEMORY(bytes)
myapp-d48f86cd4-d8nt5 24m 2Mi
ngx-new-cb79d555-x822n 0m 3Mi
[root@centos-1 dingqishi]# kubectl top pod
NAME CPU(cores) MEMORY(bytes)
myapp-d48f86cd4-8xdts 5m 2Mi
myapp-d48f86cd4-bdlr2 5m 2Mi
myapp-d48f86cd4-d8nt5 5m 2Mi
myapp-d48f86cd4-mll6m 5m 2Mi
myapp-d48f86cd4-rlszf 5m 2Mi
ngx-new-cb79d555-x822n 0m 3Mi
[root@centos-1 dingqishi]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
myapp Deployment/myapp 10%/1% 1 5 5 4m8s
6、介绍-autoscaling/v2beta2
autoscaling/v2beta2接口中提供了丰富的stom metrics,如:
每秒数据包数、每秒请求数等
具体可以参阅以下demo:
apiVersion: autoscaling/v2beta2
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: 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/v1beta1
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/v1beta1
kind: Ingress
name: main-route
current:
value: 10k