在上一篇文章中,给大家介绍和剖析了 HPA 的实现原理以及演进的思路与历程。本文我们将会为大家讲解如何使用 HPA 以及一些需要注意的细节。

autoscaling/v1 实践

v1 的模板可能是大家平时见到最多的也是最简单的,v1 版本的 HPA 只支持一种指标 —— CPU。传统意义上,弹性伸缩最少也会支持 CPU 与 Memory 两种指标,为什么在 Kubernetes 中只放开了 CPU 呢?其实最早的 HPA 是计划同时支持这两种指标的,但是实际的开发测试中发现:内存不是一个非常好的弹性伸缩判断条件。因为和 CPU不 同,很多内存型的应用,并不会因为 HPA 弹出新的容器而带来内存的快速回收,很多应用的内存都要交给语言层面的 VM 进行管理,也就是说,内存的回收是由 VM 的 GC 来决定的。这就有可能因为 GC 时间的差异导致 HPA 在不恰当的时间点震荡,因此在 v1 的版本中,HPA 就只支持了 CPU 这一种指标。

一个标准的 v1 模板大致如下:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:name: php-apachenamespace: default
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: php-apacheminReplicas: 1maxReplicas: 10targetCPUUtilizationPercentage: 50

其中 scaleTargetRef 表示当前要操作的伸缩对象是谁。在本例中,伸缩的对象是一个 apps/v1 版本的 DeploymenttargetCPUUtilizationPercentage 表示:当整体的资源利用率超过 50% 的时候,会进行扩容。接下来我们做一个简单的 Demo 来实践下。

  1. 登录容器服务控制台,首先创建一个应用部署,选择使用模板创建,模板内容如下:
apiVersion: apps/v1beta1kind: Deploymentmetadata:
name: php-apache
labels:app: php-apachespec:
replicas: 1
selector:matchLabels:app: php-apache
template:metadata:labels:app: php-apachespec:containers:- name: php-apacheimage: registry.cn-hangzhou.aliyuncs.com/ringtail/hpa-example:v1.0ports:- containerPort: 80resources:requests:memory: "300Mi"cpu: "250m"--- apiVersion: v1kind: Servicemetadata:
name: php-apache
labels:app: php-apachespec:
selector:app: php-apache
ports:
- protocol: TCPname: httpport: 80 targetPort: 80
type: ClusterIP
  1. 部署压测模组 HPA 模板
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
namespace: default
spec:
scaleTargetRef:apiVersion: apps/v1beta1kind: Deploymentname: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
  1. 开启压力测试
apiVersion: apps/v1beta1kind: Deploymentmetadata:name: load-generator labels:app: load-generatorspec:replicas: 1selector:matchLabels:app: load-generatortemplate:metadata:labels:app: load-generatorspec:containers:- name: load-generatorimage: busybox command:- "sh"- "-c"- "while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done"
  1. 检查扩容状态

  1. 关闭压测应用

  1. 检查缩容状态

这样一个使用 autoscaling/v1 的 HPA 就完成了。相对而言,这个版本的 HPA 目前是最简单的,无论是否升级 Metrics-Server 都可以实现。

autoscaling/v2beta1 实践

在前面的内容中为大家讲解了 HPA 还有 autoscaling/v2beta1autoscaling/v2beta2 两个版本。这两个版本的区别是 autoscaling/v1beta1 支持了 Resource MetricsCustom Metrics。而在 autoscaling/v2beta2 的版本中额外增加了 External Metrics 的支持。对于 External Metrics 在本文中就不进行过多赘述,因为 External Metrics 目前在社区里面没有太多成熟的实现,比较成熟的实现是 Prometheus Custom Metrics

上面这张图为大家展现了开启 Metrics Server 后, HPA 如何使用不同类型的Metrics,如果需要使用 Custom Metrics ,则需要配置安装相应的 Custom Metrics Adapter。在下文中,主要为大家介绍一个基于 QPS 来进行弹性伸缩的例子。

  1. 安装 Metrics Server 并在 kube-controller-manager 中进行开启

目前默认的阿里云容器服务 Kubernetes 集群使用还是 Heapster,容器服务计划在 1.12 中更新 Metrics Server,这个地方需要特别说明下,社区虽然已经逐渐开始废弃 Heapster,但是社区中还有大量的组件是在强依赖 Heapster 的 API,因此阿里云基于 Metrics Server 进行了 Heapster 完整的兼容,既可以让开发者使用 Metrics Server 的新功能,又可以无需担心其他组件的宕机。

在部署新的 Metrics Server 之前,我们首先要备份一下 Heapster 中的一些启动参数,因为这些参数稍后会直接用在 Metrics Server 的模板中。其中重点关心的是两个 Sink,如果需要使用 Influxdb 的开发者,可以保留第一个 Sink;如果需要保留云监控集成能力的开发者,则保留第二个 Sink。

将这两个参数拷贝到 Metrics Server 的启动模板中,在本例中是两个都兼容,并下发部署。

apiVersion: v1
kind: ServiceAccount
metadata:name: metrics-servernamespace: kube-system
---
apiVersion: v1
kind: Service
metadata:name: metrics-servernamespace: kube-systemlabels:kubernetes.io/name: "Metrics-server"
spec:selector:k8s-app: metrics-serverports:- port: 443protocol: TCPtargetPort: 443
---
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:name: v1beta1.metrics.k8s.io
spec:service:name: metrics-servernamespace: kube-systemgroup: metrics.k8s.ioversion: v1beta1insecureSkipTLSVerify: truegroupPriorityMinimum: 100versionPriority: 100
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:name: metrics-servernamespace: kube-systemlabels:k8s-app: metrics-server
spec:selector:matchLabels:k8s-app: metrics-servertemplate:metadata:name: metrics-serverlabels:k8s-app: metrics-serverspec:serviceAccountName: admincontainers:- name: metrics-serverimage: registry.cn-hangzhou.aliyuncs.com/ringtail/metrics-server:1.1imagePullPolicy: Alwayscommand:- /metrics-server- '--source=kubernetes:https://kubernetes.default'- '--sink=influxdb:http://monitoring-influxdb:8086'- '--sink=socket:tcp://monitor.csk.[region_id].aliyuncs.com:8093?clusterId=[cluster_id]&public=true'

接下来我们修改下 HeapsterService,将服务的后端从 Heapster 转移到 Metrics Server

如果此时从控制台的节点页面可以获取到右侧的监控信息的话,说明 Metrics Server 已经完全兼容 Heapster

此时通过 kubectl get apiservice,如果可以看到注册的 v1beta1.metrics.k8s.io 的 api,则说明已经注册成功。

接下来我们需要在 kube-controller-manager 上切换 Metrics 的数据来源。kube-controller-manger 部署在每个 master 上,是通过 Static Pod 的托管给 kubelet 的。因此只需要修改 kube-controller-manager 的配置文件,kubelet 就会自动进行更新。kube-controller-manager 在主机上的路径是 /etc/kubernetes/manifests/kube-controller-manager.yaml

需要将 --horizontal-pod-autoscaler-use-rest-clients=true,这里有一个注意点,因为如果使用 vim 进行编辑,vim 会自动生成一个缓存文件影响最终的结果,所以比较建议的方式是将这个配置文件移动到其他的目录下进行修改,然后再移回原来的目录。至此,Metrics Server 已经可以为 HPA 进行服务了,接下来我们来做自定义指标的部分。

  1. 部署 Custom Metrics Adapter

如集群中未部署 Prometheus,可以参考《阿里云容器Kubernetes监控(七) - Prometheus监控方案部署》先部署 Prometheus。接下来我们部署 Custom Metrics Adapter

kind: Namespace
apiVersion: v1
metadata:name: custom-metrics
---
kind: ServiceAccount
apiVersion: v1
metadata:name: custom-metrics-apiservernamespace: custom-metrics
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: custom-metrics:system:auth-delegator
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: system:auth-delegator
subjects:
- kind: ServiceAccountname: custom-metrics-apiservernamespace: custom-metrics
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: custom-metrics-auth-readernamespace: kube-system
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccountname: custom-metrics-apiservernamespace: custom-metrics
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: custom-metrics-resource-reader
rules:
- apiGroups:- ""resources:- namespaces- pods- servicesverbs:- get- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: custom-metrics-apiserver-resource-reader
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: custom-metrics-resource-reader
subjects:
- kind: ServiceAccountname: custom-metrics-apiservernamespace: custom-metrics
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: custom-metrics-getter
rules:
- apiGroups:- custom.metrics.k8s.ioresources:- "*"verbs:- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: hpa-custom-metrics-getter
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: custom-metrics-getter
subjects:
- kind: ServiceAccountname: horizontal-pod-autoscalernamespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:name: custom-metrics-apiservernamespace: custom-metricslabels:app: custom-metrics-apiserver
spec:replicas: 1selector:matchLabels:app: custom-metrics-apiservertemplate:metadata:labels:app: custom-metrics-apiserverspec:tolerations:- key: beta.kubernetes.io/archvalue: armeffect: NoSchedule- key: beta.kubernetes.io/archvalue: arm64effect: NoScheduleserviceAccountName: custom-metrics-apiservercontainers:- name: custom-metrics-serverimage: luxas/k8s-prometheus-adapter:v0.2.0-beta.0args:- --prometheus-url=http://prometheus-k8s.monitoring.svc:9090- --metrics-relist-interval=30s- --rate-interval=60s- --v=10- --logtostderr=trueports:- containerPort: 443securityContext:runAsUser: 0
---
apiVersion: v1
kind: Service
metadata:name: apinamespace: custom-metrics
spec:ports:- port: 443targetPort: 443selector:app: custom-metrics-apiserver
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:name: v1beta1.custom.metrics.k8s.io
spec:insecureSkipTLSVerify: truegroup: custom.metrics.k8s.iogroupPriorityMinimum: 1000versionPriority: 5service:name: apinamespace: custom-metricsversion: v1beta1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: custom-metrics-server-resources
rules:
- apiGroups:- custom-metrics.metrics.k8s.ioresources: ["*"]verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: hpa-controller-custom-metrics
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: custom-metrics-server-resources
subjects:
- kind: ServiceAccountname: horizontal-pod-autoscalernamespace: kube-system
  1. 部署手压测应用与 HPA 模板
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: sample-metrics-appname: sample-metrics-app
spec:replicas: 2selector:matchLabels:app: sample-metrics-apptemplate:metadata:labels:app: sample-metrics-appspec:tolerations:- key: beta.kubernetes.io/archvalue: armeffect: NoSchedule- key: beta.kubernetes.io/archvalue: arm64effect: NoSchedule- key: node.alpha.kubernetes.io/unreachableoperator: Existseffect: NoExecutetolerationSeconds: 0- key: node.alpha.kubernetes.io/notReadyoperator: Existseffect: NoExecutetolerationSeconds: 0containers:- image: luxas/autoscale-demo:v0.1.2name: sample-metrics-appports:- name: webcontainerPort: 8080readinessProbe:httpGet:path: /port: 8080initialDelaySeconds: 3periodSeconds: 5livenessProbe:httpGet:path: /port: 8080initialDelaySeconds: 3periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:name: sample-metrics-applabels:app: sample-metrics-app
spec:ports:- name: webport: 80targetPort: 8080selector:app: sample-metrics-app
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:name: sample-metrics-applabels:service-monitor: sample-metrics-app
spec:selector:matchLabels:app: sample-metrics-appendpoints:- port: web
---
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta1
metadata:name: sample-metrics-app-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: sample-metrics-appminReplicas: 2maxReplicas: 10metrics:- type: Objectobject:target:kind: Servicename: sample-metrics-appmetricName: http_requeststargetValue: 100
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: sample-metrics-appnamespace: defaultannotations:traefik.frontend.rule.type: PathPrefixStrip
spec:rules:- http:paths:- path: /sample-appbackend:serviceName: sample-metrics-appservicePort: 80

这个压测的应用暴露了一个 Prometheus 的接口。接口中的数据如下,其中 http_requests_total 这个指标就是我们接下来伸缩使用的自定义指标。

[root@iZwz99zrzfnfq8wllk0dvcZ manifests]# curl 172.16.1.160:8080/metrics
# HELP http_requests_total The amount of requests served by the server in total
# TYPE http_requests_total counter
http_requests_total 3955684
  1. 部署压测应用
apiVersion: apps/v1beta1
kind: Deployment
metadata:name: load-generator labels:app: load-generator
spec:replicas: 1selector:matchLabels:app: load-generatortemplate:metadata:labels:app: load-generatorspec:containers:- name: load-generatorimage: busybox command:- "sh"- "-c"- "while true; do wget -q -O- http://sample-metrics-app.default.svc.cluster.local; done"
  1. 查看 HPA 的状态与伸缩,稍等几分钟,Pod 已经伸缩成功了。
workspace kubectl get hpa
NAME                     REFERENCE                       TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
php-apache               Deployment/php-apache           0%/50%        1         10        1          21d
sample-metrics-app-hpa   Deployment/sample-metrics-app   538133m/100   2         10        10         15h

最后

这篇文章主要是给大家带来一个对于 autoscaling/v1autoscaling/v2beta1 的感性认知和大体的操作方式,对于 autoscaling/v1 我们不做过多的赘述,对于希望使用支持 Custom Metricsautoscaling/v2beta1 的开发者而言,也许会认为整体的操作流程过于复杂难以理解,我们会在下一篇文章中为大家详解 autoscaling/v2beta1 使用 Custom Metrics 的种种细节,帮助大家更深入地理解其中的原理与设计思路。

Kubernetes 弹性伸缩全场景解析(三) - HPA 实践手册相关推荐

  1. Kubernetes 弹性伸缩全场景解析 (四)- 让核心组件充满弹性

    前言 在本系列的前三篇文章中,我们介绍了弹性伸缩的整体布局以及 HPA 的一些原理,HPA 的部分还遗留了一些内容需要进行详细解析.在准备这部分内容的期间,会穿插几篇弹性伸缩组件的最佳实践.今天我们要 ...

  2. Kubernetes 弹性伸缩全场景解析 (一):概念延伸与组件布局

    传统弹性伸缩的困境 弹性伸缩是 Kubernetes 中被大家关注的一大亮点,在讨论相关的组件和实现方案之前.首先想先给大家扩充下弹性伸缩的边界与定义,传统意义上来讲,弹性伸缩主要解决的问题是容量规划 ...

  3. Kubernetes 弹性伸缩全场景解读(二)- HPA 的原理与演进

    前言 在上一篇文章 Kubernetes 弹性伸缩全场景解析 (一):概念延伸与组件布局中,我们介绍了在 Kubernetes 在处理弹性伸缩时的设计理念以及相关组件的布局,在今天这篇文章中,会为大家 ...

  4. Kubernetes 弹性伸缩全场景解读(五) - 定时伸缩组件发布与开源

    作者| 阿里云容器技术专家刘中巍(莫源) 导读:Kubernetes弹性伸缩系列文章为读者一一解析了各个弹性伸缩组件的相关原理和用法.本篇文章中,阿里云容器技术专家莫源将为你带来定时伸缩组件  kub ...

  5. Kubernetes弹性伸缩全场景解读(五) - 定时伸缩组件发布与开源

    前言 容器技术的发展让软件交付和运维变得更加标准化.轻量化.自动化.这使得动态调整负载的容量变成一件非常简单的事情.在kubernetes中,通常只需要修改对应的replicas数目即可完成.当负载的 ...

  6. Kubernetes弹性伸缩与监控

    kubernetes的弹性伸缩 kubernetes 监控 cadvisor kubernetes内置监控系统 为了解决docker stats的问题(存储.展示),谷歌开源的cadvisor诞生了, ...

  7. 容器服务kubernetes弹性伸缩高级用法

    前言 近期,阿里云容器服务kubernetes发布了cluster-autoscaler的支持,开发者可以通过页面简单快捷的配置节点的弹性伸缩,支持普通实例.GPU实例以及竞价实例帮助开发者实现架构弹 ...

  8. Sugar BI 增强分析能力全场景解析与分享

    自从 BI 的概念被提出,30多年时间 BI 经历了多轮发展. BI 1.0通过自主开发.搭建仪表盘.Excel 工具等实现数据分析. 互联网技术和 IM 的发展,加速了BI 2.0 敏捷 BI 产品 ...

  9. 达达集团智能弹性伸缩架构的设计与落地实践

    文章来源:架构头条,嘉宾 | 杨森,编辑 | 李忠良 面对节假日常规促销.618/ 双 11 购物节等配送业务订单量的暴增,达达集团通过智能弹性伸缩架构和精细化的容量管理,有效地做到了业务系统对配送全 ...

最新文章

  1. HDU1576 A/B (解法二)【试探法】
  2. SublimeLinter插件对PHP语法检测不起作用的解决办法
  3. source insight和vim同时使用
  4. 国产数据库建模工具,看到界面第一眼,良心了! ​
  5. bzoj4195(并查集+离散化)
  6. 在javafx中界面主题_最小的JavaFX演示文稿(在JavaFX中)
  7. apache服务器工作原理,Apache服务器的原理简介
  8. 【Prince2科普】P2七大主题之商业论证
  9. [转载] 不少Gate或Node运算子 的反向传播代码
  10. C语言程序设计知识必备pdf,C语言程序设计基础知识要点.pdf
  11. 《SQL入门经典》总结
  12. linux文件系统目录结构采用的是,关于linux分区,文件系统,目录结构的概述
  13. sklearn.utils.Bunch的属性
  14. 罗永浩Vs王自如:浮躁的世界该如何降温?!
  15. c#中计算三角形面积公式,C#源代码—三角形面积、圆的面积
  16. 如何批量删除pdf中的批注
  17. 研发路上的总结和思考 -----来自阿里巴巴中间插件----作者:石佳宁
  18. 昨天睡眠质量记录70分
  19. 如何取消Office 正版增值验证
  20. 数值法求解最优控制问题(二)——打靶法

热门文章

  1. 1.16 static关键字(静态变量和静态方法)
  2. HDU1862 EXCEL排序
  3. CSS选择器的声明与嵌套
  4. 整人之bat重启文件
  5. 终端服务器有多种运行模式,云终端的三种工作模式你都知道的吗
  6. 还在网上找Demo?这个Java项目真香!
  7. 国内程序员最容易发音错误的单词集合
  8. 怎么解决java.lang.NoClassDefFoundError错误
  9. Android调用系统软件打开文件(包括apk文件)
  10. 解读Cardinality Estimation算法(第三部分:LogLog Counting)