HPA自动扩缩容


HPA的自动扩缩容介绍

官网介绍

在 Kubernetes 中,HorizontalPodAutoscaler 自动更新工作负载资源 (例如 Deployment 或者 StatefulSet), 目的是自动扩缩工作负载以满足需求。

水平扩缩意味着对增加的负载的响应是部署更多的 Pod。 这与“垂直(Vertical)”扩缩不同,对于
Kubernetes, 垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的Pod。

如果负载减少,并且 Pod 的数量高于配置的最小值, HorizontalPodAutoscaler 会指示工作负载资源(Deployment、StatefulSet 或其他类似资源)缩减。

总结:HPA可根据 系统负载 情况(CPU、MEM、Disk...)对控制器(Deployment、StatefulSet 
ReplicaSet)进行操作,修改副本(replicas)数量,达到扩缩容的目的

image-20240924142853860

image-20240924143401422

Metrics Server介绍

metrics-server是离线监控数据组件。即使您处于离线状态,您也可以通过metrics-server组件查看监控数据。本文介绍metrics-server组件的详细信息、使用说明和变更记录。

Metrics Server是Kubernetes内置自动缩放管道的可扩展、高效的容器资源度量源。

Metrics Server从Kubelets收集资源度量,并通过Metrics API在Kubernetes apiserver中公开这些度量,供Horizontal Pod Autoscaler和Vertical Pod Autocaler使用。kubectl top还可以访问度量API,从而更容易地调试自动缩放管道。

image-20240924143612653

部署Metrics Server

### 不部署无法查看pod和node的信息
[root@master01 wordpress]# kubectl top node 
error: Metrics API not available

### 所有的node节点导入镜像
[root@node01 ~]# docker load < metrics-server.tar
[root@node02 ~]# docker load < metrics-server.tar
[root@node03 ~]# docker load < metrics-server.tar

[root@node01 ~]# docker images metrics-server
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
metrics-server      v0.4.0              592eadd45a90        3 years ago         60.5MB


[root@master kubernetes]# kubectl get daemonsets.apps -n kube-system metrics-server 
NAME             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
metrics-server   3         3         3       3            3           kubernetes.io/os=linux   5h21m
### 在master上面执行metrcs资源清单
#--- 修改资源控制器为 DaemonSET
#--- 修改镜像为 metrics-server: v0.4.0

## 执行
[root@master kubernetes]# kubectl apply -f components.yaml 

## 查询信息
[root@master kubernetes]# kubectl get daemonsets.apps -n kube-system metrics-server 
NAME             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
metrics-server   3         3         3       3            3           kubernetes.io/os=linux   5h21m
#### 执行查询命令 即可
## 查询pod的信息
[root@master kubernetes]# kubectl top pod 
NAME                            CPU(cores)   MEMORY(bytes)   
c7                              0m           0Mi             
nginx-565785f75c-4sll4          0m           2Mi             
nginx-deploy-545f948568-4m7bq   0m           2Mi             
nginx-deploy-545f948568-7lg2x   0m           2Mi             
nginx-deploy-545f948568-v95hv   0m           2Mi             
php-apache-869dfddb74-zfdlm     1m           16Mi   
## 查询节点的信息
[root@master kubernetes]# kubectl top node 
NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
master   101m         5%     1133Mi          60%       
node01   30m          1%     949Mi           50%       
node02   35m          1%     643Mi           34%       
node03   41m          2%     1200Mi          31%   
## 查询pod内容器的信息
[root@master kubernetes]# kubectl top pod nginxrs-8nqsr  --containers 
POD             NAME              CPU(cores)   MEMORY(bytes)   
nginxrs-8nqsr   nginx-container   1m           2Mi             
nginxrs-8nqsr   tomcat            166m         71Mi       


配置自动扩缩容 (横向)

#### hpa 资源清单
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  maxReplicas: 15    					## 最大副本数
  minReplicas: 1						## 最小副本数
  scaleTargetRef:						## HPA关联的控制器
    apiVersion: apps/v1					## 控制器接口
    kind: Deployment					## 控制器类型
    name: php-apache					## 控制器名字
  targetCPUUtilizationPercentage: 50      ## 所关联的控制器cpu扩容警戒线
###### 新的k8s 配置文件更加灵活 ######
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  maxReplicas: 15
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  metrics:
  - type: Resource
    resource:
      name: cpu       # 基于cpu
      target:
        type: Utilization
        averageUtilization: 50  ## 超过50 扩容
  - type: Resource
    resource:
      name: memory                   # 基于内存的扩缩容
      target:
        type: Utilization
        averageUtilization: 75        # 当内存使用率超过 75% 时扩容
  - type: Pods
    pods:
      metric:
        name: custom_disk_io_metric  # Prometheus 中定义的磁盘 I/O 指标
      target:
        type: AverageValue
        averageValue: 100Mi         # 根据自定义的指标阈值扩容
实战扩缩容
---  根据pod中cup的占用来扩容  (并非是node的cpu占用)
### 制作操作docker镜像
# 1.编写php代码
cat > index.php << 'EOF'
<?php
	$x = 0.0001;
	for ($i = 0; $i <= 1000000; $i++) {
		$x += sqrt($x);
	}
	echo "OK!";
?>
EOF

# 2.创建Dockerfile
cat > dockerfile << 'EOF'
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php
EOF

# 3.构建镜像
docker build -t php:v1 .
逐步分析脚本的运作:
	初始化变量$x为0.0001。
	开始一个循环,循环变量$i从0开始,直到(包括)1000000。在每次循环迭代中:
	计算$x的平方根(使用sqrt()函数)。
	将计算得到的平方根值加到$x上。
	当$i达到1000000时,循环结束。
	输出"OK!"。
################ dp资源清单 #############
## dp命令行: kubectl run php-apache --image=php:v1 --requests=cpu=200m --expose --port=80

## dp资源清单
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  replicas: 1
  selector:
    matchLabels:
      run: php-apache
  template:
    metadata:
      labels:
         run: php-apache
    spec:
      containers:
      - image: php:v1
        imagePullPolicy: IfNotPresent
        name: php-apache
        resources:
          requests:
            cpu: 200m
            
resources: 定义了容器需要的资源。
requests: 指定了资源请求,即容器正常运行所需的最小资源量。
cpu: 指定了CPU资源请求,这里是200m。m是毫核(milli-cores)的缩写,所以200m等于0.2个CPU核心。

######################## HPA ##############################
## HPA命令行: kubectl autoscale deployment php-apache --
cpu-percent=50 --min=1 --max=10

## HPA资源清单 
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  maxReplicas: 15    					## 最大副本数
  minReplicas: 1						## 最小副本数
  scaleTargetRef:						## HPA关联的控制器
    apiVersion: apps/v1					## 控制器接口
    kind: Deployment					## 控制器类型
    name: php-apache					## 控制器名字
  targetCPUUtilizationPercentage: 50      ## 所关联的控制器cpu扩容警戒线
  
  
  
[root@master hpa]# kubectl apply  -f php.yaml  (php资源清单)
deployment.apps/php-apache created

[root@master hpa]# kubectl apply  -f hpa-php.yaml   (hpa资源清单)
horizontalpodautoscaler.autoscaling/php-apache unchanged
##### 压测前的资源准备  
[root@master ser]# kubectl get pod php-apache-869dfddb74-fnbkq -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP          NODE     
php-apache-869   1/1     Running   0          17m   10.2.3.20   node03

IP : 10.2.3.20

### 持续监控 dp资源
[root@master ser]# kubectl get horizontalpodautoscalers.autoscaling -w
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         15        1          5h21m

### 持续查看 node的状态
[root@master ser]# kubectl top node 
NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
master   119m         5%     1138Mi          60%       
node01   26m          1%     944Mi           50%       
node02   28m          1%     620Mi           32%       
node03   28m          1%     1212Mi          31%  

###########################################################

while true; do wget -q -O- http://10.2.3.20; done

image-20240924154650681

image-20240924154732579

image-20240924154856807

自动扩充的pod并不会立马消失 

HPA 会每 15 秒轮询一次与目标资源(如 CPU、内存)相关的度量指标,然后决定是否执行扩容或缩容动作。HPA 的具体时间行为如下:

扩容动作通常会快速执行,如果发现负载持续增加,HPA 会立即增加 Pods 的数量。
缩容动作则是逐步执行的,默认情况下,Kubernetes 不会立刻缩减所有不需要的 Pods。HPA 至少会等到最近一次扩容的 5 分钟之后才会开始缩容,以避免快速扩容和缩容之间的抖动。

image-20240924155638059