本文属于 k8s 监控系列,其他文章为:node
原本按计划这篇文章应该讲 grafana 和 alertmanager 的,可是因为它们部署起来太简单没有啥写的动力。最近由于研究了 Prometheus adapter,因此想将本身的研究所得写下来,也许下一篇会写 grafana 和 alertmanager。。python
ok,让咱们直接进入正文。git
kubernetes apiserver 提供了两种 api 用于监控指标相关的操做:github
kubectl top
;kubernetes apiserver 用于将 kubernetes 的功能经过 restapi 的方式暴露出去,给其余组件使用,可是它提供的都是核心相关功能。有些功能有用,可是非核心,apiserver 又得提供这样的功能咋办?正则表达式
考虑到这样的状况,kubernetes apiserver 提供对应的 api,可是对于达到这个 api 的请求,它并不处理,而是转发到一个扩展 apiserver 上。有意思的是,这个扩展 apiserver 只要遵循规范,任何人均可以开发。json
使用者在使用扩展 apiserver 时,只须要将其注册到 kube-aggregator(kubernetes apiserver 的功能),aggregator 就会将对于这个 api 的请求转发到这个扩展 apiserver 上。固然 kubernetes apiserver 和扩展 apiserver 之间的交互会涉及到很是多的细节,这里就很少提。api
resource metrics API 和 custom metrics API 就是这样的例子,kubernetes apiserver 提供了这两个 api,可是具体的实现它就无论了。markdown
而这篇文章的目的就是经过 Prometheus adapter 实现它们。app
在实现这两个 api 以前,咱们先来聊聊 api 组和 api 版本。ide
所谓的 api group 就是你执行 kubectl api-versions
出现的值,这些值由 api group 和 api version 构成。
# kubectl api-versions admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 ... 复制代码
内容太多,这里只列出了 5 个。第一个 admissionregistration.k8s.io/v1beta1 中,admissionregistration.k8s.io
是 api group,v1beta1
表示它的版本。
若是 api group 为空表示核心 api,kubernetes 的资源都是由 api group 提供的。那么如何知道哪些资源是由哪些 api group 提供的呢?
执行 kubectl api-resources
就可以知道了:
# kubectl api-resources NAME SHORTNAMES APIGROUP NAMESPACED KIND bindings true Binding componentstatuses cs false ComponentStatus configmaps cm true ConfigMap endpoints ep true Endpoints events ev true Event limitranges limits true LimitRange namespaces ns false Namespace nodes no false Node ... 复制代码
内容不少,这里只列出一部分。输出结果为 5 列,NAME
列就是资源名,它的功能由 APIGROUP
列的 api group 提供。SHORTNAMES
列就是这些资源的缩写了,缩写在使用 kubectl 时很是好用。
上面列出的全部结果中,APIGROUP
都为空,表示这些资源都是核心 api 提供的。当你看到某些 role 或者 clusterRole 中 apiGroup
的值为 ""
时,就应该知道它要访问的资源都是核心 api 提供的。
对于咱们要实现的两个 api:
metrics.k8s.io
,版本为 v1beta1
;custom.metrics.k8s.io
,版本为 v1beta1
。它们的 api group 和 api version 会在后面注册时用到。
先说这个 custom metrics API,resource metrics API 放在后面。你若是说你只须要 resource metrics API,那你也得看这个,由于这两个 api 都由 Prometheus adapter 来实现。
custom metrics API 彻底就是给 HPA v2 准备的,由于 v1 只能使用 CPU 做为 pod 横向扩展的指标,很明显没法知足使用者的须要。
custom metrics API 的实现有多个,咱们之因此选择 Prometheus adapter,是由于咱们已经安装了 Prometheus。而经过 Prometheus adapter,只要存在于 Prometheus 中的指标,均可以拿来作 HPA 的条件,这样就能知足全部的使用场景了。
kubernetes 1.14 中 apiserver 已经开启了 Aggregation layer,所以咱们只须要安装 Prometheus adapter 就行。
咱们会使用 deployment 部署 Prometheus adapter,固然会为启动它的 serviceAccount 绑定各类角色。由于它自己就是一个 apiserver,所以它会监听一个端口,对外提供 http 服务。
咱们还须要为它建立一个 service,kubernetes apiserver 转发请求时,会将请求发送到 service 上,经由 service 到达后面的 Prometheus adapter。
本文全部的 yml 文件均保存在 GitHub,这里就不一一列出了。Prometheus adapter 相关的文件都在 adapter 目录下,custom metrics API 用到的文件有:
prometheus-adapter-apiServiceCustomMetrics.yml
prometheus-adapter-apiServiceMetrics.yml
prometheus-adapter-clusterRoleAggregatedMetricsReader.yml
prometheus-adapter-clusterRoleBindingDelegator.yml
prometheus-adapter-clusterRoleBinding.yml
prometheus-adapter-clusterRole.yml
prometheus-adapter-configMap.yml
prometheus-adapter-deployment.yml
prometheus-adapter-roleBindingAuthReader.yml
prometheus-adapter-serviceAccount.yml
prometheus-adapter-service.yml
复制代码
其中:
custom.metrics.k8s.io
,版本为 v1beta1
;metrics.k8s.io
,版本为 v1beta1
。这是给 resource metrics 使用的;metrics.k8s.io
和 custom.metrics.k8s.io
下面的任意资源具备任意权限;不少人在使用的时候会使用 kubernetes CA 签署一个证书以后用这个证书来为 Prometheus adapter 提供 https。其实不须要如此,Prometheus adapter 启动的时候,若是你没有给它提供证书,它会生成一个自签署的证书来提供 https。
至于这个证书是否受信任并不重要,由于 prometheus-adapter-apiServiceCustomMetrics.yml
文件中存在 insecureSkipTLSVerify: true
这个选项。
clone 并部署:
git clone https://github.com/maxadd/k8s-prometheus kubectl apply -f k8s-prometheus/adapter 复制代码
经过下面直接访问 api 的方式来测试部署是否 ok(你可能须要略等一下子):
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | python -mjson.tool kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/*/fs_usage_bytes" | python -mjson.tool 复制代码
第一条命令会输出很是多的值,都是能够用做 HPA 的指标。若是你没有,那么部署存在问题,缘由后面会讲。
第二条命令会输出 monitoring 名称空间下全部 pod 的 fs_usage_bytes
指标的值,若是你没有,那么部署一样存在问题。
由于我前面安装 Prometheus 的文章中对 Prometheus 中的一些指标和标签作了一些修改,所以若是你直接使用官方的配置,那么确定会出问题的。配置相关的内容下面会提到。
另外,Prometheus adapter 启动参数中的 -v
至关于 debug 级别,值越大,输出的日志就越详细,最高貌似为 10?可是好像这个日志没啥做用。。
Prometheus adapter 的配置文件格式以下所示(因为过长,因此截取了一部分)。它分为两个部分,第一个是 rules,用于 custom metrics;另外一个是 resourceRules,用于 metrics。若是你只用 Prometheus adapter 作 HPA,那么 resourceRules 就能够省略,反之亦然。
咱们从 rules 规则讲起,这个规则下面有不少的查询语句,这些查询语句的做用就是尽量多的获取指标,从而让这些指标均可以用于 HPA。
也就是说经过 Prometheus adapter,你能够将 Prometheus 中的任何一个指标都用于 HPA,可是前提是你得经过查询语句将它拿到(包括指标名称和其对应的值)。也就是说,若是你只须要使用一个指标作 HPA,那么你彻底就能够只写一条查询,而不像下面使用了好多个查询。
rules: - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod!=""}' seriesFilters: [] resources: overrides: namespace: resource: namespace pod: # 官方示例中的这个值为 pod_name,因为我以前将 pod_name 改成了 pod,因此这里也为 pod resource: pods name: matches: ^container_(.*)_seconds_total$ as: "" metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}[1m])) by (<<.GroupBy>>) --- resourceRules: cpu: containerQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) nodeQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>, id='/'}[1m])) by (<<.GroupBy>>) resources: overrides: instance: resource: nodes namespace: resource: namespace pod: resource: pods containerLabel: container_name 复制代码
接下来咱们会对其关键字进行解释:
is: <regex>
:只获取正则表达式匹配到的指标名称;isNot: <regex>
:overrides
,另外一种是 template
。
microservice: {group: "apps", resource: "deployment"}
这么写表示将指标中 microservice 这个标签和 apps 这 api 组中 deployment 资源关联起来;template: "kube_<<.Group>>_<<.Resource>>"
这么写表示,假如 <<.Group>>
为 apps,<<.Resource>>
为 deployment,那么它就是将指标中 kube_apps_deployment
标签和 deployment 资源关联起来;$1
,也就是第一个分组。as 为空就是使用默认值的意思。前面访问 /apis/custom.metrics.k8s.io/v1beta1/
出现的全部指标都是这些规则中 seriesQuery 查询到的,固然名称可能和 Prometheus 中不彻底同样,由于这里使用了 name 进行了重命名。
其实不少指标拿来作 HPA 是没有必要的,好比说 Prometheus 自身的指标以及 k8s 组件指标等,可是 Prometheus adapter 确定但愿将全部的指标都暴露出来,让你想使用啥就使用啥,因此它的 seriesQuery 才会这么多。
访问 /apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/*/fs_usage_bytes
则是经过 metricsQuery 进行查询,从而获取每一个 pod 的指标值。
部署有问题的多半就是配置文件中的关联没有作好,只有理解了这个配置文件的意思才能保证部署没有问题。
剩下的 resourceRules 规则则是用于 resource metrics,只有 cpu 和 memory 两个属性,而这两个属性又分为 node 和 pod,很容易看懂。当执行 kubectl top pods/nodes
时就会执行这两条查询语句。
关于 custom metrics 就到此为止了,HPA 的内容这里就不涉及了。
resource metrics API 官方的说法是给 k8s 核心组件提供监控指标的,可是它只提供了 pod 和 node 的 CPU 和内存指标,功能实在有限。
官方给出它能够作如下工做:
因此总结下来,resource metrics API 的最大做用就是居然是让你可使用 kubectl top
命令?固然我们先无论它是否有用,咱们目的之一就是部署一个扩展 apiserver 来实现它,接下来就是选一个扩展 apiserver。
不少人会使用 metrics server 提供 resource metrics API,而后使用 Prometheus adapter 提供 custom metrics API。可是其实 Prometheus adapter 彻底能够支持这两种 api,所以咱们彻底不须要 metrics server,只部署一个 Prometheus adapter 就行。
前面咱们其实已经部署好了,只须要验证就行。
# kubectl -n monitoring top pods NAME CPU(cores) MEMORY(bytes) alertmanager-c8d754fbc-2slzr 1m 15Mi grafana-74bf6c49f6-lf7vw 7m 50Mi kube-state-metrics-856448748c-xtdxl 0m 24Mi prometheus-adapter-548c9b9c4c-mr9zq 0m 39Mi 复制代码
可是执行 kubectl top node
会出现问题,由于我将 id='/'
的指标都删掉了,若是不想将这些指标恢复,能够看我下一篇收集宿主机指标的文章。
这篇文章就到这了,感谢阅读,谢谢!