Kubernetes实战(二十七)-HPA实战

2024-02-08 15:52

本文主要是介绍Kubernetes实战(二十七)-HPA实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 HPA简介

HPA 全称是 Horizontal Pod Autoscaler,用于POD 水平自动伸缩, HPA 可以 基于 POD CPU 利用率对 deployment 中的 pod 数量进行自动扩缩容(除了 CPU 也可以基于自定义的指标进行自动扩缩容)。pod 自动缩放不适用于无法缩放的对象,比如 DaemonSets。

HPA 由 Kubernetes API 资源和控制器实现。控制器会周期性的获取平均 CPU 利用率, 并与目标值相比较后调整 deployment 中的副本数量。

2 HPA实战

HPA 是根据指标来进行自动伸缩的,目前 HPA 有两个版本–v1 和 v2beta

HPA 的 API 有三个版本,通过 kubectl api-versions | grep autoscal 可看到

[root@master k8s]#  kubectl api-versions | grep autoscal
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
  • 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:

  • Metrics server 是 K8S 集群资源使用情况的聚合器
  • 从 1.8 版本开始,Metrics server 可以通过 yaml 文件的方式进行部署
  • Metrics server 收集所有 node 节点的 metrics 信息

2.1 HPA工作原理

HPA 的实现是一个控制循环,由 controller manager 的--horizontal-pod-autoscaler-syncperiod 参数指定周期(默认值为 15 秒)。每个周期内,controller manager 根据每个 HorizontalPodAutoscaler 定义中指定的指标查询资源利用率。controller manager 可以从 resource metrics API(pod 资源指标)和 custom metrics API(自定义指标)获取指标。

然后通过现有 pods 的 CPU 使用率的平均值(计算方式是最近的 pod 使用量(最近一分钟的平均 值,从 metrics-server 中获得)除以设定的每个 Pod 的 CPU 使用率限额)跟目标使用率进行比较, 并且在扩容时,还要遵循预先设定的副本数限制:MinReplicas <= Replicas <= MaxReplicas。计算扩容后 Pod 的个数:sum(最近一分钟内某个 Pod 的 CPU 使用率的平均值)/CPU 使用上限的 整数+1。

2.2 扩容流程

1)创建 HPA 资源,设定目标 CPU 使用率限额,以及最大、最小实例数

2)收集一组中(PodSelector)每个 Pod 最近一分钟内的 CPU 使用率,并计算平均值

3)读取 HPA 中设定的 CPU 使用限额

4)计算:平均值之和/限额,求出目标调整的实例个数

5)目标调整的实例数不能超过 1)中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数

6)回到 2,不断循环

2.3 HPA部署验证

2.3.1 安装数据采集组件metrics-server

metrics-server 是一个集群范围内的资源数据集和工具,同样的,metrics-server 也只是显示数据,并不提供数据存储服务,主要关注的是资源度量 API 的实现,比如 CPU、文件描述符、内存、 请求延时等指标,metric-server 收集数据给 k8s 集群内使用,如 kubectl,hpa,scheduler 等

#通过离线方式获取镜像

需要的镜像是:k8s.gcr.io/metrics-server-amd64:v0.3.6 和 k8s.gcr.io/addon-resizer:1.8.4,把镜像上传 到 k8s 的各个节点,并导入:

docker load -i addon.tar.gzdocker load -i metrics-server-amd64-0-3-6.tar.gz

# 部署metrics-server服务

#在/etc/kubernetes/manifests 里面改一下 apiserver 的配置

注意:这个是 k8s 在 1.17 的新特性,如果是 1.16 版本的可以不用添加,1.17 以后要添加。这个参 数的作用是 Aggregation 允许在不修改 Kubernetes 核心代码的同时扩展 Kubernetes API。

[root@master ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml

增加如下内容: - --enable-aggregator-routing=true

重新更新 apiserver 配置:

[root@master ~]# kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
pod/kube-apiserver created
[root@master ~]# kubectl apply -f metrics.yaml 
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
configmap/metrics-server-config created
deployment.apps/metrics-server created
service/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created

#验证 metrics-server 是否部署成功

[root@master ~]# kubectl get pods -n kube-system | grep metrics
metrics-server-6595f875d6-bjgrv 2/2 Running 0 31s# 测试kubectl top命令
[root@master ~]# kubectl top nodes
NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
master   368m         9%     1641Mi          28%       
node1    93m          4%     700Mi           19%       
node3    75m          3%     559Mi           32% [root@master ~]# kubectl top pods -n kube-system
NAME                                       CPU(cores)   MEMORY(bytes)   
calico-kube-controllers-56c7cdffc6-n2grp   1m           21Mi            
calico-node-lcq82                          41m          81Mi            
calico-node-ltnpt                          39m          101Mi           
calico-node-zhvpx                          76m          74Mi            
coredns-7f89b7bc75-bd6k7                   10m          15Mi            
coredns-7f89b7bc75-thkbx                   6m           15Mi            
etcd-master                                34m          71Mi            
kube-apiserver-master                      107m         459Mi           
kube-controller-manager-master             40m          54Mi            
kube-proxy-gjx9g                           1m           18Mi            
kube-proxy-wmnd4                           1m           18Mi            
kube-proxy-xz4b7                           1m           18Mi            
kube-scheduler-master                      6m           23Mi            
metrics-server-6595f875d6-bjgrv            1m           15Mi 

2.3.2 创建php-apache服务,利用HAP进行自动扩缩容 

1)创建并运行一个 php-apache 服务
使用 dockerfile 构建一个新的镜像,在 k8s 的 master 构建

[root@master php]# mkdir /root/php
[root@master php]# cd php
[root@master php]# docker load -i php.tar.gz
[root@master php]# cat dockerfile 
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php
[root@master php]# cat index.php 
<?php$x = 0.0001;for ($i = 0; $i <= 1000000;$i++) {$x += sqrt($x);}echo "OK!";
?>

2)构建镜像 

[root@master php]# docker build -t 192.168.10.12/test/hap-example:v1 .
# 在各节点导入该镜像
[root@master php]# docker save  192.168.10.12/test/hap-example:v1 -o hpa-example.tar.gz
[root@master php]# docker load -i hpa-example.tar.gz

3) 部署php-apache服务

[root@master php]# cat php-apache.yaml 
apiVersion: apps/v1
kind: Deployment
metadata: name: php-apache
spec:selector:matchLabels:run: php-apachereplicas: 1template:metadata:labels:run: php-apachespec:containers:- name: php-apacheimage: 192.168.10.12/test/hap-example:v1imagePullPolicy: IfNotPresentports:- containerPort: 80resources:limits:cpu: 500mrequests:cpu: 200m
---
apiVersion: v1
kind: Service
metadata:name: php-apachelabels:run: php-apache
spec:ports:- port: 80selector:run: php-apache[root@master php]# kubectl apply -f php-apache.yaml 
deployment.apps/php-apache created
service/php-apache created[root@master php]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
php-apache-58857b55d7-4sr6m   1/1     Running   0          15s

2.3.3 创建HPA

php-apache服务正在运行,使用kubectl autoscale创建自动缩放器,实现对php-apache 这个 deployment 创建的 pod 自动扩缩容,下面的命令将会创建一个 HPA,HPA 将会 根据 CPU,内存等资源指标增加或减少副本数,创建一个可以实现如下目的的 hpa:

  • 让副本数维持在 1-10 个之间(这里副本数指的是通过 deployment 部署的 pod 的副本数)
  • 将所有 Pod 的平均 CPU 使用率维持在 50%(通过 kubectl top 看到的每个 pod 如果 是 200 毫核,这意味着平均 CPU 利用率为 100 毫核)

#给上面 php-apache 这个 deployment 创建 HPA

[root@master php]# kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled
  • --cpu-percent=50(表示 cpu 使用率不超过 50%)
  • --min=1(最少一个 pod)
  • --max=10(最多 10 个 pod)

# 验证hpa是否创建成功

[root@master php]# kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          38s

注:由于我们没有向服务器发送任何请求,因此当前 CPU 消耗为 0%(TARGET 列显示了由相应的 deployment 控制的所有 Pod 的平均值)。

2.3.4 HPA基于CPU使用率实现Pod自动扩/缩容

压测php-apache服务,只针对CPU进行压测。

1)准备好busybox和nginx镜像,并导入到节点中

[root@master ~]# docker load -i busybox.tar.gz
[root@master ~]# docker load -i nginx-1-9-1.tar.gz

2)启动
启动一个容器,并将无限查询循环发送到 php-apache 服务(复制 k8s 的 master 节点的终端,也就是打开一个新的终端窗口)。

[root@master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
php-apache   ClusterIP   10.105.167.249   <none>        80/TCP    14m[root@master php]# kubectl run v1 -it --image=busybox:latest --image-pull-policy=IfNotPresent -- /bin/sh
# while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done[root@master ~]# kubectl get hpa
NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   194%/50%   1         10        1          22m

# 上面可以看到,CPU 消耗已经达到 194%,每个 pod 的目标 cpu 使用率是 50%,所以,php-apache 这个 deployment 创建的 pod 副本数将调整为 4个副本,为什么是 4 个副本,因为 194/50=3,满足 cpu 使用率上限50%需要4个pod。# 自动扩容到7个副本,满足了需求,直到cpu使用率不超过50%

[root@master ~]# kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   48%/50%   1         10        7          24m[root@master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
php-apache-58857b55d7-skr4b   1/1     Running   0          86s
php-apache-58857b55d7-smkfp   1/1     Running   0          2m27s
php-apache-58857b55d7-vdsdj   1/1     Running   0          3m18s
php-apache-58857b55d7-wfvjg   1/1     Running   0          2m27s
v1                            1/1     Running   0          2m57s

注意:可能需要几分钟来稳定副本数。由于不以任何方式控制负载量,因此最终副本数可能会与此示例不同

# 停止对 php-apache 服务压测,HPA 会自动对 php-apache 这个 deployment 创建的 pod做缩容

[root@master ~]# kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   2%/50%    1         10        7          27m

# 需要一段时间检测才进行缩容

2.3.5 HPA基于内存实现Pod自动扩容

1)导入镜像

[root@master ~]# docker load -i nginx-1-9-1.tar.gz

2)执行yaml文件

[root@master ~]# cat nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-hpa
spec:selector:matchLabels:app: nginxreplicas: 1template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.9.1imagePullPolicy: IfNotPresentports:- containerPort: 80name: httpprotocol: TCPresources:requests:cpu: 0.01memory: 25Milimits:cpu: 0.05memory: 60Mi
---
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:selector:app: nginxtype: NodePortports:- name: httpprotocol: TCPport: 80targetPort: 80

nginx 的 pod 里需要有如下字段,否则 hpa 会采集不到内存指标
resources:
  requests:
    cpu: 0.01
    memory: 25Mi
  limits:
    cpu: 0.05
    memory: 60Mi

[root@master ~]# kubectl apply -f nginx.yaml 
deployment.apps/nginx-hpa created
service/nginx created[root@master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx        NodePort    10.110.32.245   <none>        80:30073/TCP   111s
[root@master manifests]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
nginx-hpa-fb74696c-vtgsg      1/1     Running   0          4m40s
#内存使用率超过60%就扩容
[root@master ~]# cat hpa-v1.yaml 
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:name: nginx-hpa
spec:maxReplicas: 10minReplicas: 1scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: nginx-hpametrics:- type: Resourceresource:name: memorytargetAverageUtilization: 60
[root@master ~]# kubectl apply -f hpa-v1.yaml 
horizontalpodautoscaler.autoscaling/nginx-hpa created[root@master ~]# kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-hpa    Deployment/nginx-hpa    5%/60%    1         10        1          39s

3)压测nginx-hpa,针对内存使用超过60%就自动扩容

压测nginx-hpa
登录到上面通过 pod 创建的 nginx,并生成一个文件,增加内存
[root@master ~]# kubectl exec -it nginx-hpa-fb74696c-vtgsg -- /bin/sh
# dd if=/dev/zero of=/tmp/a# 在新终端里查看
[root@master ~]# kubectl get hpa
NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
nginx-hpa    Deployment/nginx-hpa    125%/60%   1         10        3          15m上面的 targets 列可看到 125%/60%,125%表示当前内存使用率,60%表示所有 pod 的内存使用率维持在 60%,现在内存使用率达到 200%,所以 pod 增加到 3个,新增2个
[root@master ~]# kubectl get pods -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
nginx-hpa-fb74696c-4kmvv   1/1     Running   0          3m21s   10.244.166.156   node1   <none>           <none>
nginx-hpa-fb74696c-vtgsg   1/1     Running   0          25m     10.244.166.141   node1   <none>           <none>
nginx-hpa-fb74696c-x4wnx   1/1     Running   0          3m21s   10.244.166.155   node1   <none>           <none># 当我停止压缩后,hap会对pod自动缩容

如何查看v2版本的hpa如何定义?

[root@master ~]# kubectl get hpa.v2beta2.autoscaling -o yaml > v2.yamlkubectl explain HorizontalPodAutoscaler
kubectl explain HorizontalPodAutoscaler.spec

2.3.6 HPA 基于自定义指标自动扩缩容

除了基于 CPU 和内存来进行自动扩缩容之外,还可以根据自定义的监控指标来进行。这个自定义指标就需要使用 Prometheus Adapter,Prometheus 用于监控应用的负载和集群本身的各种指标,Prometheus Adapter 可以使用 Prometheus 收集的指标并使用它们来制定扩展策略,这些指标都是通过 APIServer 暴露的,而且 HPA 资源对象也可以很轻易的直接使用。

首先部署一个示例应用,在该应用程序上测试 Prometheus 指标自动缩放,资源清单文件如下所示:(hpa-prome-demo.yaml) 

apiVersion: apps/v1
kind: Deployment
metadata:name: hpa-prom-demo
spec:selector:matchLabels:app: nginx-servertemplate:metadata:labels:app: nginx-serverspec:containers:- name: nginx-demoimage: cnych/nginx-vts:v1.0resources:limits:cpu: 50mrequests:cpu: 50mports:- containerPort: 80name: http
---
apiVersion: v1
kind: Service
metadata:name: hpa-prom-demoannotations:prometheus.io/scrape: "true"prometheus.io/port: "80"prometheus.io/path: "/status/format/prometheus"
spec:ports:- port: 80targetPort: 80name: httpselector:app: nginx-servertype: NodePort

这里部署的应用是在 80 端口的 /status/format/prometheus 这个端点暴露 nginx-vts 指标的,前面已经在 Prometheus 中配置了 Endpoints 的自动发现,所以直接在 Service 对象的 annotations 中进行配置,这样就可以在 Prometheus 中采集该指标数据了。为了测试方便,这里使用 NodePort 类型的 Service,现在直接创建上面的资源对象即可:

$ kubectl apply -f hpa-prome-demo.yaml
deployment.apps/hpa-prom-demo created
service/hpa-prom-demo created
$ kubectl get pods -l app=nginx-server 
NAME                             READY   STATUS    RESTARTS   AGE
hpa-prom-demo-755bb56f85-lvksr   1/1     Running   0          4m52s
$ kubectl get svc 
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
hpa-prom-demo   NodePort    10.101.210.158   <none>        80:32408/TCP   5m44s
......

部署完成后可以使用如下命令测试应用是否正常,以及指标数据接口能够正常获取:

$ curl http://k8s.qikqiak.com:32408
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
$ curl http://k8s.qikqiak.com:32408/status/format/prometheus 
# HELP nginx_vts_info Nginx info
# TYPE nginx_vts_info gauge
nginx_vts_info{hostname="hpa-prom-demo-755bb56f85-lvksr",version="1.13.12"} 1
# HELP nginx_vts_start_time_seconds Nginx start time
# TYPE nginx_vts_start_time_seconds gauge
nginx_vts_start_time_seconds 1586240091.623
# HELP nginx_vts_main_connections Nginx connections
# TYPE nginx_vts_main_connections gauge
......

上面的指标数据中,nginx_vts_server_requests_total 这个指标表示请求总数,是一个 Counter 类型的指标,可以使用该指标的值来确定是否需要对应用进行自动扩缩容

 

接下来将 Prometheus-Adapter 安装到集群中,并添加一个规则来跟踪 Pod 的请求,可以将 Prometheus 中的任何一个指标都用于 HPA,但是前提是得通过查询语句将它拿到(包括指标名称和其对应的值)。

定义一个如下所示的规则:

rules:
- seriesQuery: 'nginx_vts_server_requests_total'seriesFilters: []resources:overrides:kubernetes_namespace:resource: namespacekubernetes_pod_name:resource: podname:matches: "^(.*)_total"as: "${1}_per_second"metricsQuery: (sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>))

这是一个带参数的 Prometheus 查询,其中:

  • seriesQuery:查询 Prometheus 的语句,通过这个查询语句查询到的所有指标都可以用于 HPA
  • seriesFilters:查询到的指标可能会存在不需要的,可以通过它过滤掉。
  • resources:通过 seriesQuery 查询到的只是指标,如果需要查询某个 Pod 的指标,肯定要将它的名称和所在的命名空间作为指标的标签进行查询,resources 就是将指标的标签和 k8s 的资源类型关联起来,最常用的就是 pod 和 namespace。有两种添加标签的方式,一种是 overrides,另一种是 template

  • overrides:它会将指标中的标签和 k8s 资源关联起来。上面示例中就是将指标中的 pod 和 namespace 标签和 k8s 中的 pod 和 namespace 关联起来,因为 pod 和 namespace 都属于核心 api 组,所以不需要指定 api 组。当我们查询某个 pod 的指标时,它会自动将 pod 的名称和名称空间作为标签加入到查询条件中。比如 nginx: {group: "apps", resource: "deployment"} 这么写表示的就是将指标中 nginx 这个标签和 apps 这个 api 组中的 deployment 资源关联起来;
  • template:通过 go 模板的形式。比如template: "kube_<<.Group>>_<<.Resource>>" 这么写表示,假如 <<.Group>> 为 apps,<<.Resource>> 为 deployment,那么它就是将指标中 kube_apps_deployment 标签和 deployment 资源关联起来。
  • name:用来给指标重命名的,之所以要给指标重命名是因为有些指标是只增的,比如以 total 结尾的指标。这些指标拿来做 HPA 是没有意义的,我们一般计算它的速率,以速率作为值,那么此时的名称就不能以 total 结尾了,所以要进行重命名。 
  • matches:通过正则表达式来匹配指标名,可以进行分组
  • as:默认值为 $1,也就是第一个分组。as 为空就是使用默认值的意思。
  • metricsQuery:这就是 Prometheus 的查询语句了,前面的 seriesQuery 查询是获得 HPA 指标。当我们要查某个指标的值时就要通过它指定的查询语句进行了。可以看到查询语句使用了速率和分组,这就是解决上面提到的只增指标的问题。 
  • Series:表示指标名称
  • LabelMatchers:附加的标签,目前只有 pod 和 namespace 两种,因此我们要在之前使用 resources 进行关联
  • GroupBy:就是 pod 名称,同样需要使用 resources 进行关联。

接下来我们通过 Helm Chart 来部署 Prometheus Adapter,新建 hpa-prome-adapter-values.yaml 文件覆盖默认的 Values 值,内容如下所示:

rules:default: falsecustom:- seriesQuery: 'nginx_vts_server_requests_total'resources: overrides:kubernetes_namespace:resource: namespacekubernetes_pod_name:resource: podname:matches: "^(.*)_total"as: "${1}_per_second"metricsQuery: (sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>))prometheus:url: http://thanos-querier.kube-mon.svc.cluster.local

这里我们添加了一条 rules 规则,然后指定了 Prometheus 的地址,我们这里是使用了 Thanos 部署的 Promethues 集群,所以用 Querier 的地址。使用下面的命令一键安装:

$ helm install prometheus-adapter stable/prometheus-adapter -n kube-mon -f hpa-prome-adapter-values.yaml
NAME: prometheus-adapter
LAST DEPLOYED: Tue Apr  7 15:26:36 2020
NAMESPACE: kube-mon
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
prometheus-adapter has been deployed.
In a few minutes you should be able to list metrics using the following command(s):kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1

等一小会儿,安装完成后,可以使用下面的命令来检测是否生效了:

$ kubectl get pods -n kube-mon -l app=prometheus-adapter
NAME                                  READY   STATUS    RESTARTS   AGE
prometheus-adapter-58b559fc7d-l2j6t   1/1     Running   0          3m21s
$  kubectl get --raw="/apis/custom.metrics.k8s.io/v1beta1" | jq
{"kind": "APIResourceList","apiVersion": "v1","groupVersion": "custom.metrics.k8s.io/v1beta1","resources": [{"name": "namespaces/nginx_vts_server_requests_per_second","singularName": "","namespaced": false,"kind": "MetricValueList","verbs": ["get"]},{"name": "pods/nginx_vts_server_requests_per_second","singularName": "","namespaced": true,"kind": "MetricValueList","verbs": ["get"]}]
}

我们可以看到 nginx_vts_server_requests_per_second 指标可用。 现在,让我们检查该指标的当前值:

$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/nginx_vts_server_requests_per_second" | jq .
{"kind": "MetricValueList","apiVersion": "custom.metrics.k8s.io/v1beta1","metadata": {"selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/nginx_vts_server_requests_per_second"},"items": [{"describedObject": {"kind": "Pod","namespace": "default","name": "hpa-prom-demo-755bb56f85-lvksr","apiVersion": "/v1"},"metricName": "nginx_vts_server_requests_per_second","timestamp": "2020-04-07T09:45:45Z","value": "527m","selector": null}]
}

出现类似上面的信息就表明已经配置成功了,接下来我们部署一个针对上面的自定义指标的 HPA资源对象,如下所示:(hpa-prome.yaml)

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:name: nginx-custom-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: hpa-prom-demominReplicas: 2maxReplicas: 5metrics:- type: Podspods:metricName: nginx_vts_server_requests_per_secondtargetAverageValue: 10

如果请求数超过每秒10个,则将对应用进行扩容。直接创建上面的资源对象:

$ kubectl apply -f hpa-prome.yaml
horizontalpodautoscaler.autoscaling/nginx-custom-hpa created
$ kubectl describe hpa nginx-custom-hpa
Name:                                              nginx-custom-hpa
Namespace:                                         default
Labels:                                            <none>
Annotations:                                       kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"autoscaling/v2beta1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"nginx-custom-hpa","namespace":"d...
CreationTimestamp:                                 Tue, 07 Apr 2020 17:54:55 +0800
Reference:                                         Deployment/hpa-prom-demo
Metrics:                                           ( current / target )"nginx_vts_server_requests_per_second" on pods:  <unknown> / 10
Min replicas:                                      2
Max replicas:                                      5
Deployment pods:                                   1 current / 2 desired
Conditions:Type         Status  Reason            Message----         ------  ------            -------AbleToScale  True    SucceededRescale  the HPA controller was able to update the target scale to 2
Events:Type    Reason             Age   From                       Message----    ------             ----  ----                       -------Normal  SuccessfulRescale  7s    horizontal-pod-autoscaler  New size: 2; reason: Current number of replicas below Spec.MinReplicas

 可以看到 HPA 对象已经生效了,会应用最小的副本数2,所以会新增一个 Pod 副本:

$ kubectl get pods -l app=nginx-server
NAME                             READY   STATUS    RESTARTS   AGE
hpa-prom-demo-755bb56f85-s5dzf   1/1     Running   0          67s
hpa-prom-demo-755bb56f85-wbpfr   1/1     Running   0          3m30s

接下来我们同样对应用进行压测:

$ while true; do wget -q -O- http://k8s.qikqiak.com:32408; done

 打开另外一个终端观察 HPA 对象的变化:

$ kubectl get hpa
NAME               REFERENCE                  TARGETS     MINPODS   MAXPODS   REPLICAS   AGE
nginx-custom-hpa   Deployment/hpa-prom-demo   14239m/10   2         5         2          4m27s
$ kubectl describe hpa nginx-custom-hpa
Name:                                              nginx-custom-hpa
Namespace:                                         default
Labels:                                            <none>
Annotations:                                       kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"autoscaling/v2beta1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"nginx-custom-hpa","namespace":"d...
CreationTimestamp:                                 Tue, 07 Apr 2020 17:54:55 +0800
Reference:                                         Deployment/hpa-prom-demo
Metrics:                                           ( current / target )"nginx_vts_server_requests_per_second" on pods:  14308m / 10
Min replicas:                                      2
Max replicas:                                      5
Deployment pods:                                   3 current / 3 desired
Conditions:Type            Status  Reason              Message----            ------  ------              -------AbleToScale     True    ReadyForNewScale    recommended size matches current sizeScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from pods metric nginx_vts_server_requests_per_secondScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable range
Events:Type    Reason             Age   From                       Message----    ------             ----  ----                       -------Normal  SuccessfulRescale  5m2s  horizontal-pod-autoscaler  New size: 2; reason: Current number of replicas below Spec.MinReplicasNormal  SuccessfulRescale  61s   horizontal-pod-autoscaler  New size: 3; reason: pods metric nginx_vts_server_requests_per_second above target

可以看到指标 nginx_vts_server_requests_per_second 的数据已经超过阈值了,触发扩容动作了,副本数变成了3,但是后续很难继续扩容了,这是因为上面我们的 while 命令并不够快,3个副本完全可以满足每秒不超过 10 个请求的阈值。

如果需要更好的进行测试,我们可以使用一些压测工具,比如 ab、fortio 等工具。当我们中断测试后,默认5分钟过后就会自动缩容:

$ kubectl describe hpa nginx-custom-hpa
Name:                                              nginx-custom-hpa
Namespace:                                         default
Labels:                                            <none>
Annotations:                                       kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"autoscaling/v2beta1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"nginx-custom-hpa","namespace":"d...
CreationTimestamp:                                 Tue, 07 Apr 2020 17:54:55 +0800
Reference:                                         Deployment/hpa-prom-demo
Metrics:                                           ( current / target )"nginx_vts_server_requests_per_second" on pods:  533m / 10
Min replicas:                                      2
Max replicas:                                      5
Deployment pods:                                   2 current / 2 desired
Conditions:Type            Status  Reason            Message----            ------  ------            -------AbleToScale     True    ReadyForNewScale  recommended size matches current sizeScalingActive   True    ValidMetricFound  the HPA was able to successfully calculate a replica count from pods metric nginx_vts_server_requests_per_secondScalingLimited  True    TooFewReplicas    the desired replica count is less than the minimum replica count
Events:Type    Reason             Age   From                       Message----    ------             ----  ----                       -------Normal  SuccessfulRescale  23m   horizontal-pod-autoscaler  New size: 2; reason: Current number of replicas below Spec.MinReplicasNormal  SuccessfulRescale  19m   horizontal-pod-autoscaler  New size: 3; reason: pods metric nginx_vts_server_requests_per_second above targetNormal  SuccessfulRescale  4m2s  horizontal-pod-autoscaler  New size: 2; reason: All metrics below target

到这里我们就完成了使用自定义的指标对应用进行自动扩缩容的操作。如果 Prometheus 安装在我们的 Kubernetes 集群之外,则只需要确保可以从集群访问到查询的端点,并在 adapter 的部署清单中对其进行更新即可。在更复杂的场景中,可以获取多个指标结合使用来制定扩展策略。 

这篇关于Kubernetes实战(二十七)-HPA实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/691508

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

什么是Kubernetes PodSecurityPolicy?

@TOC 💖The Begin💖点点关注,收藏不迷路💖 1、什么是PodSecurityPolicy? PodSecurityPolicy(PSP)是Kubernetes中的一个安全特性,用于在Pod创建前进行安全策略检查,限制Pod的资源使用、运行权限等,提升集群安全性。 2、为什么需要它? 默认情况下,Kubernetes允许用户自由创建Pod,可能带来安全风险。

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

springboot实战学习(1)(开发模式与环境)

目录 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 (3)前端 二、开发模式 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 Validation:做参数校验Mybatis:做数据库的操作Redis:做缓存Junit:单元测试项目部署:springboot项目部署相关的知识 (3)前端 Vite:Vue项目的脚手架Router:路由Pina:状态管理Eleme