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 的部署清单中对其进行更新即可。在更复杂的场景中,可以获取多个指标结合使用来制定扩展策略。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/675192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NGINX upstream、stream、四/七层负载均衡以及案例示例

文章目录 前言1. 四/七层负载均衡1.1 开放式系统互联模型 —— OSI1.2 四/七层负载均衡 2. Nginx七层负载均衡2.1 upstream指令2.2 server指令和负载均衡状态与策略2.2.1 负载均衡状态2.2.2 负载均衡策略 2.3 案例 3. Nginx四层负载均衡的指令3.1 stream3.2 upstream指令3.3 四…

深入理解ES的倒排索引

目录 数据写入过程 词项字典 term dictionary 倒排表 posting list FOR算法 RBM算法 ArrayContainer BitMapContainer 词项索引 term index 在Elasticsearch中&#xff0c;倒排索引的设计无疑是惊为天人的&#xff0c;下面看下倒排索引的结构。 倒排索引分为词项索引【…

JS中常用占位符使用方法详解_ |%s|%d|%f|%o|%O|%c|

在 JavaScript 中&#xff0c;%s 是一种字符串格式化占位符&#xff0c;用于将字符串插入到另一个字符串中的指定位置。这种方法基于 C 语言的 printf() 函数&#xff0c;但在 JavaScript 中有一些变化。 在 JavaScript 中&#xff0c;%s 可以接受任何类型的值&#xff0c;并将…

上市公司人工智能转型指数及55个工具变量汇总数据集(2024.2月更新)

一、“智能化转型”发文趋势和主题分布 二、数据来源 上市公司年报、官网&#xff0c;中国知网及各期刊官网等三、时间跨度 工具变量&#xff1a;2022-2024年&#xff1b; 上市公司人工智能转型指数&#xff1a;2007-2021年四、数据范围 中国A股上市公司五、数据展示 序号…

一键部署自动化运维工具spug

简介 Spug是面向中小型企业设计的轻量级无Agent的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、应用发布部署、在线任务计划、配置中心、监控、报警等一系列功能。 部署 1.创建目录 mkdir -p /opt/spug/{mysql,service,repos} 2.进入目录 cd /o…

Modern C++ 内存篇1 - allocator

1. 前言 从今天起我们开始内存相关的话题&#xff0c;内存是个很大的话题&#xff0c;一时不知从何说起。内存离不开allocator&#xff0c;我们就从allocator开始吧。allocator目前有两种&#xff1a;std::allocator, std::pmr::polymorphic_allocator&#xff0c;各有优缺点。…

Vue源码系列讲解——虚拟DOM篇【二】(Vue中的DOM-Diff)

目录 1. 前言 2. patch 3. 创建节点 4. 删除节点 5. 更新节点 6. 总结 1. 前言 在上一篇文章介绍VNode的时候我们说了&#xff0c;VNode最大的用途就是在数据变化前后生成真实DOM对应的虚拟DOM节点&#xff0c;然后就可以对比新旧两份VNode&#xff0c;找出差异所在&…

docker 基于容器创建本地web容器化镜像

一、docker 基于容器创建本地web容器化镜像 1、启动指定buysbox 镜像 docker run --name b1 -it busybox:latest 2、创建目录&#xff0c;并创建html mkdir -p /data/html vi index.html 内容自定义例如&#xff1a;<h1>welcome to busybox<h1> 3、新增窗口&am…

ubuntu22.04 安装部署05:禁用默认显卡驱动

一、相关文章 ubuntu22.04安装部署03&#xff1a; 设置root密码-CSDN博客 《ubuntu22.04装部署01&#xff1a;禁用内核更新》 《ubuntu22.04装部署02&#xff1a;禁用显卡更新》 二、场景说明 Ubuntu22.04 默认显卡驱动&#xff0c;如果安装cuda&#xff0c;需要单独安装显…

Android开发 button 按钮点击两次 响应onclick方法

问题 Android开发 button 按钮点击两次 响应onclick方法 详细问题 笔者xml代码 <!-- 一个按钮 --> <Button android:id"id/button1" android:layout_width"wrap_conten…

Conda历史版本下载地址和python对应关系

一、前言 因为Conda安装版本问题&#xff0c;带来了很多问题&#xff0c;虽然不能直接确定二者之间的关系&#xff0c;但是安装指定版本的conda,确实是一个比较好的方法。特此记忆。 二、下载地址 下载最新版本&#xff1a;Free Download | Anaconda 下载历史版本&#xff…

Xcode配置GLFW GLAD (MAC)

这里的GLFW用的是静态链接 博主反复修改&#xff0c;实在是没能找到为什么用动态会出现线程报错 下载GLAD:版本我一般是选倒数第二新&#xff0c;profile记得选core 点击GENRATE 点glad.zip获得下载 下载GLFW 点击download 最后&#xff0c;将两个文件都放到项目里面去 打开…

形态学操作之开操作与闭操作的python实现——数字图像处理

原理 图像处理中的开操作&#xff08;Opening&#xff09;和闭操作&#xff08;Closing&#xff09;是形态学&#xff08;Morphological&#xff09;操作的两个基本类型&#xff0c;它们都是基于膨胀&#xff08;Dilation&#xff09;和腐蚀&#xff08;Erosion&#xff09;操…

基于PHP的学生管理系统

前言 基于PHP的学生管理系统&#xff1b; 实现 登录、注册、学生信息、修改学生、删除学生、查询学生、添加学生等功能 &#xff1b; 环境准备 开发平台&#xff1a;PhpStrom2022.1.2 、Phpstudy_pro 数据库&#xff1a;MySQL5.7.26 技术架构 Bootstrap PHP7.3.4html5css3 项目…

系统架构21 - 统一建模语言UML(下)

UML图 UML中的图分类作用 视图用例视图逻辑视图进程视图实现视图部署视图 UML中的图 “图”是一组元素的图形表示&#xff0c;大多数情况下把图画成顶点&#xff08;代表事物&#xff09;和弧&#xff08;代表关系&#xff09;的连通图。为了对系统进行可视化&#xff0c;可以…

运维高级篇-分库分表(拆分策略详解)

分库分表 介绍 问题分析 随着互联网及移动互联网的发展&#xff0c;应用系统的数据量也是成指数式增长&#xff0c;若采用单数据库进行数据存 储&#xff0c;存在以下性能瓶颈&#xff1a; IO瓶颈&#xff1a;热点数据太多&#xff0c;数据库缓存不足&#xff0c;产生大量磁盘…

关节点检测

https://www.bilibili.com/video/BV19g4y1777q/?p2&spm_id_frompageDriver 关节点检测全流程 YOLO:单阶段&#xff0c;快&#xff1b; MMPose&#xff1a;双阶段&#xff0c;准&#xff1b; 标注工具Labelme 用Labelme标注样本数据集

电脑通电自启动设置

首先要进入BIOS&#xff0c;以华硕为例&#xff0c;按下电源键&#xff0c;在开机之前按下delete键&#xff0c;其他电脑可能是esc或者某个f键&#xff0c;请自行查找。 进入BIOS后要找到电源管理&#xff0c;可以在高级选项中找一找&#xff0c;如上图右下角选择高级模式。 …

PKI - 借助Nginx 实现Https 服务端单向认证、服务端客户端双向认证

文章目录 Openssl操系统默认的CA证书的公钥位置Nginx Https 自签证书Nginx Https 使用CA签发证书客户端使用自签证书供服务端验证客户端使用 根证书 签发客户端证书 供服务端验证 Openssl https://www.openssl.net.cn/ openssl是一个功能丰富且自包含的开源安全工具箱。 它提…

2024腾讯云游戏服务器租用多少钱一年?

2024年更新腾讯云游戏联机服务器配置价格表&#xff0c;可用于搭建幻兽帕鲁、雾锁王国等游戏服务器&#xff0c;游戏服务器配置可选4核16G12M、8核32G22M、4核32G10M、16核64G35M、4核16G14M等配置&#xff0c;可以选择轻量应用服务器和云服务器CVM内存型MA3或标准型SA2实例&am…