HPA 全称是 Horizontal Pod Autoscaler,翻译成中文是 POD 水平自动伸缩, HPA 可以基于CPU 利用率对 deployment 中的 pod 数量进行自动扩缩容(除了 CPU 也可以基于自定义的指标进行自动扩缩容)。pod 自动缩放不适用于无法缩放的对象,比如 DaemonSets。
HPA 由 Kubernetes API 资源和控制器实现。控制器会周期性的获取平均 CPU 利用率,并与目标值相比较后调整 deployment 中的副本数量。
HPA 的 API 有三个版本,通过 kubectl api-versions | grep autoscal 可看到
autoscaling/v1 只支持基于 CPU 指标的缩放;
autoscaling/v2beta1 支持 Resource Metrics(资源指标,如 pod 的内存)和 Custom Metrics(自定义指标)的缩放;
autoscaling/v2beta2 支持 Resource Metrics(资源指标,如 pod 的内存)和 Custom Metrics(自定义指标)和 ExternalMetrics(额外指标)的缩放,但是目前也仅仅是处于 beta 阶段
指标从哪里来?
K8S 从 1.8 版本开始,CPU、内存等资源的 metrics 信息可以通过 Metrics API 来获取,用户可以直接获取这些 metrics 信息(例如通过执行 kubect top 命令),HPA 使用这些 metics 信息来实现动态伸缩。
Metrics server:
1、Metrics server 是 K8S 集群资源使用情况的聚合器
2、从 1.8 版本开始,Metrics server 可以通过 yaml 文件的方式进行部署
3、Metrics server 收集所有 node 节点的 metrics 信息
metrics-server 是一个集群范围内的资源数据集和工具,同样的,metrics-server 也只是显示数据,并不提供数据存储服务,主要关注的是资源度量 API 的实现,比如 CPU、文件描述符、内存、请求延时等指标,metric-server 收集数据给 k8s 集群内使用,如 kubectl,hpa,scheduler 等
1.部署 metrics-server 组件
通过在线方式获取镜像
需要的镜像是:k8s.gcr.io/metrics-server-amd64:v0.3.6 和 k8s.gcr.io/addon-resizer:1.8.4
使用 registry.aliyuncs.com/google_containers 代理拉取 k8s.gcr.io
docker pull registry.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
docker pull registry.aliyuncs.com/google_containers/addon-resizer:1.8.4
部署 metrics-server 服务
在/etc/kubernetes/manifests 里面改一下 apiserver 的配置
注意:这个是 k8s 在 1.17 的新特性,如果是 1.16 版本的可以不用添加,1.17 以后要添加。这个参数的作用是 Aggregation 允许在不修改 Kubernetes 核心代码的同时扩展 Kubernetes API。
vim /etc/kubernetes/manifests/kube-apiserver.yaml
增加如下内容:
- --enable-aggregator-routing=true
重新更新 apiserver 配置:
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system
kubectl apply -f metrics.yaml
基于 dockerfile 构建一个 PHP-apache 项目
1)创建并运行一个 php-apache 服务
使用 dockerfile 构建一个新的镜像,在 k8s-master1 节点构建
mkdir php
cd php/
vim dockerfile
vim index.php
构建镜像
docker build -t k8s.gcr.io/hpa-example:v1 .
打包镜像
docker save -o hpa-example.tar.gz k8s.gcr.io/hpa-example:v1
解压镜像
可以把镜像传到 k8s 的各个工作节点,通过 docker load -i hpa-example.tar.gz 进行解压:
scp hpa-example.tar.gz k8s-01:/root/
scp hpa-example.tar.gz k8s-02:/root/
通过 deployment 部署一个 php-apache 服务
vim php-apache.yaml
php-apache 服务正在运行,使用 kubectl autoscale 创建自动缩放器,实现对 php-apache 这个deployment 创建的 pod 自动扩缩容,下面的命令将会创建一个 HPA,HPA 将会根据 CPU,内存等资源指标增加或减少副本数
创建一个可以实现如下目的的 hpa:
1)让副本数维持在 1-10 个之间(这里副本数指的是通过 deployment 部署的 pod 的副本数)
2)将所有 Pod 的平均 CPU 使用率维持在 50%(通过 kubectl run 运行的每个 pod 如果是 200毫核,这意味着平均 CPU 利用率为 100 毫核)
编辑 hpa-v2.yaml
更新 nginx.yaml
重新生成 pod
kubectl delete -f hpa-v1.yaml
kubectl delete -f nginx.yaml
kubectl apply -f hpa-v2.yaml
kubectl apply -f nginx.yaml
同样进入容器进行压测
kubectl exec -it nginx-hpa-v2-6675977fc6-jz4fq -- bash
/ :dd if=/dev/zero of=/tmp/a
再打开2个窗口观察
scaleUp:
policies:
- periodSeconds: 60 检测时间 AGE 这里可以看到大概 1m 左右 检测一次,一次增加1个
type: Percent 判断类型是 百分比
value: 9 使用率上限,可以使用 % 比如 900% 也可以直接指定数值
nginx-hpa-v2 Deployment/nginx-hpa-v2 0%/80% v2默认使用率为 80%
510% / 80% 约= 6 最终稳定在了 6个 pod
停止检测,再观察
scaleDown:
policies:
- periodSeconds: 60 检测时间
type: Pods 检测类型 为 pod 数量
value: 1 每次减少一个
经过观察大约1m 左右减少一个 pod。停止压测的时候反而增加了一个pod
参考:
https://v1-18.docs.kubernetes.io/docs/reference/generated/kubernetesapi/v1.18/horizontalpodautoscalerbehavior-v2beta2-autoscaling
使用 HPA 功能需要在 controller-manager 启动文件中加入的参数:
--horizontal-pod-autoscaler-tolerance=0.1,设置扩缩容忍度,默认值 0.1(10%),表示基于算法得到的结果在 0.9-1.1(-10%-10%),控制器都不会进行扩缩容
--horizontal-pod-autoscaler-initial-readiness-delay=30s,设置首次探测 Pod 是否 Ready 的延时时间,默认值 30min
--horizontal-pod-autoscaler-cpu-initialization-period=10s,设置首次采集 Pod 的 CPU 使用率的延迟时间
--horizontal-pod-autoscaler-downscale-stabilization=1m0s,这个配置可让系统更平滑的进行缩容操作,默认值 5min
Cluster Autoscaler (CA)是一个独立程序,是用来弹性伸缩 kubernetes 集群。它可以自动根据部署应用所请求的资源量来动态的伸缩集群。当集群容量不足时,它会自动去 Cloud Provider (支持GCE、GKE 和 AWS)创建新的 Node,而在 Node 长时间资源利用率很低时自动将其删除以节省开支。
项目地址:https://github.com/kubernetes/autoscaler
Cluster Autoscaler 什么时候伸缩集群?
在以下情况下,集群自动扩容或者缩放:
扩容:由于资源不足,某些 Pod 无法在任何当前节点上进行调度
缩容: Node 节点资源利用率较低时,且此 node 节点上存在的 pod 都能被重新调度到其他 node节点上运行
什么时候集群节点不会被 CA 删除?
1)节点上有 pod 被 PodDisruptionBudget 控制器限制。
2)节点上有命名空间是 kube-system 的 pods。
3)节点上的 pod 不是被控制器创建,例如不是被 deployment, replica set, job, stateful set 创建。
4)节点上有 pod 使用了本地存储
5)节点上 pod 驱逐后无处可去,即没有其他 node 能调度这个 pod
6)节点有注解:"cluster-autoscaler.kubernetes.io/scale-down-disabled": "true"(在 CA 1.0.3 或更高版本中受支持)
扩展:什么是 PodDisruptionBudget?
通过 PodDisruptionBudget 控制器可以设置应用 POD 集群处于运行状态最低个数,也可以设置应用 POD 集群处于运行状态的最低百分比,这样可以保证在主动销毁应用 POD 的时候,不会一次性销毁太多的应用 POD,从而保证业务不中断
Horizontal Pod Autoscaler 如何与 Cluster Autoscaler 一起使用?
Horizontal Pod Autoscaler 会根据当前 CPU 负载更改部署或副本集的副本数。如果负载增加,则 HPA 将创建新的副本,集群中可能有足够的空间,也可能没有足够的空间。如果没有足够的资源,CA将尝试启动一些节点,以便 HPA 创建的 Pod 可以运行。如果负载减少,则 HPA 将停止某些副本。结果,某些节点可能变得利用率过低或完全为空,然后 CA 将终止这些不需要的节点。
扩展:如何防止节点被 CA 删除?
节点可以打上以下标签:
"cluster-autoscaler.kubernetes.io/scale-down-disabled": "true"
可以使用 kubectl 将其添加到节点(或从节点删除):
$ kubectl annotate node <nodename> cluster-autoscaler.kubernetes.io/scale-downdisabled=true
Cluster Autoscaler 支持那些云厂商?
GCE https://kubernetes.io/docs/concepts/cluster-administration/cluster-management/
GKE https://cloud.google.com/container-engine/docs/cluster-autoscaler
AWS(亚马逊) https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/aws/README.md
Azure(微软) https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/azure/README.md
Alibaba Cloud https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/alicloud/README.md
OpenStack Magnum https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/magnum/README.md
DigitalOcean https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/digitalocean/README.md
CloudStack https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/cloudstack/README.md
Exoscale https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/exoscale/README.md
Packet https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/packet/README.md
OVHcloud https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/ovhcloud/README.md
Linode https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/linode/README.md
Hetzner https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/hetzner/README.md
Cluster API https://github.com/kubernetes/autoscaler/blob/master/clusterautoscaler/cloudprovider/clusterapi/README.md
网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。
加入交流群
请使用微信扫一扫!