构建企业级监控平台系列(二十二):Prometheus 基于 K8S 服务发现详解
Prometheus中k8s服务发现的原理是通过 Kubernetes 的REST API 检索抓取目标,并始终与集群状态保持同步。所以我们需要配置Kubernetes_sd_configs来访问K8s API。比如我们要抓取k8s ingress,需要为Prometheus指定用于RBAC认证证书和serviceaccount的token。
点击下方名片,设为星标!
回复“1024”获取2TB学习资源!
前面介绍了 Prometheus Exporter 、Node Exporter、标签 label、PromQL、AlertManager、Alertmanager 配置实现钉钉告警、Pushgateway等相关的知识点,今天我将详细的为大家介绍Prometheus 基于K8S服务发现相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发朋友圈支持一波!!!
Prometheus 服务发现
Prometheus Server 的数据抓取工作基于 Pull 模型,因而,它必须要事先知道各 target 的位置,然后才能从相应的 Exporter 或 Instrumentation 中抓取数据。
对于小型的系统环境,使用 static_configs 指定各 target 即可解决问题,但是对于较大的集群不适用,尤其不适用于使用容器和基于云的实例的动态集群,因为这些实例会经常出现变化、创建、或销毁的情况。
Prometheus 为此专门设计了一组服务发现机制,以便于能够基于服务注册中心自动发现、检测、分类可被监控的各 target ,以及更新发生了变动的 target。Prometheus 可以集成到多种不同的开源服务发现工具上,以便动态发现需要监控的目标。
在k8s容器环境中由于集群内实例网络地址是动态的,我们不可能每次创建或修改实例都将实例IP写入Prometheus的target中,借助服务发现我们可以快速的将集群内的资源注册到Prometheus-server中。
Prometheus 可以很好的集成到 Kubernetes 平台上,通过其 API Server 动态发现各类被监控的 Pod、Service、Endpoint、Ingress 及 Node 对象,还支持基于文件实现的动态发现。
更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
Prometheus目前支持的服务发现类型
prometheus目前支持以下几种的服务发现类型:
-
基于文件的服务发现
-
基于consul的服务发现
-
基于k8s API的服务发现
-
基于eureka的服务发现
-
基于nacos的服务发现
-
基于DNS的服务发现
今天来学习一下 Prometheus 基于 K8S API 的服务发现(kubernetes_sd_configs: Kubernetes 服务发现)。
什么是 Kubernetes_sd_configs?
Prometheus中k8s服务发现的原理是通过 Kubernetes 的REST API 检索抓取目标,并始终与集群状态保持同步。所以我们需要配置Kubernetes_sd_configs来访问K8s API。比如我们要抓取k8s ingress,需要为Prometheus指定用于RBAC认证证书和serviceaccount的token。
- job_name: 'kubernetes-ingress'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: ingress
这里的role为k8s中资源实体如 endpoints、service,、pod,、node或 ingress,当指定ingress时,Prometheus将每个入口地址发现为一个目标。
基于 kubernetes_sd_configs 自动发现配置
准备Prometheus的自动发现的配置文件并加载
[root@VM-12-8-centos kube-prom]# cat prometheus-additional.yaml
- job_name: 'blackbox'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- http://10.1.226.250:6000
- http://10.1.38.97:3000/healthz/ready
- http://10.1.116.84:5000
- http://10.1.215.125:7000/healthz/ready
- http://10.1.111.235:8000/healthz/ready
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- 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: namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: service
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
action: replace
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: pod
运行生成secret文件
[root@VM-12-8-centos kube-prom]# kubectl create secret generic additional-scrape-configs --from-file=prometheus-additional.yaml --dry-run -oyaml > additional-scrape-configs.yaml
应用,配置进入Prometheus中
[root@VM-12-8-centos kube-prom]# kubectl apply -f additional-scrape-configs.yaml -n monitoring secret/additional-scrape-configs configured
运行curl -XPOST http://10.0.12.8:30090/-/reload热加载一下,就可以在dashboard中看到增加的配置了。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
修改prometheus-k8s 的 ClusterRole权限
Prometheus 绑定了一个名为 prometheus-k8s 的 ServiceAccount 对象,而这个对象绑定的是一个名为 prometheus-k8s 的 ClusterRole,这个角色没有对 Service 或者 Pod 的 list 权限,所以需要进行修改
[root@VM-12-8-centos manifests]# kubectl edit clusterrole prometheus-k8s -n monitoring -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2022-11-13T14:21:08Z"
name: prometheus-k8s
resourceVersion: "16164985"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/prometheus-k8s
uid: 7a404fac-9462-486a-a109-65a1ef98e423
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
pod 配置自动发现
pod 要自动发现,必须在 annotations:增加prometheus.io/scrape: "true"
,新建一个pod。
[root@VM-12-8-centos k8s]# cat PODforheadlesssvr.yml
apiVersion: v1
kind: Pod
metadata:
name: ex-podforheadlesssvr
annotations:
prometheus.io/scrape: "true"
spec:
containers:
- name: testcontainer
image: docker.io/appropriate/curl
imagePullPolicy: IfNotPresent
command: ['sh', '-c']
args: ['echo "test pod for headless service";sleep 96000']
[root@VM-12-8-centos k8s]# kubectl apply -f ex6_1_4PODforheadlesssvr.yml
pod/ex-podforheadlesssvr created
[root@VM-12-8-centos k8s]# kubectl get po
NAME READY STATUS RESTARTS AGE
ex-podforheadlesssvr 1/1 Running 0 3s
过一会检查dashboard,已经在界面上了状态为down,因为这个pod对应的镜像并没有相关的metrics接口,我们主要是用来进行自动发现测试的,在服务发现界面。在target labels部分如上操作,就可以基于k8s自动发现 在Prometheus中增加监控项了。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
Prometheus 基于k8s服务发现案例
下面学习一下 Prometheus 基于k8s服务发现通过Cadvisor监控Kubernetes。
Kubernetes主要提供了如下5种服务发现模式和Prometheus进行集成:
-
Node
-
Pod
-
Endpoints
-
Service
-
Ingress
使用cAdvisor主要需要使用Node服务发现模式,配置方式如下所示:
kubernetes_sd_configs:
- role: node
监控指标
-
Kubernetes本身监控
-
Node资源利用率
-
Node数量
-
Pods数量(Node)
-
资源对象状态
-
-
Pod监控
-
Pod数量(项目)
-
容器资源利用率
-
应用程序
-
监控Kubernetes
Prometheus通过Cadvisor监控k8s
Kubernetes默认提供cAdvisor和特定节点的时间序列。我们可以创建一个作业来从每个节点的Kubernetes API中抓取这些时间序列。我们可以使用这些时间序列来监控节点,以及每个节点上的Docker守护进程和容器。这里将作业命名为 kubernetes-cadvisor ,并使用服务发现来返回 node 角色的 Kubernetes 节点列表。我们使用https 来抓取指标,并指定证书颁发机构和一个本地令牌文件以对 Kubernetes 进行身份验证。
然后我们重新标记时间序列,以便从使用 labelmap 发现的元数据标签中创建标签,将 __address__
标签替换为Kubernetes API 服务器的默认 DNS 名称。然后,我们使用其中一个元数据标签,一个带有节点名称的标签,在API 上创建一个新标签 __metrics_path__
,它将节点名称传递给路径。
监控K8s集群Pod步骤
-
K8s RBAC授权
现在普罗米修斯要通过服务发现连接到k8s集群,k8s授权普罗米修斯可以访问如下地址
[root@k8s-master ~]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.179.102:6443 74d
Prometheus -> apiserver(192.168.179.102:6443)->kubelet(cadvisor) 这个过程是需要授权的,所以第一步就是授权。
[root@k8s-master ~]# cat rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: kube-system
[root@k8s-master ~]# kubectl apply -f rbac.yaml
serviceaccount/prometheus created
现在要拿到创建rbac产生的token,,这是非常关键的,让普罗米修斯拿着这个token去访问api那么就具有rbac里面授予的权限了。
怎么拿到这个token呢,产生的sa在kube-system上,怎么拿到这个token呢,产生的sa在kube-system上。
[root@k8s-master ~]# kubectl get sa -n kube-system | grep prome
prometheus 1 4m59s
[root@k8s-master ~]# kubectl describe sa prometheus -n kube-system
Name: prometheus
Namespace: kube-system
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: prometheus-token-jq2kg
Tokens: prometheus-token-jq2kg
Events: <none>
Token保存在这个secret当中 prometheus-token-jq2kg。
[root@k8s-master ~]# kubectl describe secret prometheus-token-jq2kg -n kube-system
token: eyJhbGciOiJSUzI1NiIsImtpZCI6InR0cTRHNDNQUGFMeUZ5Rnp1azZnSUEyRVU0WEY1dWdEMEYwd056ZnNkWWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJwcm9tZXRoZXVzLXRva2VuLWpxMmtnIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InByb21ldGhldXMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxNDYxYTU1Mi0xZWE0LTRjYWQtOTdhOC05YmE1Zjg2YjhkMmYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cHJvbWV0aGV1cyJ9.FfRTfjE5ih9ZvCy0XFL1Trc00H7k1s6kkGmFvnkKJghswTLeATRPfziAJqrBYBYY0dA8IK52WEa0JR2TevtotnWOyIXZnv6KWcPb0RObvlL4dxp1ZJyZRAc01rliyukTU2HphgX2NlLnf_TZHMo1bapPf8crDdMlZHoEe42ukMtr1nZrPgChXJCtGoR383bAWDoDrq1nZ7e8xCQnoxEkq_khLO9ypHqAlFfMCG-w0x35uC1Wa06FdoeygW0gABDK_Ltgvz6_IuLM9wLl54SnPZJEPSMfiNpuvN8vDWNUcjqPj1Lqi3eSMKLf7b3zBvlTEcLQKoUQdXBdg-97pfeDVw
更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
-
获取Token并保存到文件
拿到这个token,拷贝到普罗米修斯这个节点。
[root@k8s-master ~]# kubectl describe secret prometheus-token-jq2kg -n kube-system > token.k8s
[root@k8s-master ~]# scp token.k8s root@192.168.179.99:/usr/local/prometheus
在普罗米修斯上只保存这token值,其余的全部去掉
[root@localhost prometheus]# cat token.k8s
eyJhbGciOiJSUzI1NiIsImtpZCI6InR0cTRHNDNQUGFMeUZ5Rnp1azZnSUEyRVU0WEY1dWdEMEYwd056ZnNkWWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJwcm9tZXRoZXVzLXRva2VuLWpxMmtnIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InByb21ldGhldXMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxNDYxYTU1Mi0xZWE0LTRjYWQtOTdhOC05YmE1Zjg2YjhkMmYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cHJvbWV0aGV1cyJ9.FfRTfjE5ih9ZvCy0XFL1Trc00H7k1s6kkGmFvnkKJghswTLeATRPfziAJqrBYBYY0dA8IK52WEa0JR2TevtotnWOyIXZnv6KWcPb0RObvlL4dxp1ZJyZRAc01rliyukTU2HphgX2NlLnf_TZHMo1bapPf8crDdMlZHoEe42ukMtr1nZrPgChXJCtGoR383bAWDoDrq1nZ7e8xCQnoxEkq_khLO9ypHqAlFfMCG-w0x35uC1Wa06FdoeygW0gABDK_Ltgvz6_IuLM9wLl54SnPZJEPSMfiNpuvN8vDWNUcjqPj1Lqi3eSMKLf7b3zBvlTEcLQKoUQdXBdg-97pfeDVw
现在可以让普罗米修斯拿着这个token访问api了。
-
创建Job和kubeconfig_sd_configs**
现在可以让普罗米修斯拿着这个token访问api了,这里启用的是k8s服务发现的配置。
[root@localhost ~]# vim /usr/local/prometheus/prometheus.yml
- job_name: kubernetes-nodes-cadvisor
metrics_path: /metrics
scheme: https #访问api使用https访问
kubernetes_sd_configs:
- role: node #指定服务发现类型的角色为node
api_server: https://192.168.179.102:6443
bearer_token_file: /usr/local/prometheus/token.k8s
tls_config:
insecure_skip_verify: true #跳过https验证,因为自签发,不受信任,跳过证书校验
bearer_token_file: /usr/local/prometheus/token.k8s
tls_config:
insecure_skip_verify: true #跳过证书
relabel_configs:
# 将标签(.*)作为新标签名,原有值不变
- action: labelmap
regex: __meta_kubernetes_node_label_(.*)
# 修改NodeIP:10250为APIServerIP:6443
- action: replace
regex: (.*)
source_labels: ["__address__"]
target_label: __address__
replacement: 192.168.31.61:6443
# 实际访问指标接口 https://NodeIP:10250/metrics/cadvisor 这个接口只能APISERVER访问,故此重新标记>标签使用APISERVER代理访问
- action: replace
source_labels: [__meta_kubernetes_node_name]
target_label: __metrics_path__
regex: (.*)
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
[root@localhost prometheus]# ./promtool check config prometheus.yml
Checking prometheus.yml
SUCCESS: 0 rule files found
https://192.168.179.102:6443/api/v1/nodes/k8s-node1/proxy/metrics/cadvisor,这些数据就是从这个地址下面拿到的,如果你将该段去掉,可以看到没有重新标记标签会采集不到数据。
# - action: replace
# source_labels: [__meta_kubernetes_node_name]
# target_label: __metrics_path__
# regex: (.*)
# replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
以上就是今天给大家分享的 Prometheus 基于K8S服务发现配置与案例介绍。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
参考文章:https://blog.csdn.net/qq_37256882/article
/details/129337276
https://blog.csdn.net/qq_34556414/article/
details/113350137
读者专属技术群
构建高质量的技术交流社群,欢迎从事后端开发、运维技术进群(备注岗位,已在技术交流群的请勿重复添加)。主要以技术交流、内推、行业探讨为主,请文明发言。广告人士勿入,切勿轻信私聊,防止被骗。
扫码加我好友,拉你进群
PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!
更多推荐
所有评论(0)