写点什么

根据 Nginx Ingress 指标对指定后端进行 HPA

  • 2024-04-22
    广东
  • 本文字数:3020 字

    阅读完需:约 10 分钟

根据Nginx Ingress指标对指定后端进行HPA

本文分享自华为云社区《根据Nginx Ingress指标对指定后端进行HPA》,作者: 可以交个朋友。

背景


生产场景下,Nginx Ingress 的流量会通过域名和 path 路径最终转发至不同的应用,而有时候 cpu 和内存并不是 nginx 的性能瓶颈,此时可以基于nginx_ingress_controller_requests指标,为其对应的应用配置 HPA,以实现基于不同域名和 path 的请求量弹性指定后端工作负载

简介


环境准备


  • nginx-ingress 已部署

  • 云原生监控插件 kube-prometheus-stack 已安装(server 模式),插件默认监控 nginx-ingress,开源环境请自行配置监控。

  • 已配置 kubectl 命令或使用 cloudshell


注意:由于 HPA 规则中scaleTargetRefdescribedObject两个字段都无法指定命名空间,所以指标来源、HPA 和弹性目标需在同一命名空间,而 nginx-ingress 和业务工作负载一般处在不同命名空间;本次方案采用 external 类型的 HPA,可以忽略指标来源的命名空间

操作步骤


创建演示需要的弹性目标工作负载,service 以及 ingress


apiVersion: apps/v1 kind: Deployment metadata:   name: test-hpa   labels:     app: test-app spec:   replicas: 1   selector:     matchLabels:       app: test-app   template:     metadata:       labels:         app: test-app     spec:       containers:       - image: skto/sample-app:v2         name: metrics-provider         ports:         - name: http           containerPort: 8080 --- apiVersion: v1 kind: Service metadata:   name: test-app   namespace: default   labels:     app: test-app spec:   ports:     - port: 8080       name: http       protocol: TCP       targetPort: 8080   selector:     app: test-app   type: ClusterIP 
--- apiVersion: apps/v1 kind: Deployment metadata: name: sample-app labels: app: sample-app spec: replicas: 1 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - image: skto/sample-app:v2 name: metrics-provider ports: - name: http containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: sample-app namespace: default labels: app: sample-app spec: ports: - port: 80 name: http protocol: TCP targetPort: 8080 selector: app: sample-app type: ClusterIP --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress namespace: default spec: ingressClassName: nginx rules: - host: test.example.com http: paths: - backend: service: name: sample-app port: number: 80 path: / pathType: ImplementationSpecific - backend: service: name: test-app port: number: 8080 path: /home pathType: ImplementationSpecific
复制代码


分别查询test.example.com/test.example.com/home的 nginx_ingress_controller_requests 指标,指标正常




创建 external 类型的 apiservices 资源;创建后 apiservices 的状态为 false 是正常现象,添加 externalRules 后状态变为 true


apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata:   name: v1beta1.external.metrics.k8s.io spec:   group: external.metrics.k8s.io   groupPriorityMinimum: 100   insecureSkipTLSVerify: true   service:         #指定prometheus-adapter对应的service,华为CCE插件中adapter名称为custom-metrics-apiserver     name: custom-metrics-apiserver     namespace: monitoring     port: 443   version: v1beta1   versionPriority: 100
复制代码


将 externalRules 规则添加到 adapter 的 configmap 中,修改后需要重启 prometheus-adapter 服务


kubectl -n monitoring edit configmap user-adapter-config
复制代码



externalRules: - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)   name:     as: ${1}_per_second     matches: ^(.*)   resources:     namespaced: false  #忽略指标来源的命名空间,该配置不适用rules规则   seriesQuery: nginx_ingress_controller_requests
复制代码


seriesQuery:原始指标;可以直接写指标名称,也可以使用{labelKey=labelValue}的方式筛选出原始指标


metricsQuery:用 PromQL 对指标进行筛选汇聚;.Series表示原始指标,.LabelMatchers表示对指标进行标签筛选,hpa 中可以配置具体的筛选规则


name:将指标重命名


resources:hpa 查询指标时通过 api 的方式调用,调用路径为:



而 resources 的作用就是将指标中命名空间标签的值替换路径中的 ${namespace},而我们本次方案需要忽略指标来源命名空间。


custom-metrics-apiserver 服务重启后需要等待 1 分钟左右,执行命令查看指标是否正常


kubectl get --raw /apis/external.metrics.k8s.io/v1beta1/namespaces/*/nginx_ingress_controller_requests_per_second
复制代码



创建 HPA 规则


apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata:   name: sample-hpa spec:   scaleTargetRef:     apiVersion: apps/v1     kind: Deployment     name: sample-app   minReplicas: 1   maxReplicas: 10   metrics:     - type: External       external:         metric:           name: nginx_ingress_controller_requests_per_second           selector:             matchLabels:    #可以通过该字段对指标进行过滤,这里标签筛选条件会加入到externalRules的<<.LabelMatchers>>中。               exported_service: sample-app  #筛选后端服务为sample-app的请求               host: test.example.com        #筛选访问域名为test.example.com的请求         target:           type: AverageValue   #External指标类型下只支持Value和AverageValue类型的目标值。           averageValue: 30 --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata:   name: test-hpa spec:   scaleTargetRef:     apiVersion: apps/v1     kind: Deployment     name: test-app   minReplicas: 1   maxReplicas: 10   metrics:     - type: External       external:         metric:           name: nginx_ingress_controller_requests_per_second           selector:             matchLabels:               exported_service: test-app               host: test.example.com         target:           type: AverageValue           averageValue: 30
复制代码


弹性演示


使用命令压测 sample-app 对应的访问域名和路径,正常触发弹性;请自行配置域名与 ELB 地址的映射


ab -c 50 -n 5000 http://test.example.com/
复制代码



用同样的方式压测 test-app,正常触发弹性


ab -c 50 -n 5000 http://test.example.com/home
复制代码



点击关注,第一时间了解华为云新鲜技术~

发布于: 2024-04-22阅读数: 2
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
根据Nginx Ingress指标对指定后端进行HPA_nginx_华为云开发者联盟_InfoQ写作社区