前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用NSX高级负载均衡度量值水平扩缩(HPA)容器实例

使用NSX高级负载均衡度量值水平扩缩(HPA)容器实例

作者头像
我是阳明
发布2021-06-25 17:04:03
7050
发布2021-06-25 17:04:03
举报
文章被收录于专栏:k8s技术圈k8s技术圈
tags: Avi

承接上一篇, 使用NSX高级负载均衡(以下简称ALB)度量值触发后端虚拟机池水平扩缩, 本篇讲讲容器环境中使用ALB度量值触发容器的水平扩缩(HPA: Horizontal Pod Autoscaler). 我们的目标是监控ALB上某个L7 VS(Virtual Service)或Pool的度量值, 当度量值达到某个预设值时, 触发HPA, 扩展Pod实例.

可行性方案

关于ALB度量值:

查询ALB文档

代码语言:javascript
复制
https://avinetworks.com/docs/20.1/avi-vantage-prometheus-integration/

发现ALB很早就支持将控制器 / 虚拟服务(VS) / 后端池(Pool) / 服务引擎(SE or LB) 的各度量值以Prometheus格式暴露. 文档中也描述了抓取的API路径和方法, 另外所有的度量值分类都在Metrics List文档中有详细描述:

代码语言:javascript
复制
https://avinetworks.com/docs/20.1/metrics-list/#vmware-metrics

关于HPA:

查询HPA文档, 发现HPA V1并不支持自定义度量值, 只能通过Metrics-Server提供的CPU / Men使用率来做水平扩缩策略. 但文档中有提到HPA V2beta2可以支持custom.metrics & external.metrics. 那么我们的思路就变成了, 如果使用Prometheus将抓取的ALB度量值暴露到K8s的custom.metrics中去, 让HPA V2beta2查询到.

关于Prometheus: 经过一轮搜索, 得知了Prometheus Adapter这个项目可以将Prometheus抓取的度量值暴露在custom.metrics & external.metrics. 该项目描述如下:

This repository contains an implementation of the Kubernetes resource metrics, custom metrics, and external metrics APIs. This adapter is therefore suitable for use with the autoscaling/v2 Horizontal Pod Autoscaler in Kubernetes 1.6+. It can also replace the metrics server on clusters that already run Prometheus and collect the appropriate metrics.

另外还好社区里有kube-prometheus这样的项目来简化安装与集成, 同时可以使用Prometheus Operator来简化配置Prometheus抓取配置.(不然我可能坚持不下去, 原生的抓取规则看了一眼就头大.)

逻辑导图

  • ALB承担K8s集群负载均衡(LB)和服务入口(Ingress)
  • ALB默认对服务引擎(SE)进行度量值采样, 并以Prometheus格式暴露
  • ALB设置为基本认证模式, 方便Prometheus使用用户名密码认证后抓取度量值
  • 制作ServiceMonitor(Prometheus Opretor的CRD)配置Prometheus抓取参数, 如认证, 目标地址, 度量值, 间隔等.
  • 查看v1beta1.metrics.k8s.io, 检查Prometheus Adapter是否成功暴露自定义度量值
  • 制作HPA, 预设扩缩阀值
  • 压力测试

测试拓扑

特点:

  • 使用NSX-T作为CNI, 为容器提供可路由环境. 服务引擎(SE)路由可达Pod避免了Kube-Proxy SNAT的参与, 更好的健康检测.
  • AKO(ALB K8s Operator)监听K8s集群内LB和Ingress的请求, 自动配置服务引擎实现发布.

准备工作

CNI当然推荐NSX-T, 毕竟Pod可路由省去很多麻烦. 如果觉得NSX-T集成有难度可以考虑使用VMware开源CNI Antrea, 独有的NodeportLocal也能很好的规避Kube-Proxy的NAT, 也能实现LB对Pod的健康检查(可以考虑下篇做个简短的Demo).

安装K8s(废话)

安装AKO:

配置ALB控制器API采用基础认证:

安装Prometheus Operator:

安装Prometheus Operator微信公众号文章:

集成过程相当折磨, Prometheus体系也是很大的, 还好Operator对其操作做了简化. 过程需要趟坑的话欢迎小窗.

配置环节

找一个你喜欢的Web应用发布成Ingress, SVC Type LB也行. 我使用的是Kuard.

代码语言:javascript
复制
root@ubuk8s-c3-vm01:/# kubectl get ingress -n routing-ns1
NAME            CLASS    HOSTS                       ADDRESS          PORTS   AGE
kuard-ingress   <none>   kuard.nsx.rockhomelab.org   192.168.30.103   80      13d

ALB相应后获得VIP: 192.168.30.103, 可以在ALB控制器界面中确认. 同时也可以发现, 后端池成员就是Pod IP.

获取目标Pool Name. 其实这一步也可以直接用VS Name, 但当时我没有设置每个Ingress生成独立的VS, 所以就选择了用Pool级别的度量值.

然后配置Prometheus抓取该Pool的度量值, 我这里选择了Pool级别的度量值: l4_server.avg_open_conns.

  1. 制作伪SVC: avilb, 与发布的Pod在同一Namespace. 手工为伪SVC添加Endpoint, 即ALB控制器地址
代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  labels:
    lbaas: avi
  name: avilb
  namespace: routing-ns1
spec:
  clusterIP: None
  ports:
  - name: metrics
    port: 443
    targetPort: 443
  selector: null

---
apiVersion: v1
kind: Endpoints
metadata:
  labels:
    lbaas: avi
  name: avilb
  namespace: routing-ns1
subsets:
- addresses:
  - ip: 192.168.31.246
  ports:
  - name: metrics
    port: 443
    protocol: TCP

制作完后可以查询确认: SVC中selector为空时, 会选择与SVC名字一样的Endpoint作为成员.

代码语言:javascript
复制
root@ubuk8s-c3-vm01:/# kubectl get svc -n routing-ns1
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
avilb           ClusterIP   None             <none>        443/TCP   16d
kuard-service   ClusterIP   10.100.172.103   <none>        80/TCP    16d
root@ubuk8s-c3-vm01:/# kubectl get endpoints -n routing-ns1
NAME            ENDPOINTS            AGE
avilb           192.168.31.246:443   16d
kuard-service   192.169.32.5:8080    16d
root@ubuk8s-c3-vm01:/#
  1. 制作Secret, 写入ALB控制器用户名密码, 待会Prometheus抓取时需要:
代码语言:javascript
复制
kubectl create secret -n routing-ns1 generic avi-basic-auth --from-literal=username='admin' --from-literal=password='VMware1!VMware1!'
  1. 制作ServiceMonitor
代码语言:javascript
复制
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: avilb-servicemonitor
  namespace: routing-ns1
  labels:
    lbaas: avi # This is what the prometheus1 CR looking for match
spec:
  endpoints:
  - path: '/api/analytics/prometheus-metrics/pool/'
    params:
      entity_name:
        - k8s-03-cluster--kuard.nsx.rockhomelab.org_-routing-ns1-kuard-ingress
      metric_id: 
        - l4_server.avg_open_conns
    scheme: https
    port: metrics
    tlsConfig:
      insecureSkipVerify: true 
    basicAuth:
      password:
        name: avi-basic-auth
        key: password
      username:
        name: avi-basic-auth
        key: username
  jobLabel: lbaas
  namespaceSelector:
    matchNames:
    - routing-ns1
  selector:
    matchLabels:
      lbaas: avi

登录到Prometheus, 在Targets中查看自定义抓取的ALB度量值状态是否正常. 可选将该度量值图表添加到Grafana中.

确保Prometheus Adaptor 已经将该自定义度量值暴露了在 custom.metrics.k8s.io/v1beta1中, 使用kubectl get --raw来验证. 由于Prometheus的时区是UTC0, 并且是Hard code在程序里的, 显示的时间戳会有8小时“时差”. Grafana中可以在UI中设置本地时区, 可以解决现实问题.

代码语言:javascript
复制
kubectl get --raw="/apis/custom.metrics.k8s.io/v1beta1/namespaces/routing-ns1/services/avilb/avi_l4_server_avg_open_conns/" |jq
{
  "kind": "MetricValueList",
  "apiVersion": "custom.metrics.k8s.io/v1beta1",
  "metadata": {
    "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/routing-ns1/services/avilb/avi_l4_server_avg_open_conns/"
  },
  "items": [
    {
      "describedObject": {
        "kind": "Service",
        "namespace": "routing-ns1",
        "name": "avilb",
        "apiVersion": "/v1"
      },
      "metricName": "avi_l4_server_avg_open_conns",
      "timestamp": "2021-05-30T05:54:25Z",
      "value": "0"
    }
  ]
}
  1. 制作HPA

根据文档提供的水平扩展的公式:

代码语言:javascript
复制
期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]

我们将期望指标设置在200, Pod副本最大扩展到5个.

代码语言:javascript
复制
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-kuard-l4metric
  namespace: routing-ns1
spec:
  maxReplicas: 5
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: kuard-deployment
  metrics:
    - type: Object
      object:
        metric:
          name: avi_l4_server_avg_open_conns
        describedObject:
          apiVersion: v1
          kind: Service
          name: avilb
        target:
          type: Value
          value: 200

HPA是Namespace级别的对象, 所以刚才在制作伪SVC时也要放在相同的Namespace内.

  1. 压测

还是请出我们的Locust, 模拟1000个用户连接访问VIP. 这次我们对比三个图形界面观察度量值变化. 压测从下午15:08分开始, 截止时间15:30分. 1000个Users, 每秒孵化5个.

ALB控制界面, Pod实例扩展到5个, 轮询模式接受连接.

Grafana界面清楚的现实, 最开始只有一个Pod, 当HPA生效后, 5个Pod的度量值为该Pool L4 Open Connection的总值.

查看HPA所在的Namespace可以观察到事件的触发过程.

代码语言:javascript
复制
32m         Normal    SuccessfulCreate               replicaset/kuard-deployment-5c55bf6c         Created pod: kuard-deployment-5c55bf6c-jnxzv
32m         Normal    SuccessfulCreate               replicaset/kuard-deployment-5c55bf6c         Created pod: kuard-deployment-5c55bf6c-khzqt
32m         Normal    SuccessfulCreate               replicaset/kuard-deployment-5c55bf6c         Created pod: kuard-deployment-5c55bf6c-78csp
31m         Normal    SuccessfulCreate               replicaset/kuard-deployment-5c55bf6c         Created pod: kuard-deployment-5c55bf6c-hndwq
2m15s       Normal    SuccessfulDelete               replicaset/kuard-deployment-5c55bf6c         Deleted pod: kuard-deployment-5c55bf6c-78csp
2m15s       Normal    SuccessfulDelete               replicaset/kuard-deployment-5c55bf6c         Deleted pod: kuard-deployment-5c55bf6c-jnxzv
2m15s       Normal    SuccessfulDelete               replicaset/kuard-deployment-5c55bf6c         Deleted pod: kuard-deployment-5c55bf6c-hndwq
2m15s       Normal    SuccessfulDelete               replicaset/kuard-deployment-5c55bf6c         Deleted pod: kuard-deployment-5c55bf6c-khzqt
2m15s       Normal    ScalingReplicaSet              deployment/kuard-deployment                  Scaled down replica set kuard-deployment-5c55bf6c to 1
32m         Normal    ScalingReplicaSet              deployment/kuard-deployment                  Scaled up replica set kuard-deployment-5c55bf6c to 4
31m         Normal    ScalingReplicaSet              deployment/kuard-deployment                  Scaled up replica set kuard-deployment-5c55bf6c to 5

ALB默认5分钟汇报一次度量值(可调,最高到实时), Prometheus每30s抓取一次(在ServiceMonitor中可调整), HPA默认冷却时间5分钟.

小结

由于篇幅的问题, 准备环境环节省略了很多过程, 实际上安装与集成的步骤有官方文档和大拿们的分享贴, 有兴趣复制该实验的同学可以搜来参考一下.

或者科学上网搜索Custom Metrics HPA也有可以参考的文章. 这些文章大多会提供一个Demo App, 该Demo App自己提供度量值然后被Prometheus抓取, 逻辑跟本文一样, 通过Adaptor提供API在被HPA查询到.

让业务应用自己输出度量值(兼容Prometheus格式)也许对于研发来说并不是难事, 也许是我站着说话不腰疼. 总体来说暴露什么样的度量值和怎么使用都需要系统的规划, 对于运维体系来说事情可大可小. 对于通过负载均衡暴露的业务来说, 除CPU/MEN外的指标外, L4/L7的指标由负载均衡器来汇报更为科学. 当然了由业务应用汇报度量值又可以更为灵活, 可以匹配业务逻辑. 可以综合使用, 比如水平扩缩采用负载均衡汇报的度量值, 业务运维统计则使用App开发时定制的度量值, 相得益彰.

Prometheus自成体系, 周边的生态也很多, 学来不易. 折射出运维管理是门大学问, 致敬每一位运维人.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 k8s技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 可行性方案
  • 逻辑导图
  • 测试拓扑
  • 准备工作
  • 配置环节
  • 小结
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档