我们讲解了Kubernetes在核心监控体系的架构,在其中Prometheus在其中占据了核心位置
在Kubernetes中,还有一个能力,就是自定义监控指标,在Paas项目中,Auto Scaling也是由过存在的痕迹,不过,这个功能只在某种特定的资源类型中水平扩展使用,CPU或者Memory的使用值
在真实的情况下,Auto Scaling的实现是需要一定的成本的,因为Auto Scaling一般是自定义的监控指标,某个应用的等待队列的长度,和某种应用相关资源的使用情况,比较难以实现
在强大的API机制,Custom Metrics已经成为了Kubernetes的一项标准能力,Kubernetes的自动扩展器组件 HPA,可以直接使用Custom Metrics来指定用户的扩展策略,是可定制的
不难想到,Kubernetes中的Custom Metrics机制,可以借助Aggregator ApiServer来实现,当我们启动Custom Metrics APIService启动后,Kubernetes中就会出现一个叫做custom.metrics.k8s.io的API,访问这个URL的时候,Aggregator就会将请求进行转发到这个APIServer中
而Custom Metrics APIServer 的实现,就是Prometheus 项目的Adaptor,比如,我们要实现一个根据Pod收到的HTTP请求来进行Auto Scaling的Custom Metrics,这个Metrics就可以通过访问入下的自定义监控URL访问到
https://<apiserver_ip>/apis/custom-metrics.metrics.k8s.io/v1beta1/namespaces/default/pods/sample-metrics-app/http_requests
访问如上的URL,就会得到监控数据,暴露出来
这个http_request的值,可以自定义的方式暴露出来,比如Pod内的应用本身就暴露了一个/metrics的API,API中返回结果,由HPA进行定期的Pull,进行计算结果,我们看一下具体的使用方式,我们假设集群的Aggregator功能开启了
首先,我们部署一个Prometheus,我们使用了Prometheus Operator来完成,
$ kubectl apply -f demos/monitoring/prometheus-operator.yaml
clusterrole “prometheus-operator” created serviceaccount “prometheus-operator” created clusterrolebinding “prometheus-operator” created deployment “prometheus-operator” created $ kubectl apply -f demos/monitoring/sample-prometheus-instance.yaml clusterrole “prometheus” created serviceaccount “prometheus” created clusterrolebinding “prometheus” created prometheus “sample-metrics-prom” created service “sample-metrics-prom” created |
第二步,我们将Custom Metrics APIServer部署起来,如下所示
$ kubectl apply -f demos/monitoring/custom-metrics.yaml
namespace “custom-metrics” created serviceaccount “custom-metrics-apiserver” created clusterrolebinding “custom-metrics:system:auth-delegator” created rolebinding “custom-metrics-auth-reader” created clusterrole “custom-metrics-read” created clusterrolebinding “custom-metrics-read” created deployment “custom-metrics-apiserver” created service “api” created apiservice “v1beta1.custom-metrics.metrics.k8s.io” created clusterrole “custom-metrics-server-resources” created clusterrolebinding “hpa-controller-custom-metrics” created |
第三步,我们需要为Custom Metrics APIServer创建对应的ClusterRoleBinding,以便使用curl来访问Custom Metrics的API:
$ kubectl create clusterrolebinding allowall-cm –clusterrole custom-metrics-server-resources –user system:anonymous
clusterrolebinding “allowall-cm” created |
第四步,就将被监控的应用和HPA部署起来了,如下所示
$ kubectl apply -f demos/monitoring/sample-metrics-app.yaml
deployment “sample-metrics-app” created service “sample-metrics-app” created servicemonitor “sample-metrics-app” created horizontalpodautoscaler “sample-metrics-app-hpa” created ingress “sample-metrics-app” created |
最后HPA的配置如下所示
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta1 metadata: name: sample-metrics-app-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: sample-metrics-app minReplicas: 2 maxReplicas: 10 metrics: – type: Object object: target: kind: Service name: sample-metrics-app metricName: http_requests targetValue: 100 |
HPA的配置,就是设置Auto Scaling规则的地方,比如scaleTargerRef字段,就是指定了被监控的对象
为Deployment,名字为sample-metrics-app,并且,最小的实例数目为2,最大为10,在metrics字段,我们指定了HPA进行了Scale的依据,就是通过一个名为http_requests的监控指标,我们可以通过访问sample-metrics-app的Service来获取到
有了个字段的定义,HPA就会向下面的URL发起请求获取到Custom Metrics的值
https://<apiserver_ip>/apis/custom-metrics.metrics.k8s.io/v1beta1/namespaces/default/services/sample-metrics-app/http_requests |
需要注意的是,上面的URL对应的被监控对象,是我们应用对应的Service,这种使用Service来采集Pod的Metrics才是合理的做法
这样,我们可以通过一些脚本手段来进行测试访问压力
之后在访问应用的Service的Custom Metrics URL,就会看到能够返回HTTP的请求数量
$ curl -sSLk https://<apiserver_ip>/apis/custom-metrics.metrics.k8s.io/v1beta1/namespaces/default/services/sample-metrics-app/http_requests
{ “kind”: “MetricValueList”, “apiVersion”: “custom-metrics.metrics.k8s.io/v1beta1”, “metadata”: { “selfLink”: “/apis/custom-metrics.metrics.k8s.io/v1beta1/namespaces/default/services/sample-metrics-app/http_requests” }, “items”: [ { “describedObject”: { “kind”: “Service”, “name”: “sample-metrics-app”, “apiVersion”: “/__internal” }, “metricName”: “http_requests”, “timestamp”: “2018-11-30T20:56:34Z”, “value”: “501484m” } ] } |
我们看到,返回的结果值是HTTP request的总数,应用代码返回的也是如此
在Custom Metrics APIServer收到对于http_Request的指标的访问请求之后,会从Prometheus中查询http_request_total的值,将其折算为一个时间为单位的请求率,作为http_request的指标的值返回
Custom Metrics返回的值是501484m,这里的格式,就是换算好的请求速率,这里的格式是milli-requests,相当于是每秒501个请求,方便HPA使用,也避免了计算每秒的请求个数
那么Prometheus项目,如何知道采集哪些Pod的/metrics的API作为监控的指标来源呢?
那么会在之前创建Pod的时候,看到创建了一个ServiceMonitor的对象,其对应的YAML文件如下所示
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor metadata: name: sample-metrics-app labels: service-monitor: sample-metrics-app spec: selector: matchLabels: app: sample-metrics-app endpoints: – port: web |
通过配置了matchLabels来指定了被监控的应用
那么,在本章中,我们讲解了Kubernetes中的自定义监控指标,Custom Metrics的设计和实现机制,这套机制方便我们去扩展,使得Auto Scaling在Kubernetes中可以行之有效的使用
Kubernetes中的Aggregator APIServer,是一套行之有效的API扩容机制,Kubernetes提供了一套名为KubeBuilder的工具库,帮助其生成一个API Server的完整代码框架,然后选择性的添加自定义的API,完成业务逻辑
实际场景中,有什么样的指标可以作为Custom Metrics,对Pod进行Auto Scaling呢?
HPA通过HorizontalPodAutoscaler配置要访问的Custom Metrics,决定如何sacle,Custom Metrics API Server实现是一个Prometheus 的Adaptor,去决定读取哪个Pod/Service具体指标值,比如我们自定义的http request的请求率.
Prometheus通过ServiceMonitor object配置监控的Pod和endPoints,来确定监控哪些Pod的metrics
应用也需要实现/metrics,响应Prometheus的数据采集请求