使用Prometheus监控Kubernetes集群

监控方面Grafana采用YUM安装通过服务形式运行,部署在Master上,而Prometheus则通过POD运行,Grafana通过使用Prometheus的service地址来获取数据源。

Prometheus的配置清单在kubernetes二进制程序包中就有,下载地址

解压后有一个cluster目录,该目录里面的addons里面有所需要的插件,比如dns、dashboard以及prometheus等。

我用的就是它自带的这个prometheus清单文件,但是它里面有些问题比如prometheus这个组件需要PV但是原始的包里面没有这个PV你需要手动建立,我这里已经写好了yaml文件不过使用的是hostpath,主要是为了测试方便如果是生产环境中不建议这样使用至少也要用个NFS这种存储,另外它原始的清单文件中使用的prometheus等镜像版本较低虽然也可以使用但是我修改了这些版本使用的最新的版本,最新版本中有些启动参数变化了所以也修改了响应的内容。所以你直接使用我修改的这个就可以,从下面的链接下载,另外这里还包括了grafana的2个dashboard,这两个也做了修改,因为从官网下载的模板对于有些指标识别不了(因为版本问题或者其他问题导致指标名称对不上),所以需要修改。

文件说明

上图是原始内容,我包里的yaml文件只比它多一个。上面分成4个部分,

下面这4个是部署prometheus服务端用的
prometheus-configmap.yaml # 我在原有的配置中增加了global区域
prometheus-rabc.yaml
prometheus-service.yaml
prometheus-statefulset.yaml

下面这2个是部署node_exporter用的
node-exporter-ds.yaml
node-exporter-service.yaml

下面3个是部署kube-state-metrics用的,这个组件是对监控内容的补充,虽然你部署了metric-server、kubelet也提供了cadvisor接口以及上面
部署的node_exporter,但是还有一些指标需要监控比如调度了多少副本现在有几个可用、不同状态的POD有多少、POD重启了多少次、运行了多少job等
这个组件也是从API SERVER上去获取数据但是这些数据是原始数据而不像kubectl那样可能会为了便于理解而对某些数据做修改
kube-state-metrics-deployment.yaml
kube-state-metrics-rabc.yaml
kube-state-metrics-service.yaml

下面4个是alertmanager报警组件的部署
alertmanager-service.yaml
alertmanager-pvc.yaml
alertmanager-deployment.yaml
alertmanager-configmap.yaml

kube-state-metrics与metric-server的对比

metric-server(或heapster)是一个集群组件定期通过kubelet来获取集群节点的cpu、内存使用率这种监控指标,而且它只保留最新数据且存储在内存中,不负责发送给第三方,你可以通过其他方式把他们发送给存储后端,如influxdb或云厂商,他当前的核心作用是:为HPA等组件提供决策指标支持。

kube-state-metrics关注于获取k8s各种资源对象的最新状态,如deployment或者daemonset,它在内存中保留kubernetes集群状态的快照并且在随后的时间里基于这个快照生成新的指标,而且它也不负责发数据发给第三方。将kube-state-metrics作为单独的项目,还可以从Prometheus等监控系统访问这些指标。

之所以没有把kube-state-metrics纳入到metric-server的能力中,是因为他们的关注点本质上是不一样的。metric-server仅仅是获取、格式化现有数据,写入特定的存储,实质上是一个监控系统。而kube-state-metrics是将k8s的运行状况在内存中做了个快照,并且获取新的指标,但他没有能力导出这些指标 换个角度讲,kube-state-metrics本身是metric-server的一种数据来源,虽然现在没有这么做。 另外,像Prometheus这种监控系统,并不会去用metric-server中的数据,他都是自己做指标收集、集成的(Prometheus包含了metric-server的能力),但Prometheus可以监控metric-server本身组件的监控状态并适时报警,这里的监控就可以通过kube-state-metrics来实现,如metric-serverpod的运行状态。

POD的Annotations是什么

Annotations将任何非标识metadata附加到对象,标签可用于选择对象并查找满足某些条件的对象集合。相比之下,Annotations不用于标识和选择对象,虽然它也是键值形式。Annotations不会被Kubernetes直接使用,其主要目的是方便用户阅读查找。

Prometheus配置文件说明


# Kubernetes的API SERVER会暴露API服务,Promethues集成了对Kubernetes的自动发现,它有5种模式:Node、Service
# 、Pod、Endpoints、ingress,下面是Prometheus官方给出的对Kubernetes服务发现的实例。这里你会看到大量的relabel_configs,
# 其实你就是把所有的relabel_configs去掉一样可以对kubernetes做服务发现。relabel_configs仅仅是对采集过来的指标做二次处理,比如
# 要什么不要什么以及替换什么等等。而以__meta_开头的这些元数据标签都是实例中包含的,而relabel则是动态的修改、覆盖、添加删除这些标签
# 或者这些标签对应的值。而且以__开头的标签通常是系统内部使用的,因此这些标签不会被写入样本数据中,如果我们要收集这些东西那么则要进行
# relabel操作。当然reabel操作也不仅限于操作__开头的标签。
#
# action的行为:
# replace:默认行为,不配置action的话就采用这种行为,它会根据regex来去匹配source_labels标签上的值,并将并将匹配到的值写入target_label中
# labelmap:它会根据regex去匹配标签名称,并将匹配到的内容作为新标签的名称,其值作为新标签的值
# keep:仅收集匹配到regex的源标签,而会丢弃没有匹配到的所有标签,用于选择
# drop:丢弃匹配到regex的源标签,而会收集没有匹配到的所有标签,用于排除
# labeldrop:使用regex匹配标签,符合regex规则的标签将从target实例中移除,其实也就是不收集不保存
# labelkeep:使用regex匹配标签,仅收集符合regex规则的标签,不符合的不收集
#
global:
scrape_interval: 10s
evaluation_interval: 30s
scrape_configs:
# 用于发现API SERVER
- job_name: 'kubernetes-apiservers'


kubernetes_sd_configs:
# 发现endpoints,它是从列出的服务端点发现目标,这个endpoints来自于Kubernetes中的service,每一个service都有对应的endpoints,这里是一个列表
# 可以是一个IP:PORT也可以是多个,这些IP:PORT就是service通过标签选择器选择的POD的IP和端口。所以endpoints角色就是用来发现server对应的pod的IP的
# kubernetes会有一个默认的service,通过找到这个service的endpoints就找到了api server的IP:PORT,那endpoints有很多,我怎么知道哪个是api server呢
# 这个就靠source_labels指定的标签名称了。
- role: endpoints
# 通过什么形式来连接,默认是https
scheme: https
# 下面这个ca_file和token_file的路径都是默认的,你可能默认设置能用么?其实可以,因为每一个运行起来的POD kubernetes都会为其
# 创建一个serviceaccout的Secret并且挂载到下面的目录上,里面就有ca.crt和token这两个文件,你可以自己启动一个POD,然后通过
# kubectl describe pods 来查看,一定会在Volumes下面有一个default-token-XXX的东西,并且Mounts里面有下面的目录。
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token


# 下面的含义是源标签__meta_kubernetes_namespace等如果其值为default;kubernetes;https标签顺序和值要对应。换句话说就是
# 当__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name三者对应的
# 值为default、kubernetes、https则进行保留,而且该endpoints对应的地址为api server的地址。
#
# __meta_kubernetes_namespace 端点对象的命名空间,在不同对象上这个标签的含义不同,在角色是endpoints中这个是端点对象的名称空间
# __meta_kubernetes_service_name 端点对象的服务名称
# __meta_kubernetes_endpoint_port_name 端点的端口名称
#
# kubernetes默认在default名称空间有一个叫做kubernetes的service,所以这个service的有3个设置对应的就是下面三个标签
# __meta_kubernetes_namespace 值为default
# __meta_kubernetes_service_name 值为kubernetes
# __meta_kubernetes_endpoint_port_name 值为https
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https


# 配置针对kubelet的服务发现以及对标签的处理,是获取kubelet上/metrics接口数据来获取node的资源使用情况
- job_name: 'kubernetes-nodes-kubelet'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# 跳过CA验证
# insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token


kubernetes_sd_configs:
# 使用node角色,它使用默认的kubelet提供的http端口来发现集群中每个node节点。那具体地址是什么呢?
# 地址类型有四种NodeInternalIP, NodeExternalIP, NodeLegacyHostIP 和 NodeHostName,默认为这四个中第一个可用的地址。
# 那么这里为什么使用node角色呢?因为node角色就是用来发现kubelet的
# __meta_kubernetes_node_name:节点对象的名字
# __meta_kubernetes_node_label_<labelname>:表示节点对象上的每一个标签
# __meta_kubernetes_node_annotation_<annotationname>:表示节点对象上的每一个annotation
# __meta_kubernetes_node_address_<address_type>:如果存在,那么将是每一个节点地址类型的第一个地址
# Node模式,Prometheus会自动发现Kubernetes中所有Node节点的信息并作为监控的目标Target。
# 而这些Target的访问地址实际上就是Kubelet的访问地址,并且Kubelet实际上直接内置了对Promtheus的支持
- role: node


relabel_configs:
# 保留(.+)匹配到的内容,去掉__meta_kubernetes_node_label_,实际上就是把(.+)当做新标签,然后老标签的值给这个新标签,
# 这里没有设置source_labels,则表示匹配所有标签
- action: labelmap
# 匹配节点对象上的每一个标签
regex: __meta_kubernetes_node_label_(.+)


# 抓取cAdvisor数据,是获取kubelet上/metrics/cadvisor接口数据来获取容器的资源使用情况
- job_name: 'kubernetes-nodes-cadvisor'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token


kubernetes_sd_configs:
# 使用角色为node
- role: node


relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
# 把__metrics_path__的值替换为/metrics/cadvisor,因为默认是/metrics
- target_label: __metrics_path__
replacement: /metrics/cadvisor


# 抓取服务端点,整个这个任务都是用来发现node-exporter和kube-state-metrics-service的,这里用的是endpoints角色,这是通过这两者的service来发现
# 的后端endpoints。另外需要说明的是如果满足采集条件,那么在service、POD中定义的labels也会被采集进去
- job_name: 'kubernetes-service-endpoints'


kubernetes_sd_configs:
- role: endpoints


relabel_configs:
# 重新打标仅抓取到的具有 "prometheus.io/scrape: true" 的annotation的端点,意思是说如果某个service具有prometheus.io/scrape = true annotation声明则抓取
# annotation本身也是键值结构,所以这里的源标签设置为键,而regex设置值,当值匹配到regex设定的内容时则执行keep动作也就是保留,其余则丢弃.
# node-exporter这个POD的service里面就有一个叫做prometheus.io/scrape = true的annotations所以就找到了node-exporter这个POD
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true

# 应用中自定义暴露的指标,也许你暴露的API接口不是/metrics这个路径,那么你可以在这个POD对应的service中做一个
# "prometheus.io/path = /mymetrics" 声明,下面的意思就是把你声明的这个路径赋值给__metrics_path__
# 其实就是让prometheus来获取自定义应用暴露的metrices的具体路径,不过这里写的要和service中做好约定
# 如果service中这样写 prometheus.io/app-metrics-path: '/metrics' 那么你这里就要
# __meta_kubernetes_service_annotation_prometheus_io_app_metrics_path这样写
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)

# 暴露自定义的应用的端口,就是把地址和你在service中定义的 "prometheus.io/port = <port>" 声明做一个拼接
# 然后赋值给__address__,这样prometheus就能获取自定义应用的端口,然后通过这个端口再结合__metrics_path__来获取
# 指标,如果__metrics_path__值不是默认的/metrics那么就要使用上面的标签替换来获取真正暴露的具体路径
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__

# 重新设置scheme
# 匹配源标签__meta_kubernetes_service_annotation_prometheus_io_scheme也就是prometheus.io/scheme annotation
# 如果源标签的值匹配到regex则把值替换为__scheme__对应的值
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)


# 下面主要是为了给样本添加额外信息
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name


# 下面是自动发现service,不过如果要想监控service则需要安装blackbox-exporter
- job_name: 'kubernetes-services-http'


metrics_path: /probe
# 生成__param_module="http_2xx"的label,如果是TCP探测则使用 module: [tcp_connect]
params:
module: [http_2xx]


kubernetes_sd_configs:
- role: service


relabel_configs:
# 为了让service可以被探测到,那需要在service的annotation中增加 prometheus.io/scrape: true 声明
# 也就是只保留prometheus.io/scrape: true的service
- action: keep
regex: true
source_labels:
- __meta_kubernetes_service_annotation_prometheus_io_scrape
# 用__address__这个label的值创建一个名为__param_target的label为blackbox-exporter,值为内部service的访问地址,作为blackbox-exporter采集用
- source_labels: [__address__]
target_label: __param_target


# 用blackbox-exporter的service地址值”prometheus-blackbox-exporter:9115"替换原__address__的值
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance

# 下面主要是为了给样本添加额外信息
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
target_label: kubernetes_name


# 下面是对ingresses监控,不过如果要想监控ingresses则需要安装blackbox-exporter
- job_name: 'kubernetes-ingresses'


metrics_path: /probe
# 生成__param_module="http_2xx"的label
params:
module: [http_2xx]


kubernetes_sd_configs:
- role: ingress


relabel_configs:
# Example relabel to probe only some ingresses that have "example.io/should_be_probed = true" annotation
# - source_labels: [__meta_kubernetes_ingress_annotation_example_io_should_be_probed]
# action: keep
# regex: true
- source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
regex: (.+);(.+);(.+)
replacement: ${1}://${2}${3}
target_label: __param_target
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance
# 下面主要是为了给样本添加额外信息
- action: labelmap
regex: __meta_kubernetes_ingress_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_ingress_name]
target_label: kubernetes_name


# 抓取POD进行监控
- job_name: 'kubernetes-pods'


kubernetes_sd_configs:
- role: pod
relabel_configs:
# POD的 annotation 中含有"prometheus.io/scrape: true" 的则保留,意思就是会被Prometheus抓取,不具有这个的POD则不会被抓取
- action: keep
regex: true
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_scrape
# 获取POD的 annotation 中定义的"prometheus.io/path: XXX"定义的值,这个值就是你的程序暴露符合prometheus规范的metrics的地址
# 如果你的metrics的地址不是 /metrics 的话,通过这个标签说,那么这里就会把这个值赋值给 __metrics_path__这个变量,因为prometheus
# 是通过这个变量获取路径然后进行拼接出来一个完整的URL,并通过这个URL来获取metrics值的,因为prometheus默认使用的就是 http(s)://X.X.X.X/metrics
# 这样一个路径来获取的。
- action: replace
regex: (.+)
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_path
target_label: __metrics_path__
# 这里是端口信息,因为你的程序很有可能在容器中并不是以80端口运行的,那么就需要做一个拼接http(s)://x.x.x.x:xx/metrics
# __address__在prometheus中代表的就是实例的IP地址,而POD中的annotation 中定义的"prometheus.io/port: XX"就是你程序
# 被访问到的端口,最终在prometheus中将会被显示为 instance=X.X.X.X:XX这样
- action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
source_labels:
- __address__
- __meta_kubernetes_pod_annotation_prometheus_io_port
target_label: __address__


- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name

prometheus是如何识别apiserver的呢?

这些乱七八糟的标签可能让你眼花缭乱,我们举一个简单的例子看一下,prometheus是如何识别apiserver的,看下图

其他说明和参考文档

另外在grafana主机安装插件 grafana-cli plugins install grafana-piechart-panel 然后重启grafana服务。否则8919中的饼图使用不了。

https://github.com/1046102779/prometheus/blob/master/operating/configuration.md

https://blog.csdn.net/liukuan73/article/details/78881008

https://github.com/yunlzheng/prometheus-book

监控清单文件下载

Kubernetes集群部署史上最详细(二)Prometheus监控Kubernetes集群的更多相关文章

  1. Kubernetes集群部署史上最详细(一)Kubernetes集群安装

    适用部署结构以及版本 本系列中涉及的部署方式和脚本适用于1.13.x和1.14,而且采取的是二进制程序部署方式. 脚本支持的部署模式 最小部署模式 3台主机,1台为k8s的master角色,其余2台为 ...

  2. 史上最详细“截图”搭建Hexo博客并部署到Github

    http://jingyan.baidu.com/article/d8072ac47aca0fec95cefd2d.html 大家也搭建过博客,很多时候,按着教程来做就可以了,但是我当时为了搭建Hex ...

  3. 转 史上最详细的Hadoop环境搭建

    GitChat 作者:鸣宇淳 原文:史上最详细的Hadoop环境搭建 关注公众号:GitChat 技术杂谈,一本正经的讲技术 [不要错过文末活动哦] 前言 Hadoop在大数据技术体系中的地位至关重要 ...

  4. 史上最详细“截图”搭建Hexo博客——For Windows

    http://angelen.me/2015/01/23/2015-01-23-%E5%8F%B2%E4%B8%8A%E6%9C%80%E8%AF%A6%E7%BB%86%E2%80%9C%E6%88 ...

  5. 史上最详细Windows版本搭建安装React Native环境配置 转载,比官网的靠谱亲测可用

    史上最详细Windows版本搭建安装React Native环境配置   2016/01/29 |  React Native技术文章 |  Sky丶清|  95条评论 |  33530 views ...

  6. 测试思想-测试设计 史上最详细测试用例设计实践总结 Part2

    史上最详细测试用例设计实践总结 by:授客 QQ:1033553122 -------------------------接 Part1-------------------------- 方法:这里 ...

  7. 史上最详细的C语言和Python的插入排序算法

    史上最详细的C语言和Python的插入排序算法插入排序原理:所谓插入排序,就像我们在打牌(斗地主)时,整理我们自己手中自己的牌一样,就像是2,1,3,9,J,K,5,4,这四张牌.我们要把它其中的几张 ...

  8. 史上最详细的XGBoost实战

    史上最详细的XGBoost实战 0. 环境介绍 Python 版 本: 3.6.2 操作系统 : Windows 集成开发环境: PyCharm 1. 安装Python环境 安装Python 首先,我 ...

  9. 史上最详细的Android Studio系列教程一--下载和安装

    链接地址:http://segmentfault.com/a/1190000002401964#articleHeader4 原文链接:http://stormzhang.com/devtools/2 ...

随机推荐

  1. rsync 密钥文件错误问题总结

    rsync 可以使用 --password-file 选项指定密钥文件,密钥文件中简单存放 rsync 密码:在第一次使用密钥文件的时候经常遇到文件权限相关问题:这里总结一下,我遇到的问题. 问题描述 ...

  2. linux基础和vim基本使用

    Liunx基础 1. 目录  /:根目录,一般根目录只存放目录,在linux下有且只有一个根目录.所有的东西都是从这里开始,例如:/home就是先从根目录/开始,再进入到home目录.  /bin ...

  3. arcEngine开发之根据点坐标创建Shp图层

    思路 根据点坐标创建Shapefile文件大致思路是这样的: (1)创建表的工作空间,通过 IField.IFieldsEdit.IField 等接口创建属性字段,添加到要素集中. (2)根据获取点的 ...

  4. wordpress上下篇

    分页一: <!--上下篇开始--> <div class="shangxia"> <?php $current_category=get_the_ca ...

  5. 初识函数库libpcap

    由于工作上的需要,最近简单学习了抓包函数库libpcap,顺便记下笔记,方便以后查看 一.libpcap简介    libpcap(Packet Capture Library),即数据包捕获函数库, ...

  6. 微信公众号 模板消息 定时推送 java

    前提:业务需要,要做一个关于月报的微信消息推送.即每个月定时自动发送一条消息 给关注 公众号的人 用的是 公众号的测试账号(实际开发需要认证的公众号) 微信官网的 模板消息接口规则: 1.所有服务号都 ...

  7. S/4 HANA中的数据库锁策略

    S4中的新的MM数据模型以及HANA的Insert-only特性允许物料凭证的并行处理,提高了相关的吞吐量.由此,数据库锁的应用情况也发生了变化.下文将介绍这些变化(基于S4 1610). 本文链接: ...

  8. 你不知道的JavaScript--Item16 for 循环和for...in 循环的那点事儿

    大家都知道在JavaScript中提供了两种方式迭代对象: for 循环: for..in循环: 1.for循环 不足: 在于每次循环的时候数组的长度都要去获取: 终止条件要明确: 在for循环中,你 ...

  9. Android 手势检测实战 打造支持缩放平移的图片预览效果(下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图 ...

  10. codeforces 985C Liebig's Barrels

    题意: 有n * k块木板,每个木桶由k木板组成,每个木桶的容量定义为它最短的那块木板的长度. 任意两个木桶的容量v1,v2,满足|v1-v2| <= d. 问n个木桶容量的最大的和为多少,或者 ...