k8s:根据CPU利用率实现pod的弹性伸缩
一、概念
1. 弹性伸缩的作用:
让集群的配置可以根据计算需求,自动增加或者自动减少。在服务器访问量突然增多,算力吃紧的情况下增加节点配置数量,直到访问量下降,计算后减少节点数,保证业务平稳健康运行。
2. k8s中如何实现弹性伸缩:
弹性伸缩主要针对资源不足情况,k8s平台中资源主要为node和pod两个维度。
pod是如何实现弹性伸缩的? 通过 HPA
Horizontal Pod Autoscale (HPA-->pod水平自动伸缩):根据资源利用率或自定义指标自动调整pod副本数。也就是对k8s的 workload的副本数进行自动水平扩缩容(scale)机制。
早期的kubernetes版本,只支持CPU指标的检测,因为它是通过kubernetes自带的监控系统heapster实现的。
到了kubernetes 1.8版本后,heapster已经弃用,资源指标主要通过metrics api获取,这时能支持检测的指标就变多了 (CPU、内存等核心指标和qps等自定义指标),目前内存指标不推荐,原因:pod中应用有各自内存管理机制。
3.利用Metrics Sevrer获取指标来实现HPA对pod的弹性伸缩
①了解Metrics Sevrer:
Metrics Sevrer是Kubernetes 集群核心监控数据的聚合器,也是k8s监控组件中重要一部分,Metrics Server 主要分为 API 和 Server 两大部分。其中 Metrics API 部分主要通过 APIServer 对外暴露 Pod 资源使用情况,比如:HPA、 kubectl top、Kubernetes dashboard 等。Metrics Server 是根据 Kubernetes 监控架构进行实施,该组件会定期通过 Summary API 从 Kubelet 所在集群节点获取服务指标,然后将指标汇总、存储到内存中,仅仅存储指标最新状态,一 旦重启组件数据将会丢失。现在通过 Metrics Server 采集到了数据,也暴露了 API 那么通过 kube-aggregator 统一 把 API Server(/apis/metrics) 数据转发给 Metrics Server,最后通过 metrics api 统一暴露出去。
②使用HPA,需要满足的条件:
- 启用kubernetes API聚合层(API Aggregation Layer):
在k8s 1.7版本引入了聚合层,允许第三方应用程序通过将自己注册到kube-apiserver上,将通过API server的 HTTP UTL对新的API进行访问和操作。因此k8s在apisevrer服务中引入API聚合层,用于扩展API的访问请求 转发到用户服务的功能。
- 注册API:
Metrics Server:提供资源指标获取(CPU/内存)。
Adapter:提供自定义指标,适配k8s api和三方获取服务指标。
二、通过HPA实现对pod资源类型(CPU)的弹性伸缩:
1.部署Metrics Server数据聚合器:
Metrics Server从kubelet从收集资源指标,通过metrics API在K8S apiserver暴露,供HPA使用
https://github.com/kubernetes-sigs/metrics-server metrics server 部署参考地址!
$kubectl apply -f https://github.com/kubernetes-sigs/metrics- server/releases/latest/download/components.yaml --dry-run=client -o yaml > metrics-server.yaml #拉一下github metrics-server yaml保存到本地
打开yaml文件,添加 - --kubelet-insecure-tls 参数,该参数为不验证kubelet提供的https证书
$kubectl apply -f metrics-server.yaml #部署metrics-server
$kubectl get pod -n kube-system | grep metrics-server #查看等待部署成功
$kubectl get apiservice | grep metrics #查看到成功注册到apiserver中
$kubectl top node/pod #通过访问metrics api验证是否成功
$kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods #返回获取指标json
2.部署测试应用
①部署nginx网站服务pod,定义requests资源:
$kubectl create deployment svc-pod1 --image=nginx --dry-run=client -o yaml > svc-pod1.yaml #生成nignx pod yaml文件
②修改yaml文件,定义requests资源:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: svc-pod1
name: svc-pod1
spec:
replicas: 3 #3个副本
selector:
matchLabels:
app: svc-pod1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: svc-pod1
spec:
containers:
- image: nginx
name: nginx
resources:
requests: #定义资源
cpu: 0.1
memory: 200M
limits:
cpu: 0.2
memory: 300M
③部署svc,暴露nginx服务:
$kubectl expose deployment svc-pod1 --port=80 --target-port=80 --type=NodePort --name svc-web
$kubectl get svc
④定义HPA:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: svc-pod1
spec:
maxReplicas: 10
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: svc-pod1
targetCPUUtilizationPercentage: 80
maxReplicas: 10 #最大扩容pod数
minReplicas: 2 #最小缩容pod数
targetCPUUtilizationPercentage: 80 #基于cpu达到80% 开始扩容
执行apply 创建hpa
目前还未使用。
⑤使用ab命令做压力测试:
$yum -y install httpd-tools #安装ab命令
$ab -n 200000 -c 1000 http://10.105.181.200/index.html #进行压力测试
cpu平均值已经到135% 使用kubectl get pod 查看是否开始扩容
可以看见节点已经扩容到6个
HPA有自己冷却周期,这样不会让pod副本数不断波动。 默认执行缩容后有5分钟冷却,执行扩容后有3分钟冷却。
等待后已恢复到定义的2个副本。