一、为什么要使用Prometheus服务发现

之前我们讲过通过配置prometheus-operator的CRD ServiceMonitor来达到K8S集群相关组件和微服务的监控的目的,可以在ServiceMonitor的配置文件中以手动方式通过match lable和想要监控的Service进行匹配(这里相当于是手动进行服务注册和服务发现的作用,也可以将这种模式称为静态服务发现),以此来完成对想要监控的服务和组件进行监控,但这种方式进行监控配置,只能手工一个一个的增加,如果在k8s集群规模较大的情况下,或者是集群后面又增加了节点或者组件信息,这种方式就会很麻烦也不现实,于是引出了今天的主题-Prometheus动态服务发现机制,下面来让我们了解一下Prometheus是如何动态实现服务发现的。

二、什么是Prometheus服务发现

从上面的介绍大家已经知道,prometheus获取数据源target的方式主要有两种模式,一种是静态配置,一种是动态服务发现配置,promethues的静态服务发现static_configs或者是ServiceMonitor 通过标签匹配Service:每当有一个新的目标实例需要监控,都需要手动修改配置文件配置目标target或者修改ServiceMonitor CRD配置文件.

那么面对现如今动不动就成百上千台节点的集群来说,静态服务发现这种纯手动配置很显然是不切实际的,然而现在的集群往往都有一个很重要的功能叫做服务发现,例如在现在常用的微服务SpringCloud架构的中,Eureka组件作为服务注册和发现的中心,在Kubernetes这类容器管理平台中,Kubernetes也具有服务发现的功能,它们都掌握并管理着所有的容器或者是服务的相关信息,于是Prometheus通过这个中间的代理人(服务发现和注册中心)来获取集群当中监控目标的信息,从而巧妙地实现了prometheus的动态服务发现。

三、Prometheus常用的集几种动态服务发现

prometheus目前支持的动态服务发现有很多种,常用的主要分为以下几种:

1. promethues基于k8s的服务发现kubernetes_sd_configs

2. promethues基于consul的服务发现consul_sd_config

3. promethues基于Eureka的服务发现eureka_sd_config

还有基于DNS等等的就不一一列举。

下面主要讲解promethues基于的k8s服务发现kubernetes_sd_configs

四、详解Prometheus服务发现之kubernetes_sd_configs

目前,在Kubernetes下,Prometheus 通过与 Kubernetes API 集成主要支持5种服务发现模式又叫角色role:Node、Service、Pod、Endpoints、Ingress。不同的服务发现模式适用于不同的场景,例如:node适用于与主机相关的监控资源,如节点中运行的Kubernetes 组件状态、节点上运行的容器状态等;service 和 ingress 适用于通过黑盒监控的场景,如对服务的可用性以及服务质量的监控;endpoints 和 pod 均可用于获取 Pod 实例的监控数据,如监控用户或者管理员部署的支持 Prometheus 的应用。

下面贴出在Prometheus官网对这五种role的详细说明:

1. node

node角色可以发现集群中每个node节点的地址端口,默认为Kubelet的HTTP端口。目标地址默认为Kubernetes节点对象的第一个现有地址,地址类型顺序为NodeInternalIP、NodeExternalIP、NodeLegacyHostIP和NodeHostName。

作用:监控K8S的node节点的服务器相关的指标数据。



2. service

service角色可以发现每个service的ip和port,将其作为target。这对于黑盒监控(blackbox)很有用。



3. pod

pod角色可以发现所有pod并将其中的pod ip作为target。如果有多个端口或者多个容器,将生成多个target(例如:80,443这两个端口,pod ip为10.0.244.22,则将10.0.244.22:80,10.0.244.22:443分别作为抓取的target)。

如果容器没有指定的端口,则会为每个容器创建一个无端口target,以便通过relabel手动添加端口。



4. endpoints

endpoints角色可以从ep(endpoints)列表中发现所有targets。



- 如果ep是属于service的话,则会附加service角色的所有标签

- 对于ep的后端节点是pod,则会附加pod角色的所有标签(即上边介绍的pod角色可用标签)

比如我么手动创建一个ep,这个ep关联到一个pod,则prometheus的标签中会包含这个pod角色的所有标签

5. ingress

ingress角色发现ingress的每个路径的target。这通常对黑盒监控很有用。该地址将设置为ingress中指定的host。

Prometheus-additional.yaml配置文件规则详解

为解决服务发现的问题,kube-prometheus 为我们提供了一个额外的抓取配置来解决这个问题,我们可以通过添加额外的配置来进行服务发现进行自动监控。我们可以在 kube-prometheus 当中去自动发现并监控具有 prometheus.io/scrape=true 这个 annotations 的 Service。

其中通过 kubernetes_sd_configs 支持监控其各种资源。kubernetes SD 配置允许从 kubernetes REST API 接受搜集指标,且总是和集群保持同步状态,任何一种 role 类型都能够配置来发现我们想要的对象。

规则配置使用 yaml 格式,下面是文件中一级配置项。自动发现 k8s Metrics 接口是通过 scrape_configs 来实现的:

#全局配置
global: #规则配置主要是配置报警规则
rule_files: #抓取配置,主要配置抓取客户端相关
scrape_configs: #报警配置
alerting: #用于远程存储写配置
remote_write: #用于远程读配置
remote_read:

举例说明:

# 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: 30s
# 超时时间
scrape_timeout: 10s
# 另一个独立的规则周期,对告警规则做定期计算
evaluation_interval: 30s
# 外部系统标签
external_labels:
prometheus: monitoring/k8s
prometheus_replica: prometheus-k8s-1 # 抓取服务端点,整个这个任务都是用来发现node-exporter和kube-state-metrics-service的,这里用的是endpoints角色,这是通过这两者的service来发现
# 的后端endpoints。另外需要说明的是如果满足采集条件,那么在service、POD中定义的labels也会被采集进去
scrape_configs:
# 定义job名称,是一个拉取单元
- job_name: "kubernetes-endpoints"
# 发现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指定的标签名称了。
kubernetes_sd_configs:
# 角色为 endpoints
- role: endpoints # 下面的含义是源标签__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:
# 重新打标仅抓取到的具有 "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]
# 动作 删除 regex 与串联不匹配的目标 source_labels
action: keep
# 通过正式表达式匹配 true
regex: true
# 重新设置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?)
# 匹配来自 pod annotationname prometheus.io/path 字段
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
# 获取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
# 匹配目标指标路径
target_label: __metrics_path__
# 匹配全路径
regex: (.+)
# 匹配出 Pod ip地址和 Port
- source_labels:
[__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::d+)?;(d+)
replacement: $1:$2
# 下面主要是为了给样本添加额外信息
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
# 元标签 服务对象的名称空间
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
# service 对象的名称
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name
# pod对象的名称
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name

1、创建prometheus-additional.yaml配置文件

新增 prometheus 在 Kubernetes 下的自动服务发现 prometheus-additional.yaml

- job_name: 'dev-kubernetes-endpoints'
scrape_interval: 10s
scrape_timeout: 10s
metrics_path: (.*)/actuator/prometheus
scheme: http
relabel_configs:
- action: keep
regex: true
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_scrape
- action: replace
regex: (.+)
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_path
target_label: __metrics_path__
- 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_(.+)
- action: replace
source_labels:
- __meta_kubernetes_namespace
target_label: kubernetes_namespace
- action: replace
source_labels:
- __meta_kubernetes_pod_name
target_label: kubernetes_pod_name
kubernetes_sd_configs:
- role: pod
kubeconfig_file: ""
follow_redirects: true
namespaces:
names: []

2、创建Secret 对象

将上面文件直接保存为 prometheus-additional.yaml,然后通过这个文件创建一个对应的 Secret 对象:

$ kubectl create secret generic additional-configs --from-file=prometheus-additional.yaml -n monitoring
secret "additional-configs" created

3、创建资源对象

然后我们需要在声明 prometheus 的资源对象文件中通过 additionalScrapeConfigs 属性添加上这个额外的配置:

「prometheus-prometheus.yaml」:

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
app.kubernetes.io/component: prometheus
app.kubernetes.io/name: prometheus
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 2.29.1
prometheus: k8s
name: k8s
namespace: monitoring
spec:
retention: 7d
alerting:
alertmanagers:
- apiVersion: v2
name: alertmanager-main
namespace: monitoring
port: web
enableFeatures: []
externalLabels: {}
image: quay.io/prometheus/prometheus:v2.29.1
nodeSelector:
kubernetes.io/os: linux
podMetadata:
labels:
app.kubernetes.io/component: prometheus
app.kubernetes.io/name: prometheus
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 2.29.1
podMonitorNamespaceSelector: {}
podMonitorSelector: {}
probeNamespaceSelector: {}
probeSelector: {}
replicas: 2
resources:
requests:
memory: 400Mi
ruleNamespaceSelector: {}
ruleSelector: {}
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
version: 2.29.1
additionalScrapeConfigs: #以下为新增的配置项
name: prometheus-additional-configs
key: prometheus-additional-config.yaml

添加完成后,直接更新 prometheus 这个 CRD 资源对象即可:

kubectl apply -f prometheus-prometheus.yaml

过一段时间,刷新 promethues 上的 config,将会查看配置已经生效。

自动发现规则配置好后如何让prometheus抓取pod内的metrics指标呢,抓取的路径端口等信息如何指定呢,这就要在應用deployments中的spec.template.metadata.annotations中指定了。配置如下:

annotations:
prometheus.io/path: /actuator/prometheus
prometheus.io/port: "7070"
prometheus.io/scheme: http
prometheus.io/scrape: "true"

定义好后prometheus即可抓取pod内的metrics指标数据了,在prometheus的targets页面即可看到job名称为 dev-kubernetes-endpoints 的target。

4、创建 RBAC 权限

我们切换到 targets 页面下面却并没有发现对应的监控任务,查看 Prometheus 的 Pod 日志,发现很多错误日志出现,都是 xxx is forbidden,这说明是 RBAC 权限的问题。

通过 prometheus 资源对象的配置可以知道 Prometheus 绑定了一个名为 prometheus-k8s 的 ServiceAccount 对象,而这个对象绑定的是一个名为 prometheus-k8s 的 ClusterRole:

创建 prometheus-clusterRole.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus-k8s
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get

上面的权限规则中我们可以看到明显没有对 Service 或者 Pod 的 list 权限,所以报错了,要解决这个问题,我们只需要添加上需要的权限即可:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/component: prometheus
app.kubernetes.io/name: prometheus
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 2.29.1
name: prometheus-k8s
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
- /actuator/prometheus
verbs:
- get

更新上面的 ClusterRole 这个资源对象,然后重建下 Prometheus 的所有 Pod,正常就可以看到 targets 页面下面有 dev-kubernetes-endpoints 这个监控任务了。

这里抓取目标是因为 Service 中都有 prometheus.io/scrape=true 这个 annotation。至此,一个自动发现endpoint的配置就完成了,其他资源(service、pod、ingress、node同样也可以通过自动发现的方式实现。

Prometheus服务发现之kubernetes_sd_config的更多相关文章

  1. prometheus服务发现机制

    一. Prometheus与服务发现 1.1 目前支持的服务发现方式 二. 案例 2.1 基于文件的服务发现 2.2 基于Consul的服务发现 三.本地测试 3.1 基于文件的服务发现 1.测试环境 ...

  2. prometheus — 基于文件的服务发现

    基于文件的服务发现方式不需要依赖其他平台与第三方服务,用户只需将要新的target信息以yaml或json文件格式添加到target文件中 ,prometheus会定期从指定文件中读取target信息 ...

  3. Prometheus 基于文件的服务发现

    Prometheus 基于文件的服务发现 官方文档:https://github.com/prometheus/prometheus/tree/master/discovery 服务发现支持: end ...

  4. Prometheus Consul实现自动服务发现

    Prometheus Consul实现自动服务发现   1.概述 Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件. Consul 由 HashiCorp公司用Go语言开发 ...

  5. Prometheus在Kubernetes下的服务发现机制

    Prometheus作为容器监控领域的事实标准,随着以Kubernetes为核心的云原生热潮的兴起,已经得到了广泛的应用部署.灵活的服务发现机制是Prometheus和Kubernetes两者得以连接 ...

  6. Prometheus监控神器-服务发现篇(二)

    本章节讲解服务发现与Relabelling的机制与范例. 通过服务发现的方式,我们可以在不重启Prometheus服务的情况下动态的发现需要监控的Target实例信息. 如上图所示,对于线上环境我们可 ...

  7. Prometheus 通过 consul 实现自动服务发现

    1.Consul 介绍 Consul 是基于 GO 语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册.服务发现和配置管理的功能.Consul 提供服务注册/发现.健康检查.Key/Valu ...

  8. Prometheus基于Eureka的服务发现

    Prometheus基于Eureka的服务发现 一.背景 二.实现步骤 1.eureka 客户端注册到prometheus中 2.prometheus中的写法 3.实现效果 三.完整代码 四.参考链接 ...

  9. Prometheus基于文件的服务发现

    Prometheus基于文件的服务发现 一.基于文件的服务发现 1.prometheus.yml 配置文件的写法 2.file_sd 目录下的文件 3.配置结果 二.注意事项 三.参考链接 一.基于文 ...

  10. prometheus k8s服务发现

    Prometheus的服务发现在解决什么问题? 被监控的目标(target)是整个监控体系中重要组成部分,传统监控系统zabbix通过 网络发现的机制自动创建主机到zabbix-server,进而快速 ...

随机推荐

  1. C#访问MySQL(二):数据插入与修改(增改)

    前言: 前面说了数据库的连接查询,现在说数据库的增删改.这里引入一个数据库的实体类,就是将当前数据库的某一个表里面所有字段写成实体类,如下: 1.数据库的实体类: 需要项目里下载Chloe.dll和C ...

  2. SQL查询 错误 [1843] [22008]: ORA-01843: 无效的月份

    dbeaver客户端运行sql查询Oracle库报错. 正确示例: select count(*) from PRODUCTS WHERE CREATE_TIME > '15-7月-2021 ' ...

  3. 解决CentOS 7.x虚拟机无法上网的问题

    参考地址:https://blog.csdn.net/weixin_43317914/article/details/124770393 1.关闭虚拟机 2.打开cmd,查看本机dns 3.打开虚拟机 ...

  4. Jupyter lab 切换kernel

    在使用pytorch的时候需要用到pandas这个包,报错说"no module named pandas", 但是我在终端查找了conda 装了pandas,所以不是安装的问题, ...

  5. 微信小程序主包和分包的资源可以相互引用吗

    了解主包.分包 整个小程序所有分包大小不超过20M;单个分包/主包大小不能超过 2M 主包: a. 放置默认启动页面&&tabBar页面, 以及一些分包需要用到的公共资源(如wxss. ...

  6. Android studio的使用2

    运行按钮First activity: package com.example.activity;import androidx.appcompat.app.AppCompatActivity;imp ...

  7. [Leetcode 98]判断有效的二叉搜索树Validate Binary Search Tree

    题目 https://leetcode.com/problems/validate-binary-search-tree 判断所给二叉树是否是二叉搜索树 二叉搜索树:其值left<root< ...

  8. 通过右键菜单生成pyd

    批处理 @echo off reg add "HKCR\AllFilesystemObjects\shell\构建PYTHON\command" /ve /t REG_SZ /d ...

  9. spring事件发布与监听

    一.组成部分 spring的事件监听有三个部分组成,事件(ApplicationEvent).监听器(ApplicationListener)和事件发布操作. 二.具体实现 事件 事件对象就是一个简单 ...

  10. 读书笔记<<世界是部金融史>>

    1.权力只对来源负责.权力只会对其来源负责--孟德斯鸠<论法的精神> 2.能违反的是纪律,不能违反的是规律.人自然要遵从人性规律. 3.在金融市场中有一个法则,如果市场认为一件事是真的,那 ...