摘要:使用自定义监控指标自动扩展是一种根据资源使用情况自动扩展或缩减工作负载的方法。 适配器删除后缀并将指标标记为计数器指标。 负载测试完成后,部署将缩减至第一个副本。 您可能已经注意到,自动缩放程序不会立即响应使用高峰。
k8s和HPA--使用Prometheus适配器自定义监控指标
基于资源的自动伸缩是一种自动伸缩的方法或者缩小使用工作量的方法。 Kubernetes 中的自动缩放有两个方面。 集群自动缩放器处理节点缩放操作,水平 Pod 自动缩放器自动缩放部署或副本集中的 Pod 数量。 集群自动缩放与水平 Pod 自动缩放器结合使用,可以动态调整系统所需的计算能力和并行度,以满足 SLA。 虽然集群自动缩放程序在很大程度上依赖于托管集群的云提供商的底层功能,但 HPA 可以独立于 IaaS/PaaS 提供商运行。
水平 pod 自动缩放器功能首次在 Kubernetes v1.1 中引入,此后已经发生了显着的发展。 HPA 扩展容器的版本 1 基于观察到的 CPU 使用情况,后来基于内存使用情况。 Kubernetes 1.6 引入了一个新的 API,即自定义指标 API,使 HPA 能够访问任意指标。 Kubernetes 1.7 引入了一个聚合层,允许第三方应用程序通过将自己注册为 API 插件来扩展 Kubernetes API。 自定义指标 API 和聚合层允许 Prometheus 等监控系统向 HPA 控制器公开特定于应用程序的指标。
水平 Pod 自动缩放器被实现为定期查询资源的控制循环。ce 指标 API 用于获取 CPU/内存等核心指标,以及针对特定应用程序指标的自定义指标 API。
以下是为 Kubernetes 1.9 及更高版本配置 HPA v2 的分步指南。 安装提供核心指标的 Metrics Server 附加组件,并使用演示应用程序来演示根据 CPU 和内存使用情况自动扩展 Pod。 在本指南的后面部分,您将部署 Prometheus 和自定义 API 服务器。 使用聚合器层注册自定义 API 服务器,并使用演示应用程序提供的自定义指标配置 HPA。
开始之前,您需要安装 Go 1.8 或更高版本,并将 k8s-prom-hpa 存储库克隆到 GOPATH。
cd $GOPATHgit clone https://github.com/stefanprodan/k8s-prom-hpa
部署指标服务器
kubernetes指标A服务器资源使用数据的集群范围聚合器和 Heapster 的后继者。 指标服务器通过聚合来自 kubernetes.summary_api 的数据来收集节点和 Pod 的 CPU 和内存使用情况。 摘要 API 是一种节省内存的 API,用于将数据从 Kubelet/cAdvisor 传递到 Metrics Server。
HPA 的第一个版本要求 Heapster 提供 CPU 和内存指标,但在 HPA v2 和 Kubernetes 1.8 中,现在这是水平的 仅适用于 ntal[k4 ]pod-自动定标器。 -使用-rest-客户端只需要一个指标服务器。 Kubernetes 1.9 中默认启用 HPA REST 客户端。 GKE 1.9 预装了 Metrics Se河。
在 kube-system 命名空间中部署指标服务器:
kubectl create -f ./metrics-server
1 之后几分钟后,指标服务器开始报告节点和 Pod 的 CPU 和内存使用情况。
查看节点指标:
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq 。
结果是:
{ "kind": "NodeMetricsList", "apiVersion": "metrics.k8s.io/v1beta1", "metadata": { "selfLink": "/apis/metrics.k8s .io/v1beta1 /nodes" }, "items": [ { "metadata": { "name": "ip-10-1-50[ k4]61.ec2.internal", "selfLink ": "/ apis/metrics.k8s.io/v1beta1/nodes/ip-10-1-50-61.ec2.internal", "creationTimestamp": "2019-02-13T08: 34:05Z" }, "时间戳": "2019-02-13T08:33:38Z", "窗口": "30s", "用法": { "cpu": "78322168n", "内存" :“563180Ki”} }, { "metadata": { "name": "ip-10-1-57-40.ec2.internal", "selfLink": "/apis/metrics.k8s.io /v1beta1/nodes/ip-10-1-57-40.ec2.internal", "creationTimestamp": "2019-02-13T08:34:05Z" }, "时间戳": "2019-02-13T08:33:42Z", "窗口": "30 秒", "使用情况": { "cpu": "48926263n", "内存": "554472Ki " } } , { “元数据”: { “名称”: “ip-10-1-62-29.ec2.internal”, “selfLink”: “/apis/metrics.k8s .io/v1beta1 /nodes/ip-10-1-62-29.ec2.internal", "creationTimestamp": "2019-02-13T08:34:05Z" } , "时间戳" : "2019-02-13T08:33:36Z", "窗口": "30s", "使用情况": { "cpu": "36700681n", "内存": "326088Ki" }} ]}
查看 Pod 指标:
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/pods" | jq .
结果是:
{ "kind": "PodMetricsList", "apiVersion": "metrics.k8s.io/v1beta1", "metadata": { "selfLink": "/apis/metrics.k8s.io/v1beta1 /pods" }, "items": [ { "metadata": { "name": "kube-proxy-77nt2", "namespace" : "kube-system" , "selfLink": "/ apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-proxy-77nt2", "creationTimestamp": "2019-02-13T08:35:19Z" }, "timestamp": "2019-02-13T08:35:00Z", "window": "30s", "container": [ { "name": "kube-proxy", " 用法": { "cpu": "2370555n", "内存": "13184Ki" } } ] },{ “元数据”:{ “名称”:“cluster-autoscaler-n2xsl”, “命名空间”:“kube-system”, “selfLink”:“/apis/metrics.k8s.io/ v1beta1/命名空间/kube-system/pods/cluster-autoscaler-n2xsl", "creationTimestamp": "2019-02-13T08:35:19Z" }, "timestamp": "2019 - ] ]02-13T08:35:12Z", "window": "30s", "container": [ { "name": "cluster- autoscaler", "usage": { "cpu ": "1477997n " , "内存": "54584Ki" } } ] }, { "元数据": { "名称": "core-dns-autoscaler-b4785d4d7-j64xd", "命名空间": "kube [ k4]system", "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/core-dns-autoscaler-b4785d4d7 -j64xd", "creationTimestamp": "2019-02-13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:08Z", "窗口": "30s" , "Container": [ { "Name": "Autoscaler", "Usage": { "cpu": "191293n", "Memory": "7956Ki" } } ] }, { "Metadata": { "name": “spot-中断-handler-8t2xk”,“命名空间”:“kube-system”,“selfLink”:“/apis/metrics.k8s.io/v1beta1/namespaces/kube -系统/pods/spot-中断-处理程序-8t2xk","creationTimestamp":"2019-02-13T08:35:19Z"},"时间戳":"2019-02 -13T08:35:04Z", "window": "30s", "containers": [ { "name": "spot-interrupt-handler", "usage": { "cpu ":"844907n", "内存": "4608Ki" } } ] }, { "元数据": { "名称": "kube-proxy-t5kqm", "命名空间": "kube-system ", “selfLink”:“/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-proxy-t5kqm”,“creationTimestamp”:“2019-02- 13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:08Z", "窗口": "30s", "容器": [ { "名称": " kube[k4 ]proxy", "用法": { "cpu": "1194766n", "内存": "12204Ki" } } ] }, { "元数据": { "name": "kube-proxy[k4 ]zxmqb" , “命名空间”: “kube-system”, “selfLink”: “/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-proxy- zxmqb", "creationTimestamp": "2019-02-13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:06Z", "窗口": "30s ", "容器": [ { "名称": "kube-proxy", "使用情况": { "cpu": "3021117n", "内存": "13628Ki" } } ] }, { "元数据": { “名称”:“aws-node-rcz5c”, “命名空间”:“kube-system”, “selfLink”:“/apis/metrics.k8s.io/v1beta1/namespaces/kube [k4 ]system/pods/aws-node-rcz5c", "creationTimestamp": "2019-02-13T08:35:19Z" }, "timestamp": "2019-02[ k4] 13T08:35:15Z", "window": "30s", "container": [ { "name": "aws-node", "usage": { "cpu": "1217989n", "内存": “24976 基”} } ] }, { "元数据": { "名称": "aws-node-z2qxs", "命名空间": "kube-system", "selfLink": "/apis/metrics .k8s .io/v1beta1/namespaces/kube-system/pods/aws-node-z2qxs","creationTimestamp":"2019-02-13T08:35:19Z"},"时间戳" : "2019-02-13T08:35:15Z", "window": "30s", "container": [ { "name": "aws-node", "usage" : { "cpu ": "1025780n", "内存": "46424Ki" } } ] }, { "元数据": { "名称": "php-apache-899d75b96-8ppk4", "命名空间": "默认”、“selfLink”:“/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/php-apache-899d75b96-8ppk4”、“creationTimestamp”:“2019-02-13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:08Z", "窗口": "30s", "容器": [ { "名称": "php-apache", "用法": { "cpu": "24612n", "内存": "27556Ki" } } ] }, { "元数据": { "名称": "负载[ k4 ] ]generator-779c5f458c-9sglg", "namespace": "default", "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/load-generator[ k4 ] 779c5f458c-9sglg", "creationTimestamp": "2019-02-13T08:35:19Z" }, "时间戳": "2019-02-13T08:34:56Z", " window": "30s", "containers": [ { "name": "load-generator", "usage": { "cpu": "0", "memory": "336Ki" }} ] }, { "metadata": { "name": "aws-node-v9jxs", "namespace": "kube-system", "selfLink": "/apis/metrics.k8s. io/v1beta1/namespaces/kube-system/pods/aws-node-v9jxs", "creationTimestamp": "2019-02-13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:00Z", "window": "30s", "containers": [ { "name": "aws-node", "usage": { "cpu" : "1303458n", "内存": "28020Ki" } } ] }, { "元数据": { "名称": "kube2iam-m2ktt", "命名空间": "kube-system" , "selfLink" :“/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube2iam-m2ktt”,“creationTimestamp”:“2019-02-13T08:35 :19Z”} ,”时间戳": "2019-02-13T08:35:11Z", "窗口": "30s", "容器": [ { "名称": "kube2iam", "使用情况": { "cpu ": "1328864n", "内存": "9724Ki" } } ] }, { "元数据": { "名称": "kube2iam-w9cqf", "命名空间": "kube-system", "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube2iam-w9cqf", "creationTimestamp": "2019-02-13T08:35: 19Z" }, “时间戳”:“2019 - 02 - 13T08:35:03Z”,“窗口”:“30秒”,“容器”:[ {“名称”:“kube2iam”,“用法”:{“cpu” : "1294379n", "内存": "8812Ki" } } ] }, { "元数据": { "名称": "自定义-指标[k]4]apiserver-657644489c-pk8rb","命名空间":"监控","selfLink":"/apis/metrics.k8s.io/v1beta1/namespaces/monitoring/pods/custom-metrics[k4 ] ]apiserver-657644489c-pk8rb", "creationTimestamp": "2019-02-13T08:35:19Z" }, "时间戳": "2019-02-13T08:35 : 04Z", "窗口": "30s", "容器": [ { "名称": "自定义-metrics-apiserver", "使用情况": { "cpu": "22409370n", "内存 " : "42468Ki" } } ] }, { "metadata": { "name": "kube2iam-qghgt", "namespace": "kube-system", "selfLink": "/apis/metrics.k8s io/v1beta1/namespaces/kube-system/pods/kube2iam-qghgt", "creationTimestamp": "2019-02-13T08:35:19Z" },“时间戳”:“2019-02-13T08:35:11Z”,“窗口”:“30s”,“容器”:[ {“名称”:“kube2iam”,“使用情况”:{“cpu” : "2078992n", "内存": "16356Ki" } } ] }, { "元数据": { "名称": "Spot-Interrupt-Handler-ps745", "命名空间": " kube[ k4]system", "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/spot-interrupt-handler-ps745", "creationTimestamp": "2019-02-13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:10Z", "窗口": "30s", "容器": [ { "name": "spot-interrupt-handler", "usage": { "cpu": "611566n", "memory": "4336Ki" } } ]}, { "metadata": { "name": "coredns-68fb7946fb-2xnpp", "namespace": "kube-system", "selfLink": "/apis/metrics.k8s.io/ v1beta1/namespaces/kube-system/pods/coredns-68fb7946fb-2xnpp", "creationTimestamp": "2019-02-13T08:35:19Z" }, "时间戳": "2019 -02-13T08:35:12Z", "window": "30s", "container": [ { "name": "coredns", "usage": { "cpu": "1610381n ", "内存": "10480Ki" } } ] }, { "元数据": { "名称": "coredns-68fb7946fb-9ctjf", "命名空间": "kube-system", "selfLink": " /apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/coredns-68fb7946fb-9ctjf", "creationTimestamp": "2019-02[k]4]13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:13Z", "窗口": "30s", "容器": [ { "名称": " coredns ", "用法": { "cpu": "1418850n", "内存": "9852Ki" } } ] }, { "元数据": { "名称": "prometheus-7d4f6d4454-v4fnd ", "命名空间”:“监控”,“selfLink”:“/apis/metrics.k8s.io/v1beta1/namespaces/monitoring/pods/prometheus-7d4f6d4454-v4fnd”,“creationTimestamp”:“2019-02 -13T08:35:19Z" }, "时间戳": "2019-02-13T08:35:00Z", "窗口": "30s", "容器": [ { "名称": "普罗米修斯", "使用情况": { "cpu": "17951807n", "内存": "202316Ki" } } ] },{ "metadata": { "name": "metrics-server-7cdd54ccb4-k2x7m", "namespace": "kube-system", "selfLink": "/apis/metrics.k8s. io/v1beta1/namespaces/kube-system/pods/metrics-server-7cdd54ccb4-k2x7m","creationTimestamp":"2019-02-13T08:35:19Z"}, “时间戳”:“2019-02-13T08:35:04Z”,“窗口”:“30秒”,“容器”:[{“名称”:“指标-服务器-保姆”, “使用情况”:{“CPU”:“144656n”,“内存”:“5716Ki”}},{“名称”:“指标-服务器”,“使用情况”:{“CPU”:“568327n”,“ memory": "16268Ki" } } ] } ]}
根据 CPU 和内存使用情况自动缩放
使用基于 Golang 的小型 Web 应用程序并测试 Horizontal。 荚自动定标器 (HPA)。
将 podinfo 部署到默认命名空间。
kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.
使用NodePort服务,访问podinfo。位于 http://:31198。
接下来,定义一个至少维护两个副本的 HPA。 如果 CPU 平均值高于 80% 或内存高于 200Mi,则扩展到 10。
apiVersion:autoscaling/ v2beta1kind:horizontalPodAutoscalermetadata:名称:podinfospec:scaleTargetRef:apiVersion:extensions/v1beta1类型:部署名称:podinfo minReplicas:2 maxReplicas:10指标:-类型:资源资源:名称: cpu targetAverageUtilization: 80 - 类型: 资源 资源: 名称: 内存 targetAverageValue: 200Mi
创建此 hpa:
kubectl create -f ./ podinfo/podinfo- hpa.yaml
几秒钟后,HPA 控制器连接到指标服务器并获取 CPU 和内存使用情况:
kubectl get hpaNAME参考目标 MINPODS MAXPODS REPLICAS AGEpodinfo Deployment/podinfo 2826240 / 200Mi, 15% / 80% 2 10 2 5m
要增加 CPU 使用率,请使用 rakyll/hey 运行负载测试:
#install heygo get -u github.com/rakyll/hey#do 10K requestshey -n 10000 -q 10 -c 5 http://:31198/
您可以使用以下方式监控 HPA 事件:
$ kubectl 描述 hpaEvents:消息类型原因年龄 ---- ---[ k4] -- - --- ---- ------ - ] 正常成功 重新缩放 7m 水平[ k4]pod-autoscaler 新大小:4;原因:CPU 资源使用率(请求百分比)超出目标。 顺利完成。fulRescale 3m Horizontal-pod-autoscaler 新大小:8;原因:CPU 资源使用率(请求百分比)高于目标。
暂时删除podinfo。 我们将在本教程稍后再次部署:
kubectl delete -f ./podinfo/podinfo-hpa.yaml,./podinfo/podinfo-dep.yaml,./ podinfo/ podinfo-svc.yaml
部署自定义指标服务器
需要两个组件才能使用自定义指标进行扩展。 用于从应用程序收集指标并将其存储在 Prometheus 时间序列数据库中的组件。 第二个组件使用 Collect (k8s-prometheus-adapter) 提供的指标扩展 Kubernetes 自定义指标 API。
将 Prometheus 和适配器部署到私有命名空间。
监控创建命名空间:
kubectl create -f ./namespaces.yaml
部署 Prometheus v2在MonitoringStrong命名空间中:
kubectl create -f ./prometheus
输入Prometheus适配器所需的TLS证书生成:
制作证书
生成以下文件:
# ls outapiserver.csr apiserver-key.pem apiserver.pem
部署 Prometheus Custom Metrics API 适配器:
kubectl create -f ./custom-metrics- api
列出 Prometheus 提供的自定义指标。
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .
监控命名空间获取所有 Pod 的 FS 使用情况:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/ */fs_usage_bytes" | jq 。
查询结果为:
{ "kind": "MetricValueList", "apiVersion": "custom .metrics.k8s.io/v1beta1", "元数据": { "selfLink": "/apis/custom.metrics.k8s .io/v1beta1/namespaces/monitoring/pods/%2A/fs_usage_bytes" }, "items": [ { "描述对象": { "type": "pod", "namespace": "monitoring", "name" : “自定义-指标-apiserver-657644489c-pk8rb”,"apiVersion": "/v1" }, "metricName": "fs_usage_bytes", "timestamp": "2019-02-13T08:52:30Z", "value": "94253056" }, { "描述对象 ": { "kind": "Pod", "namespace": "监控", "name": "prometheus-7d4f6d4454-v4fnd", "apiVersion": "/v1" }, "metricName": " fs_usage_bytes", "timestamp": "2019-02-13T08:52:30Z", "value": "24576" } ]}
基于自定义指标自动缩放在默认命名空间中创建 podinfo NodePort 服务和部署。
kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.
podinfo 应用程序名为 http_requests_total。发布 的自定义指标。 Prometheus 适配器删除 _total 后缀并将该指标标记为计数器指标。
从自定义指标 API 获取每秒的总请求数:
kubectl get --raw "/apis/custom.metrics.k8s.io /v1beta1/namespace /默认/pods/*/http_requests" | jq .
{ "kind": "MetricValueList", "apiVersion": "custom.metrics.k8s.io/v1beta1", "metadata": { "selfLink" : "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/http_requests" }, "items": [ { "描述对象": { "kind": "pod", "name空格”:“默认”,“名称”:“podinfo-6b86c8ccc9-kv5g9”,“apiVersion”:“/__internal”},“metricName”:“http_requests”,“时间戳”:“2018- 01[ k4]10T16:49:07Z", "value": "901m" }, { "描述对象": { "type": "pod", "namespace": "default", "name": "podinfo [ k4]6b86c8ccc9 -nm7bl", "apiVersion": "/__internal" }, "metricName": "http_requests", "时间戳": "2018-01-10T16:49:07Z", "value": "898m" } ]}
构建 HPA。当请求数超过每秒 10 个时,podinfo 部署会扩展:
apiVersion : autoscaling/v2beta1kind:horizontalPodAutoscalermetadata: name : podinfospec: scaleTargetRef: apiVersion: extensions/v1beta1 kind: 部署名称: podinfo minReplicas: 2 maxReplicas: 10 指标: - 类型: Pods pods: metricName: http_requests targetAverageValue: 10
默认命名空间 podinfo HPA 部署:
kubectl create -f ./podinfo/podinfo-hpa-custom.yaml
几秒钟后,HPA 将检索 http_requests Metrics API 值:
kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEpodinfo Deployment/podinfo 899m / 10 2 10 2 1m
podinfo 服务每秒 25 个请求:
#install heygo get - u github.com/rakyll/hey#do 10K 请求sts 速率受 25 QPShey -n 10000 -q 5 -c 5 http://:31198/healthz
限制。 几分钟后,HPA 将开始部署:
kubectl description hpaName: podinfoNamespace:defaultReference: Deployment/podinfoMetrics: ( current / target ) "http_requests" on pod: 9059m / 10Min Replicas: 2Max Replicas: 10Events:类型 原因 消息年龄 [ k4] --- ------ ---- [ k4] -- [k4 ] ------- 正常成功重新缩放 2m 水平 -pod- 自动缩放器 新大小:3;原因: Pod 指标 http_requests 高于目标
按照当前的每秒请求速率,您的部署永远不会达到 10 个 Pod 的最大值。 每份复印 3 份就足够了每个 Pod 的 RPS 保持在 10 以下。
负载测试完成后,HPA 会将部署缩减到初始副本。
事件:消息类型原因年龄 -[ --- [k4 ]----- -[k4 ]-- ---- ---[ k4]--- 通常成功重新缩放 5m 水平 -pod [ k4] 自动缩放器新大小:3;原因:Pod 指标 http_requests 超出目标。 顺利完成。 重新调整 21 秒。 水平-pod-autoscaler 新大小:2。 原因:所有指标均低于目标
您可能已经注意到,自动缩放程序不会立即对使用高峰做出反应。 默认情况下,指标同步每 30 秒进行一次,并且只有在过去 3-5 分钟内没有重新缩放的情况下才可以向上/向下缩放。 通过这种方式,HPA 可以防止快速执行冲突的决策,并为集群自动缩放程序提供时间。
结论
并非所有系统都能满足具有多频段相关 CPU/内存使用指标的 SLA。 大多数网络和移动后端需要根据每秒请求进行自动缩放才能完成所有处理。 流量爆发。 对于 ETL 应用程序,可以触发自动缩放,例如,当作业队列长度超过某个阈值时。 通过使用 Prometheus 检测您的应用程序并公开适当的自动缩放,扩展指标允许您微调应用程序以更好地处理突发并确保高可用性。
评论前必须登录!
注册