经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Kubernetes » 查看文章
Prometheus服务发现之kubernetes_sd_config
来源:cnblogs  作者:渡边灬  时间:2023/3/29 10:08:43  对本文有异议

一、为什么要使用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节点的服务器相关的指标数据。

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

image
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手动添加端口。

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

image
- 如果ep是属于service的话,则会附加service角色的所有标签
- 对于ep的后端节点是pod,则会附加pod角色的所有标签(即上边介绍的pod角色可用标签)
比如我么手动创建一个ep,这个ep关联到一个pod,则prometheus的标签中会包含这个pod角色的所有标签

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

image

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 来实现的:

  1. #全局配置
  2. global:
  3. #规则配置主要是配置报警规则
  4. rule_files:
  5. #抓取配置,主要配置抓取客户端相关
  6. scrape_configs:
  7. #报警配置
  8. alerting:
  9. #用于远程存储写配置
  10. remote_write:
  11. #用于远程读配置
  12. remote_read:

举例说明:

  1. # Kubernetes的API SERVER会暴露API服务,Promethues集成了对Kubernetes的自动发现,它有5种模式:Node、Service
  2. # 、Pod、Endpoints、ingress,下面是Prometheus官方给出的对Kubernetes服务发现的实例。这里你会看到大量的relabel_configs,
  3. # 其实你就是把所有的relabel_configs去掉一样可以对kubernetes做服务发现。relabel_configs仅仅是对采集过来的指标做二次处理,比如
  4. # 要什么不要什么以及替换什么等等。而以__meta_开头的这些元数据标签都是实例中包含的,而relabel则是动态的修改、覆盖、添加删除这些标签
  5. # 或者这些标签对应的值。而且以__开头的标签通常是系统内部使用的,因此这些标签不会被写入样本数据中,如果我们要收集这些东西那么则要进行
  6. # relabel操作。当然reabel操作也不仅限于操作__开头的标签。
  7. #
  8. # action的行为:
  9. # replace:默认行为,不配置action的话就采用这种行为,它会根据regex来去匹配source_labels标签上的值,并将并将匹配到的值写入target_label中
  10. # labelmap:它会根据regex去匹配标签名称,并将匹配到的内容作为新标签的名称,其值作为新标签的值
  11. # keep:仅收集匹配到regex的源标签,而会丢弃没有匹配到的所有标签,用于选择
  12. # drop:丢弃匹配到regex的源标签,而会收集没有匹配到的所有标签,用于排除
  13. # labeldrop:使用regex匹配标签,符合regex规则的标签将从target实例中移除,其实也就是不收集不保存
  14. # labelkeep:使用regex匹配标签,仅收集符合regex规则的标签,不符合的不收集
  15. global:
  16. # 间隔时间
  17. scrape_interval: 30s
  18. # 超时时间
  19. scrape_timeout: 10s
  20. # 另一个独立的规则周期,对告警规则做定期计算
  21. evaluation_interval: 30s
  22. # 外部系统标签
  23. external_labels:
  24. prometheus: monitoring/k8s
  25. prometheus_replica: prometheus-k8s-1
  26. # 抓取服务端点,整个这个任务都是用来发现node-exporter和kube-state-metrics-service的,这里用的是endpoints角色,这是通过这两者的service来发现
  27. # 的后端endpoints。另外需要说明的是如果满足采集条件,那么在service、POD中定义的labels也会被采集进去
  28. scrape_configs:
  29. # 定义job名称,是一个拉取单元
  30. - job_name: "kubernetes-endpoints"
  31. # 发现endpoints,它是从列出的服务端点发现目标,这个endpoints来自于Kubernetes中的service,每一个service都有对应的endpoints,这里是一个列表
  32. # 可以是一个IP:PORT也可以是多个,这些IP:PORT就是service通过标签选择器选择的POD的IP和端口。所以endpoints角色就是用来发现server对应的pod的IP的
  33. # kubernetes会有一个默认的service,通过找到这个service的endpoints就找到了api server的IP:PORT,那endpoints有很多,我怎么知道哪个是api server呢
  34. # 这个就靠source_labels指定的标签名称了。
  35. kubernetes_sd_configs:
  36. # 角色为 endpoints
  37. - role: endpoints
  38. relabel_configs:
  39. # 重新打标仅抓取到的具有 "prometheus.io/scrape: true" 的annotation的端点,意思是说如果某个service具有prometheus.io/scrape = true annotation声明则抓取
  40. # annotation本身也是键值结构,所以这里的源标签设置为键,而regex设置值,当值匹配到regex设定的内容时则执行keep动作也就是保留,其余则丢弃.
  41. # node-exporter这个POD的service里面就有一个叫做prometheus.io/scrape = true的annotations所以就找到了node-exporter这个POD
  42. - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
  43. # 动作 删除 regex 与串联不匹配的目标 source_labels
  44. action: keep
  45. # 通过正式表达式匹配 true
  46. regex: true
  47. # 重新设置scheme
  48. # 匹配源标签__meta_kubernetes_service_annotation_prometheus_io_scheme也就是prometheus.io/scheme annotation
  49. # 如果源标签的值匹配到regex则把值替换为__scheme__对应的值
  50. - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
  51. action: replace
  52. target_label: __scheme__
  53. regex: (https?)
  54. # 匹配来自 pod annotationname prometheus.io/path 字段
  55. - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
  56. # 获取POD的 annotation 中定义的"prometheus.io/path: XXX"定义的值,这个值就是你的程序暴露符合prometheus规范的metrics的地址
  57. # 如果你的metrics的地址不是 /metrics 的话,通过这个标签说,那么这里就会把这个值赋值给 __metrics_path__这个变量,因为prometheus
  58. # 是通过这个变量获取路径然后进行拼接出来一个完整的URL,并通过这个URL来获取metrics值的,因为prometheus默认使用的就是 http(s)://X.X.X.X/metrics
  59. # 这样一个路径来获取的。
  60. action: replace
  61. # 匹配目标指标路径
  62. target_label: __metrics_path__
  63. # 匹配全路径
  64. regex: (.+)
  65. # 匹配出 Pod ip地址和 Port
  66. - source_labels:
  67. [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
  68. action: replace
  69. target_label: __address__
  70. regex: ([^:]+)(?::d+)?;(d+)
  71. replacement: $1:$2
  72. # 下面主要是为了给样本添加额外信息
  73. - action: labelmap
  74. regex: __meta_kubernetes_service_label_(.+)
  75. # 元标签 服务对象的名称空间
  76. - source_labels: [__meta_kubernetes_namespace]
  77. action: replace
  78. target_label: kubernetes_namespace
  79. # service 对象的名称
  80. - source_labels: [__meta_kubernetes_service_name]
  81. action: replace
  82. target_label: kubernetes_name
  83. # pod对象的名称
  84. - source_labels: [__meta_kubernetes_pod_name]
  85. action: replace
  86. target_label: kubernetes_pod_name

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

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

  1. - job_name: 'dev-kubernetes-endpoints'
  2. scrape_interval: 10s
  3. scrape_timeout: 10s
  4. metrics_path: (.*)/actuator/prometheus
  5. scheme: http
  6. relabel_configs:
  7. - action: keep
  8. regex: true
  9. source_labels:
  10. - __meta_kubernetes_pod_annotation_prometheus_io_scrape
  11. - action: replace
  12. regex: (.+)
  13. source_labels:
  14. - __meta_kubernetes_pod_annotation_prometheus_io_path
  15. target_label: __metrics_path__
  16. - action: replace
  17. regex: ([^:]+)(?::\d+)?;(\d+)
  18. replacement: $1:$2
  19. source_labels:
  20. - __address__
  21. - __meta_kubernetes_pod_annotation_prometheus_io_port
  22. target_label: __address__
  23. - action: labelmap
  24. regex: __meta_kubernetes_pod_label_(.+)
  25. - action: replace
  26. source_labels:
  27. - __meta_kubernetes_namespace
  28. target_label: kubernetes_namespace
  29. - action: replace
  30. source_labels:
  31. - __meta_kubernetes_pod_name
  32. target_label: kubernetes_pod_name
  33. kubernetes_sd_configs:
  34. - role: pod
  35. kubeconfig_file: ""
  36. follow_redirects: true
  37. namespaces:
  38. names: []

2、创建Secret 对象

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

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

3、创建资源对象

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

  1. apiVersion: monitoring.coreos.com/v1
  2. kind: Prometheus
  3. metadata:
  4. labels:
  5. app.kubernetes.io/component: prometheus
  6. app.kubernetes.io/name: prometheus
  7. app.kubernetes.io/part-of: kube-prometheus
  8. app.kubernetes.io/version: 2.29.1
  9. prometheus: k8s
  10. name: k8s
  11. namespace: monitoring
  12. spec:
  13. retention: 7d
  14. alerting:
  15. alertmanagers:
  16. - apiVersion: v2
  17. name: alertmanager-main
  18. namespace: monitoring
  19. port: web
  20. enableFeatures: []
  21. externalLabels: {}
  22. image: quay.io/prometheus/prometheus:v2.29.1
  23. nodeSelector:
  24. kubernetes.io/os: linux
  25. podMetadata:
  26. labels:
  27. app.kubernetes.io/component: prometheus
  28. app.kubernetes.io/name: prometheus
  29. app.kubernetes.io/part-of: kube-prometheus
  30. app.kubernetes.io/version: 2.29.1
  31. podMonitorNamespaceSelector: {}
  32. podMonitorSelector: {}
  33. probeNamespaceSelector: {}
  34. probeSelector: {}
  35. replicas: 2
  36. resources:
  37. requests:
  38. memory: 400Mi
  39. ruleNamespaceSelector: {}
  40. ruleSelector: {}
  41. securityContext:
  42. fsGroup: 2000
  43. runAsNonRoot: true
  44. runAsUser: 1000
  45. serviceAccountName: prometheus-k8s
  46. serviceMonitorNamespaceSelector: {}
  47. serviceMonitorSelector: {}
  48. version: 2.29.1
  49. additionalScrapeConfigs: #以下为新增的配置项
  50. name: prometheus-additional-configs
  51. key: prometheus-additional-config.yaml

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

  1. kubectl apply -f prometheus-prometheus.yaml

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

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

  1. annotations:
  2. prometheus.io/path: /actuator/prometheus
  3. prometheus.io/port: "7070"
  4. prometheus.io/scheme: http
  5. 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:

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. name: prometheus-k8s
  5. rules:
  6. - apiGroups:
  7. - ""
  8. resources:
  9. - nodes/metrics
  10. verbs:
  11. - get
  12. - nonResourceURLs:
  13. - /metrics
  14. verbs:
  15. - get

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

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. labels:
  5. app.kubernetes.io/component: prometheus
  6. app.kubernetes.io/name: prometheus
  7. app.kubernetes.io/part-of: kube-prometheus
  8. app.kubernetes.io/version: 2.29.1
  9. name: prometheus-k8s
  10. rules:
  11. - apiGroups:
  12. - ""
  13. resources:
  14. - nodes
  15. - services
  16. - endpoints
  17. - pods
  18. - nodes/proxy
  19. verbs:
  20. - get
  21. - list
  22. - watch
  23. - apiGroups:
  24. - ""
  25. resources:
  26. - nodes/metrics
  27. verbs:
  28. - get
  29. - nonResourceURLs:
  30. - /metrics
  31. - /actuator/prometheus
  32. verbs:
  33. - get

更新上面的 ClusterRole 这个资源对象,然后重建下 Prometheus 的所有 Pod,正常就可以看到 targets 页面下面有 dev-kubernetes-endpoints 这个监控任务了。
这里抓取目标是因为 Service 中都有 prometheus.io/scrape=true 这个 annotation。至此,一个自动发现endpoint的配置就完成了,其他资源(service、pod、ingress、node同样也可以通过自动发现的方式实现。

原文链接:https://www.cnblogs.com/zhangpeiyao/p/17242200.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号