资讯专栏INFORMATION COLUMN

k8s与HPA--通过 Prometheus adaptor 来自定义监控指标

孙吉亮 / 3097人阅读

摘要:与通过来自定义监控指标自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。适配器删除后缀并将度量标记为计数器度量标准。负载测试完成后,会将部署缩到其初始副本您可能已经注意到自动缩放器不会立即对使用峰值做出反应。

k8s与HPA--通过 Prometheus adaptor 来自定义监控指标

自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。 Kubernetes中的自动缩放有两个维度:Cluster Autoscaler处理节点扩展操作,Horizo​​ntal Pod Autoscaler自动扩展部署或副本集中的pod数量。 Cluster Autoscaling与Horizo​​ntal Pod Autoscaler一起用于动态调整计算能力以及系统满足SLA所需的并行度。虽然Cluster Autoscaler高度依赖托管您的集群的云提供商的基础功能,但HPA可以独立于您的IaaS / PaaS提供商运营。

Horizo​​ntal Pod Autoscaler功能最初是在Kubernetes v1.1中引入的,并且从那时起已经发展了很多。 HPA缩放容器的版本1基于观察到的CPU利用率,后来基于内存使用情况。在Kubernetes 1.6中,引入了一个新的API Custom Metrics API,使HPA能够访问任意指标。 Kubernetes 1.7引入了聚合层,允许第三方应用程序通过将自己注册为API附加组件来扩展Kubernetes API。 Custom Metrics API和聚合层使Prometheus等监控系统可以向HPA控制器公开特定于应用程序的指标。

Horizo​​ntal Pod Autoscaler实现为一个控制循环,定期查询Resource Metrics API以获取CPU /内存等核心指标和针对特定应用程序指标的Custom Metrics API。

以下是为Kubernetes 1.9或更高版本配置HPA v2的分步指南。您将安装提供核心指标的Metrics Server附加组件,然后您将使用演示应用程序根据CPU和内存使用情况展示pod自动扩展。在本指南的第二部分中,您将部署Prometheus和自定义API服务器。您将使用聚合器层注册自定义API服务器,然后使用演示应用程序提供的自定义指标配置HPA。

在开始之前,您需要安装Go 1.8或更高版本并在GOPATH中克隆k8s-prom-hpa repo。

</>复制代码

  1. cd $GOPATH
  2. git clone https://github.com/stefanprodan/k8s-prom-hpa
部署 Metrics Server

kubernetes Metrics Server是资源使用数据的集群范围聚合器,是Heapster的后继者。度量服务器通过汇集来自kubernetes.summary_api的数据来收集节点和pod的CPU和内存使用情况。摘要API是一种内存高效的API,用于将数据从Kubelet / cAdvisor传递到度量服务器。

在HPA的第一个版本中,您需要Heapster来提供CPU和内存指标,在HPA v2和Kubernetes 1.8中,只有在启用horizo​​ntal-pod-autoscaler-use-rest-clients时才需要指标服务器。默认情况下,Kubernetes 1.9中启用了HPA rest客户端。 GKE 1.9附带预安装的Metrics Server。

在kube-system命名空间中部署Metrics Server:

</>复制代码

  1. kubectl create -f ./metrics-server

一分钟后,度量服务器开始报告节点和pod的CPU和内存使用情况。

查看nodes metrics:

</>复制代码

  1. kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq .

结果如下:

</>复制代码

  1. {
  2. "kind": "NodeMetricsList",
  3. "apiVersion": "metrics.k8s.io/v1beta1",
  4. "metadata": {
  5. "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes"
  6. },
  7. "items": [
  8. {
  9. "metadata": {
  10. "name": "ip-10-1-50-61.ec2.internal",
  11. "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/ip-10-1-50-61.ec2.internal",
  12. "creationTimestamp": "2019-02-13T08:34:05Z"
  13. },
  14. "timestamp": "2019-02-13T08:33:38Z",
  15. "window": "30s",
  16. "usage": {
  17. "cpu": "78322168n",
  18. "memory": "563180Ki"
  19. }
  20. },
  21. {
  22. "metadata": {
  23. "name": "ip-10-1-57-40.ec2.internal",
  24. "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/ip-10-1-57-40.ec2.internal",
  25. "creationTimestamp": "2019-02-13T08:34:05Z"
  26. },
  27. "timestamp": "2019-02-13T08:33:42Z",
  28. "window": "30s",
  29. "usage": {
  30. "cpu": "48926263n",
  31. "memory": "554472Ki"
  32. }
  33. },
  34. {
  35. "metadata": {
  36. "name": "ip-10-1-62-29.ec2.internal",
  37. "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/ip-10-1-62-29.ec2.internal",
  38. "creationTimestamp": "2019-02-13T08:34:05Z"
  39. },
  40. "timestamp": "2019-02-13T08:33:36Z",
  41. "window": "30s",
  42. "usage": {
  43. "cpu": "36700681n",
  44. "memory": "326088Ki"
  45. }
  46. }
  47. ]
  48. }

查看pods metrics:

</>复制代码

  1. kubectl get --raw "/apis/metrics.k8s.io/v1beta1/pods" | jq .

结果如下:

</>复制代码

  1. {
  2. "kind": "PodMetricsList",
  3. "apiVersion": "metrics.k8s.io/v1beta1",
  4. "metadata": {
  5. "selfLink": "/apis/metrics.k8s.io/v1beta1/pods"
  6. },
  7. "items": [
  8. {
  9. "metadata": {
  10. "name": "kube-proxy-77nt2",
  11. "namespace": "kube-system",
  12. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-proxy-77nt2",
  13. "creationTimestamp": "2019-02-13T08:35:19Z"
  14. },
  15. "timestamp": "2019-02-13T08:35:00Z",
  16. "window": "30s",
  17. "containers": [
  18. {
  19. "name": "kube-proxy",
  20. "usage": {
  21. "cpu": "2370555n",
  22. "memory": "13184Ki"
  23. }
  24. }
  25. ]
  26. },
  27. {
  28. "metadata": {
  29. "name": "cluster-autoscaler-n2xsl",
  30. "namespace": "kube-system",
  31. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/cluster-autoscaler-n2xsl",
  32. "creationTimestamp": "2019-02-13T08:35:19Z"
  33. },
  34. "timestamp": "2019-02-13T08:35:12Z",
  35. "window": "30s",
  36. "containers": [
  37. {
  38. "name": "cluster-autoscaler",
  39. "usage": {
  40. "cpu": "1477997n",
  41. "memory": "54584Ki"
  42. }
  43. }
  44. ]
  45. },
  46. {
  47. "metadata": {
  48. "name": "core-dns-autoscaler-b4785d4d7-j64xd",
  49. "namespace": "kube-system",
  50. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/core-dns-autoscaler-b4785d4d7-j64xd",
  51. "creationTimestamp": "2019-02-13T08:35:19Z"
  52. },
  53. "timestamp": "2019-02-13T08:35:08Z",
  54. "window": "30s",
  55. "containers": [
  56. {
  57. "name": "autoscaler",
  58. "usage": {
  59. "cpu": "191293n",
  60. "memory": "7956Ki"
  61. }
  62. }
  63. ]
  64. },
  65. {
  66. "metadata": {
  67. "name": "spot-interrupt-handler-8t2xk",
  68. "namespace": "kube-system",
  69. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/spot-interrupt-handler-8t2xk",
  70. "creationTimestamp": "2019-02-13T08:35:19Z"
  71. },
  72. "timestamp": "2019-02-13T08:35:04Z",
  73. "window": "30s",
  74. "containers": [
  75. {
  76. "name": "spot-interrupt-handler",
  77. "usage": {
  78. "cpu": "844907n",
  79. "memory": "4608Ki"
  80. }
  81. }
  82. ]
  83. },
  84. {
  85. "metadata": {
  86. "name": "kube-proxy-t5kqm",
  87. "namespace": "kube-system",
  88. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-proxy-t5kqm",
  89. "creationTimestamp": "2019-02-13T08:35:19Z"
  90. },
  91. "timestamp": "2019-02-13T08:35:08Z",
  92. "window": "30s",
  93. "containers": [
  94. {
  95. "name": "kube-proxy",
  96. "usage": {
  97. "cpu": "1194766n",
  98. "memory": "12204Ki"
  99. }
  100. }
  101. ]
  102. },
  103. {
  104. "metadata": {
  105. "name": "kube-proxy-zxmqb",
  106. "namespace": "kube-system",
  107. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-proxy-zxmqb",
  108. "creationTimestamp": "2019-02-13T08:35:19Z"
  109. },
  110. "timestamp": "2019-02-13T08:35:06Z",
  111. "window": "30s",
  112. "containers": [
  113. {
  114. "name": "kube-proxy",
  115. "usage": {
  116. "cpu": "3021117n",
  117. "memory": "13628Ki"
  118. }
  119. }
  120. ]
  121. },
  122. {
  123. "metadata": {
  124. "name": "aws-node-rcz5c",
  125. "namespace": "kube-system",
  126. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/aws-node-rcz5c",
  127. "creationTimestamp": "2019-02-13T08:35:19Z"
  128. },
  129. "timestamp": "2019-02-13T08:35:15Z",
  130. "window": "30s",
  131. "containers": [
  132. {
  133. "name": "aws-node",
  134. "usage": {
  135. "cpu": "1217989n",
  136. "memory": "24976Ki"
  137. }
  138. }
  139. ]
  140. },
  141. {
  142. "metadata": {
  143. "name": "aws-node-z2qxs",
  144. "namespace": "kube-system",
  145. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/aws-node-z2qxs",
  146. "creationTimestamp": "2019-02-13T08:35:19Z"
  147. },
  148. "timestamp": "2019-02-13T08:35:15Z",
  149. "window": "30s",
  150. "containers": [
  151. {
  152. "name": "aws-node",
  153. "usage": {
  154. "cpu": "1025780n",
  155. "memory": "46424Ki"
  156. }
  157. }
  158. ]
  159. },
  160. {
  161. "metadata": {
  162. "name": "php-apache-899d75b96-8ppk4",
  163. "namespace": "default",
  164. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/php-apache-899d75b96-8ppk4",
  165. "creationTimestamp": "2019-02-13T08:35:19Z"
  166. },
  167. "timestamp": "2019-02-13T08:35:08Z",
  168. "window": "30s",
  169. "containers": [
  170. {
  171. "name": "php-apache",
  172. "usage": {
  173. "cpu": "24612n",
  174. "memory": "27556Ki"
  175. }
  176. }
  177. ]
  178. },
  179. {
  180. "metadata": {
  181. "name": "load-generator-779c5f458c-9sglg",
  182. "namespace": "default",
  183. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/load-generator-779c5f458c-9sglg",
  184. "creationTimestamp": "2019-02-13T08:35:19Z"
  185. },
  186. "timestamp": "2019-02-13T08:34:56Z",
  187. "window": "30s",
  188. "containers": [
  189. {
  190. "name": "load-generator",
  191. "usage": {
  192. "cpu": "0",
  193. "memory": "336Ki"
  194. }
  195. }
  196. ]
  197. },
  198. {
  199. "metadata": {
  200. "name": "aws-node-v9jxs",
  201. "namespace": "kube-system",
  202. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/aws-node-v9jxs",
  203. "creationTimestamp": "2019-02-13T08:35:19Z"
  204. },
  205. "timestamp": "2019-02-13T08:35:00Z",
  206. "window": "30s",
  207. "containers": [
  208. {
  209. "name": "aws-node",
  210. "usage": {
  211. "cpu": "1303458n",
  212. "memory": "28020Ki"
  213. }
  214. }
  215. ]
  216. },
  217. {
  218. "metadata": {
  219. "name": "kube2iam-m2ktt",
  220. "namespace": "kube-system",
  221. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube2iam-m2ktt",
  222. "creationTimestamp": "2019-02-13T08:35:19Z"
  223. },
  224. "timestamp": "2019-02-13T08:35:11Z",
  225. "window": "30s",
  226. "containers": [
  227. {
  228. "name": "kube2iam",
  229. "usage": {
  230. "cpu": "1328864n",
  231. "memory": "9724Ki"
  232. }
  233. }
  234. ]
  235. },
  236. {
  237. "metadata": {
  238. "name": "kube2iam-w9cqf",
  239. "namespace": "kube-system",
  240. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube2iam-w9cqf",
  241. "creationTimestamp": "2019-02-13T08:35:19Z"
  242. },
  243. "timestamp": "2019-02-13T08:35:03Z",
  244. "window": "30s",
  245. "containers": [
  246. {
  247. "name": "kube2iam",
  248. "usage": {
  249. "cpu": "1294379n",
  250. "memory": "8812Ki"
  251. }
  252. }
  253. ]
  254. },
  255. {
  256. "metadata": {
  257. "name": "custom-metrics-apiserver-657644489c-pk8rb",
  258. "namespace": "monitoring",
  259. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/monitoring/pods/custom-metrics-apiserver-657644489c-pk8rb",
  260. "creationTimestamp": "2019-02-13T08:35:19Z"
  261. },
  262. "timestamp": "2019-02-13T08:35:04Z",
  263. "window": "30s",
  264. "containers": [
  265. {
  266. "name": "custom-metrics-apiserver",
  267. "usage": {
  268. "cpu": "22409370n",
  269. "memory": "42468Ki"
  270. }
  271. }
  272. ]
  273. },
  274. {
  275. "metadata": {
  276. "name": "kube2iam-qghgt",
  277. "namespace": "kube-system",
  278. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube2iam-qghgt",
  279. "creationTimestamp": "2019-02-13T08:35:19Z"
  280. },
  281. "timestamp": "2019-02-13T08:35:11Z",
  282. "window": "30s",
  283. "containers": [
  284. {
  285. "name": "kube2iam",
  286. "usage": {
  287. "cpu": "2078992n",
  288. "memory": "16356Ki"
  289. }
  290. }
  291. ]
  292. },
  293. {
  294. "metadata": {
  295. "name": "spot-interrupt-handler-ps745",
  296. "namespace": "kube-system",
  297. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/spot-interrupt-handler-ps745",
  298. "creationTimestamp": "2019-02-13T08:35:19Z"
  299. },
  300. "timestamp": "2019-02-13T08:35:10Z",
  301. "window": "30s",
  302. "containers": [
  303. {
  304. "name": "spot-interrupt-handler",
  305. "usage": {
  306. "cpu": "611566n",
  307. "memory": "4336Ki"
  308. }
  309. }
  310. ]
  311. },
  312. {
  313. "metadata": {
  314. "name": "coredns-68fb7946fb-2xnpp",
  315. "namespace": "kube-system",
  316. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/coredns-68fb7946fb-2xnpp",
  317. "creationTimestamp": "2019-02-13T08:35:19Z"
  318. },
  319. "timestamp": "2019-02-13T08:35:12Z",
  320. "window": "30s",
  321. "containers": [
  322. {
  323. "name": "coredns",
  324. "usage": {
  325. "cpu": "1610381n",
  326. "memory": "10480Ki"
  327. }
  328. }
  329. ]
  330. },
  331. {
  332. "metadata": {
  333. "name": "coredns-68fb7946fb-9ctjf",
  334. "namespace": "kube-system",
  335. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/coredns-68fb7946fb-9ctjf",
  336. "creationTimestamp": "2019-02-13T08:35:19Z"
  337. },
  338. "timestamp": "2019-02-13T08:35:13Z",
  339. "window": "30s",
  340. "containers": [
  341. {
  342. "name": "coredns",
  343. "usage": {
  344. "cpu": "1418850n",
  345. "memory": "9852Ki"
  346. }
  347. }
  348. ]
  349. },
  350. {
  351. "metadata": {
  352. "name": "prometheus-7d4f6d4454-v4fnd",
  353. "namespace": "monitoring",
  354. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/monitoring/pods/prometheus-7d4f6d4454-v4fnd",
  355. "creationTimestamp": "2019-02-13T08:35:19Z"
  356. },
  357. "timestamp": "2019-02-13T08:35:00Z",
  358. "window": "30s",
  359. "containers": [
  360. {
  361. "name": "prometheus",
  362. "usage": {
  363. "cpu": "17951807n",
  364. "memory": "202316Ki"
  365. }
  366. }
  367. ]
  368. },
  369. {
  370. "metadata": {
  371. "name": "metrics-server-7cdd54ccb4-k2x7m",
  372. "namespace": "kube-system",
  373. "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/metrics-server-7cdd54ccb4-k2x7m",
  374. "creationTimestamp": "2019-02-13T08:35:19Z"
  375. },
  376. "timestamp": "2019-02-13T08:35:04Z",
  377. "window": "30s",
  378. "containers": [
  379. {
  380. "name": "metrics-server-nanny",
  381. "usage": {
  382. "cpu": "144656n",
  383. "memory": "5716Ki"
  384. }
  385. },
  386. {
  387. "name": "metrics-server",
  388. "usage": {
  389. "cpu": "568327n",
  390. "memory": "16268Ki"
  391. }
  392. }
  393. ]
  394. }
  395. ]
  396. }
基于CPU和内存使用情况的Auto Scaling

您将使用基于Golang的小型Web应用程序来测试Horizo​​ntal Pod Autoscaler(HPA)。

将podinfo部署到默认命名空间:

</>复制代码

  1. kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.yaml

使用NodePort服务访问podinfo,地址为http:// :31198。

接下来定义一个至少维护两个副本的HPA,如果CPU平均值超过80%或内存超过200Mi,则最多可扩展到10个:

</>复制代码

  1. apiVersion: autoscaling/v2beta1
  2. kind: HorizontalPodAutoscaler
  3. metadata:
  4. name: podinfo
  5. spec:
  6. scaleTargetRef:
  7. apiVersion: extensions/v1beta1
  8. kind: Deployment
  9. name: podinfo
  10. minReplicas: 2
  11. maxReplicas: 10
  12. metrics:
  13. - type: Resource
  14. resource:
  15. name: cpu
  16. targetAverageUtilization: 80
  17. - type: Resource
  18. resource:
  19. name: memory
  20. targetAverageValue: 200Mi

创建这个hpa:

</>复制代码

  1. kubectl create -f ./podinfo/podinfo-hpa.yaml

几秒钟后,HPA控制器联系度量服务器,然后获取CPU和内存使用情况:

</>复制代码

  1. kubectl get hpa
  2. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
  3. podinfo Deployment/podinfo 2826240 / 200Mi, 15% / 80% 2 10 2 5m

为了增加CPU使用率,请使用rakyll / hey运行负载测试:

</>复制代码

  1. #install hey
  2. go get -u github.com/rakyll/hey
  3. #do 10K requests
  4. hey -n 10000 -q 10 -c 5 http://:31198/

您可以使用以下方式监控HPA事件:

</>复制代码

  1. $ kubectl describe hpa
  2. Events:
  3. Type Reason Age From Message
  4. ---- ------ ---- ---- -------
  5. Normal SuccessfulRescale 7m horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target
  6. Normal SuccessfulRescale 3m horizontal-pod-autoscaler New size: 8; reason: cpu resource utilization (percentage of request) above target

暂时删除podinfo。稍后将在本教程中再次部署它:

</>复制代码

  1. kubectl delete -f ./podinfo/podinfo-hpa.yaml,./podinfo/podinfo-dep.yaml,./podinfo/podinfo-svc.yaml
部署 Custom Metrics Server

要根据自定义指标进行扩展,您需要拥有两个组件。一个组件,用于从应用程序收集指标并将其存储在Prometheus时间序列数据库中。第二个组件使用collect(k8s-prometheus-adapter)提供的指标扩展了Kubernetes自定义指标API。

您将在专用命名空间中部署Prometheus和适配器。

创建monitoring命名空间:

</>复制代码

  1. kubectl create -f ./namespaces.yaml

monitoring命名空间中部署Prometheus v2:

</>复制代码

  1. kubectl create -f ./prometheus

生成Prometheus适配器所需的TLS证书:

</>复制代码

  1. make certs

生成以下几个文件:

</>复制代码

  1. # ls output
  2. apiserver.csr apiserver-key.pem apiserver.pem

部署Prometheus自定义指标API适配器:

</>复制代码

  1. kubectl create -f ./custom-metrics-api

列出Prometheus提供的自定义指标:

</>复制代码

  1. kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .

获取monitoring命名空间中所有pod的FS使用情况:

</>复制代码

  1. kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/*/fs_usage_bytes" | jq .

查询结果如下:

</>复制代码

  1. {
  2. "kind": "MetricValueList",
  3. "apiVersion": "custom.metrics.k8s.io/v1beta1",
  4. "metadata": {
  5. "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/%2A/fs_usage_bytes"
  6. },
  7. "items": [
  8. {
  9. "describedObject": {
  10. "kind": "Pod",
  11. "namespace": "monitoring",
  12. "name": "custom-metrics-apiserver-657644489c-pk8rb",
  13. "apiVersion": "/v1"
  14. },
  15. "metricName": "fs_usage_bytes",
  16. "timestamp": "2019-02-13T08:52:30Z",
  17. "value": "94253056"
  18. },
  19. {
  20. "describedObject": {
  21. "kind": "Pod",
  22. "namespace": "monitoring",
  23. "name": "prometheus-7d4f6d4454-v4fnd",
  24. "apiVersion": "/v1"
  25. },
  26. "metricName": "fs_usage_bytes",
  27. "timestamp": "2019-02-13T08:52:30Z",
  28. "value": "24576"
  29. }
  30. ]
  31. }
基于custom metrics 自动伸缩

在默认命名空间中创建podinfo NodePort服务和部署:

</>复制代码

  1. kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.yaml

podinfo应用程序公开名为http_requests_total的自定义指标。 Prometheus适配器删除_total后缀并将度量标记为计数器度量标准。

从自定义指标API获取每秒的总请求数:

</>复制代码

  1. kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests" | jq .

</>复制代码

  1. {
  2. "kind": "MetricValueList",
  3. "apiVersion": "custom.metrics.k8s.io/v1beta1",
  4. "metadata": {
  5. "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/http_requests"
  6. },
  7. "items": [
  8. {
  9. "describedObject": {
  10. "kind": "Pod",
  11. "namespace": "default",
  12. "name": "podinfo-6b86c8ccc9-kv5g9",
  13. "apiVersion": "/__internal"
  14. },
  15. "metricName": "http_requests",
  16. "timestamp": "2018-01-10T16:49:07Z",
  17. "value": "901m"
  18. },
  19. {
  20. "describedObject": {
  21. "kind": "Pod",
  22. "namespace": "default",
  23. "name": "podinfo-6b86c8ccc9-nm7bl",
  24. "apiVersion": "/__internal"
  25. },
  26. "metricName": "http_requests",
  27. "timestamp": "2018-01-10T16:49:07Z",
  28. "value": "898m"
  29. }
  30. ]
  31. }

建一个HPA,如果请求数超过每秒10个,将扩展podinfo部署:

</>复制代码

  1. apiVersion: autoscaling/v2beta1
  2. kind: HorizontalPodAutoscaler
  3. metadata:
  4. name: podinfo
  5. spec:
  6. scaleTargetRef:
  7. apiVersion: extensions/v1beta1
  8. kind: Deployment
  9. name: podinfo
  10. minReplicas: 2
  11. maxReplicas: 10
  12. metrics:
  13. - type: Pods
  14. pods:
  15. metricName: http_requests
  16. targetAverageValue: 10

在默认命名空间中部署podinfo HPA:

</>复制代码

  1. kubectl create -f ./podinfo/podinfo-hpa-custom.yaml

几秒钟后,HPA从指标API获取http_requests值:

</>复制代码

  1. kubectl get hpa
  2. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
  3. podinfo Deployment/podinfo 899m / 10 2 10 2 1m

在podinfo服务上应用一些负载,每秒25个请求:

</>复制代码

  1. #install hey
  2. go get -u github.com/rakyll/hey
  3. #do 10K requests rate limited at 25 QPS
  4. hey -n 10000 -q 5 -c 5 http://:31198/healthz

几分钟后,HPA开始扩展部署:

</>复制代码

  1. kubectl describe hpa
  2. Name: podinfo
  3. Namespace: default
  4. Reference: Deployment/podinfo
  5. Metrics: ( current / target )
  6. "http_requests" on pods: 9059m / 10
  7. Min replicas: 2
  8. Max replicas: 10
  9. Events:
  10. Type Reason Age From Message
  11. ---- ------ ---- ---- -------
  12. Normal SuccessfulRescale 2m horizontal-pod-autoscaler New size: 3; reason: pods metric http_requests above target

按照当前的每秒请求速率,部署永远不会达到10个pod的最大值。三个复制品足以使每个吊舱的RPS保持在10以下。

负载测试完成后,HPA会将部署缩到其初始副本:

</>复制代码

  1. Events:
  2. Type Reason Age From Message
  3. ---- ------ ---- ---- -------
  4. Normal SuccessfulRescale 5m horizontal-pod-autoscaler New size: 3; reason: pods metric http_requests above target
  5. Normal SuccessfulRescale 21s horizontal-pod-autoscaler New size: 2; reason: All metrics below target

您可能已经注意到自动缩放器不会立即对使用峰值做出反应。默认情况下,度量标准同步每30秒发生一次,只有在最后3-5分钟内没有重新缩放时才能进行扩展/缩小。通过这种方式,HPA可以防止快速执行冲突的决策,并为Cluster Autoscaler提供时间。

结论

并非所有系统都可以通过多带带依赖CPU /内存使用指标来满足其SLA,大多数Web和移动后端需要基于每秒请求进行自动扩展以处理任何流量突发。对于ETL应用程序,可以通过作业队列长度超过某个阈值等来触发自动缩放。通过使用Prometheus检测应用程序并公开正确的自动缩放指标,您可以对应用程序进行微调,以更好地处理突发并确保高可用性。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/33142.html

相关文章

  • k8sHPA--通过 Prometheus adaptor 来自定义监控指标

    摘要:与通过来自定义监控指标自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。适配器删除后缀并将度量标记为计数器度量标准。负载测试完成后,会将部署缩到其初始副本您可能已经注意到自动缩放器不会立即对使用峰值做出反应。 k8s与HPA--通过 Prometheus adaptor 来自定义监控指标 自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。 Kubernetes中的自...

    HollisChuang 评论0 收藏0
  • k8sHPA--通过 Prometheus adaptor 来自定义监控指标

    摘要:与通过来自定义监控指标自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。适配器删除后缀并将度量标记为计数器度量标准。负载测试完成后,会将部署缩到其初始副本您可能已经注意到自动缩放器不会立即对使用峰值做出反应。 k8s与HPA--通过 Prometheus adaptor 来自定义监控指标 自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。 Kubernetes中的自...

    ityouknow 评论0 收藏0
  • 容器监控实践—Custom Metrics

    摘要:自定义指标由提供,由此可支持任意采集到的指标。文件清单的,收集级别的监控数据监控服务端,从拉数据并存储为时序数据。本文为容器监控实践系列文章,完整内容见 概述 上文metric-server提到,kubernetes的监控指标分为两种: Core metrics(核心指标):从 Kubelet、cAdvisor 等获取度量数据,再由metrics-server提供给 Dashboar...

    laznrbfe 评论0 收藏0
  • 容器监控实践—Custom Metrics

    摘要:自定义指标由提供,由此可支持任意采集到的指标。文件清单的,收集级别的监控数据监控服务端,从拉数据并存储为时序数据。本文为容器监控实践系列文章,完整内容见 概述 上文metric-server提到,kubernetes的监控指标分为两种: Core metrics(核心指标):从 Kubelet、cAdvisor 等获取度量数据,再由metrics-server提供给 Dashboar...

    DangoSky 评论0 收藏0
  • 容器监控实践—Heapster

    摘要:还可以把数据导入到第三方工具展示或使用场景共同组成了一个流行的监控解决方案原生的监控图表信息来自在中也用到了,将作为,向其获取,作为水平扩缩容的监控依据监控指标流程首先从获取集群中所有的信息。 概述 该项目将被废弃(RETIRED) Heapster是Kubernetes旗下的一个项目,Heapster是一个收集者,并不是采集 1.Heapster可以收集Node节点上的cAdvis...

    DDreach 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<