Prometheus 服务发现机制
Prometheus 默认才用pull取拉取监控数据的,也就是定时去目标主机去抓取metrics数据。所以每一个被抓取目标需要暴露一个HTTP接口,通过这个借口获取对应指标数据。
这种方式需要由目标服务决定抓取的采集目标有哪些,通过配置在scrape_config中的各种job实现,无法动态感知新服务。如果后续添加新服务就要手动改prometheus的配置,所以要用动态服务发现,通过服务发现,prometheus能查询到需要监控的Target列表,然后轮询这个Target获取监控数据
获取数据源target的方式有很多种,静态配置和服务发现,实现服务发现的方式有:
kubernetes_sd_configs #k8s服务发现,让prome动态发现k8s中被监控的目标
static_configs #静态服务发现,基于prometheus配置文件指定的监控目标(默认使用的)
dns_sd_configs #DNS服务发现监控数据
consul_sd_configs . #Consul服务发现,基于consul动态发现监控目标
file_sd_configs #基于指定的文件实现服务发现
一、kubernetes_sd_configs 1 2 3 4 5 6 promethues 的relabeling (重新修改标签)功能很强大,它能够在抓取到目标实例之前把目标实例的元数据标签动态重新修改,动态添加或者覆盖标签 prometheus 加载 target 成功之后,在Target 实例中,都包含一些 Metadata 标签信息,默认的标签有: __address__:以<host>:<port>格式显示目标targets的地址 __scheme__:采集的目标服务地址的Scheme形式, HTTP 或者HTTPS __metrics_path__:采集的目标服务的访问路径
基础功能-重新标记目的
1 2 3 relabel_configs: 在采集之前(比如在采集数据之前重新定义元标签),可以使用relabel_configs添加一些标签、也可以只采集特定目标或过滤目标。 metric_relabel_configs: 如果是已经抓取到指标数据时,可以使用metric_relabel_configs做最后的重新标记和过滤
配置 -> 重新标签(relabel_configs)-> 抓取 -> 重新标签(metric_relabel_configs) -> TSDB
1 2 3 4 5 6 7 8 9 10 11 - job_name: 'kubernetes-apiserver' kubernetes_sd_configs: #基于kubernetes_sd_configs 实现服务发现 - role: endpoints # 发现endpoints scheme: https #当前job使用的发现协议 tls_config: #证书配置 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt #容器里的证书路径 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token #容器里的token路径 relabel_configs: #重新re修改标签label配置configs - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] action: keep #action定义里relabel的具体动作,action支持多种 regex: default;kubernetes;https #发现了default命名空间的kubernetes服务且时https协议
label 详解 1 2 3 4 source_labels: 源标签,没有经过relabel处理之前的标签名字 target_label: 通过action处理之后的新的标签名字 regex: 正则表达式,匹配源标签 replacement: 通过分组替换后标签(target_label)对应的值
action 详解 https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_con
1 2 3 4 5 6 7 8 9 replace: 替换标签纸,根据regex正则匹配到源标签的值,使用replacement来引用表达式匹配的分组 keep: 满足regex正则条件的实例进行采集,把source_labels中没有匹配到regex正则内容的Target实例丢掉,即只采集匹配成功的实例 drop: 满足 regex 正则条件的实例不采集,把source_labels中匹配到regex正则内容的Target实例丢掉,即只采集没有匹配到的实例 --------------------------------------------------------- labelmap: 匹配 regex所有标签名称,然后复制匹配标签的值进行分组,通过replacement分组引用($[1),$[2),…)替代 labelkeep: 匹配 regex所有标签名称,其它不匹配的标签都将从标签集中删除 labeldrop: 匹配 regex所有标签名称,其它匹配的标签都将从标签集中删除
支持的发现目标类型
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config
node
service
pod
endpoints
Endpointslice #对endpoint进行分片
ingress
api-server 指标数据 监控 api-server 实现
可以直接通过k8s的service来获取
1 2 3 4 5 6 7 - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] action: keep regex: default;kubernetes;https #含义为匹配default的namespace,svc名称时kubernetes并且协议时https,匹配成功后进行保留,并且把regex作为source_labels相对应的值。 即labels为key、regex为值 # label替换方式如下: __meta_kubernetes_namespace=default,__meta_kubernetes_service_name=kubernetes,__meta_kubernetes_endpoint_port_name=https #最终可以匹配到api-server的地址
apiserver_request_total
查询apiserver最近一分钟不同方法的请求数量统计:
1 sum(rate(apiserver_request_total[1m]))by(resource,subresource,verb)
irate 和 rate 都会用于计算某个指标在一定时间间隔内的变化速率。但是它们的计算方法有所不同: irate取的是在指定时间范围内的最近两个数据点来算速率,而rate会取指定时间范围内所有数据点,算出一组速率,然后取平均值作为结果。
1 2 3 4 5 6 7 # 所以官网文档说:irate适合快速变化的计数器(counter),而rate适合缓慢变化的计数器(counter)。 # 根据以上算法我们也可以理解,对于快速变化的计数器,如果使用rate,因为使用了平均值,很容易把峰值削平。除非我们把时间间隔设置得足够小,就能够减弱这种效应。 ------------------------------------------------ rate(apiserver_request_total{code=~"^(?:2..)$"}[5m]) irate(apiserver_request_total{code=~"^(?:2..)$"}[5m]) # 两者有着一定的区别
关于 annotation_prometheus_io_scrape
在 k8s 中,基于prometheus的发现规则,需要在发现的目的 target 定义注解匹配 annotation_prometheus_io_scrape=true,且必须匹配成功该注解才会保留监控 target,然后再进行数据抓取并进行标签替换
如 annotation_prometheus_io_scrape 标签为http 或者htpps
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 - 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: kubernetes_namespace - source_labels: [__meta_kubernetes_service_name ] action: replace target_label: kubernetes_name
kube-dns 的服务发现
查看 kube-dns 状态
1 2 3 4 kubectl describe svc kube-dns -n kube-system prometheus.io/port:9153 #注释标签,用于prometheus服务发现端口 prometheus.io/scrape:true #运行prometheus抓取数据
修改副本数进行验证:
1 2 3 4 kubectl edit deployments coredns -n kube-system 3 # prometheus上查看,确实自动发现新增pod
node 节点发现及指标 1 2 3 4 5 6 7 8 9 10 11 12 - job_name: 'kubernetes-node' kubernetes_sd_configs: - role: node relabel_configs: - source_labels: [__address__ ] regex: '(.*):10250' replacement: '${1}:9100' target_label: __address__ action: replace - action: labelmap regex: __meta_kubernetes_node_label_(.+)
kubelet 监听端口
lsof -i : 10250
node 节点指标数据
curl ip:9100/metrics
常见监控指标
node_cpu_ :CPU相关指标
node_load1: load average #系统负载指标 (包括node_load5 、node_load15)
node_memory_ : 内存相关指标
node_network_ : 网络相关指标
node_disk_ : 磁盘IO相关指标
node_filesystem_ : 文件系统相关指标
node_boot_time_seconds: 系统启动时间监控
go_* : node exporter 运行中go相关指标
process_* : node exporter 进程内部指标
pod 发现及指标数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - job_name: 'kubernetes-node-cadvisor' kubernetes_sd_configs: - role: node scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - action: labelmap regex: __meta_kubernetes_node_label_(.+) - target_label: __address__ replacement: kubernetes.default.svc:443 - source_labels: [__meta_kubernetes_node_name ] regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
tls_config 配置的证书地址是每个 Pod 连接 apiserver 所使用的地址,无论证书是否用得上,在 Pod 启动的时候 kubelet 都会给每一个 pod 自动注入 ca 的公钥,即所有的 pod 启动的时候都会有一个 ca 公钥被注入进去用于在访问 apiserver 的时候被调用。
验证一下:
1 2 3 4 5 6 7 8 9 10 kubectl exec test-pod1 ls /var/run/secrets/kubernetes.io/serviceaccount/ ca.crt namespace token kubectl exec test-pod1 md5sum /var/run/secrets/kubernetes.io/serviceaccount/ca.crt dc631beObb3e4ca96cb9c671e607aa89 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt md5sum /etc/kubernetes/ca.crt dc631beObb3e4ca96cb9c671e607aa89 /etc/kubernetes/ca.crt
pod 监控指标
1 2 3 4 5 6 sum(rate(container_cpu_usage_seconds_total{image!=""}[1m]))without(instance) sum(rate(container_memory_usage_bytes{image!=""}[1m]))without(instance) sum(rate(container_fs_io_current{image!=""}[1m]))without(device) sum(rate(container_fs_writes_bytes_total{image!=""}[1m]))without(device) sum(rate(container_fs_reads_bytes_total{image!=""}[1m]))without(device) sum(rate(container_network_receive_bytes_total{image!=""}[1m]))without(interface)
prometheus 部署在 k8s 集群以外并实现服务发现 编写创建用户并授权的yaml
vim prom-rbac.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 apiVersion: v1 kind: ServiceAccount metadata: name: prometheus namespace: monitoring --- apiVersion: rbac.authorization.k8s.io/v1 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/v1 kind: ClusterRoleBinding metadata: name: prometheus roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus subjects: - kind: ServiceAccount name: prometheus namespace: monitoring
应用并获取token
1 2 3 4 5 6 7 8 kubectl create -f prom-rbac.yaml # 获取 token kubectl get sa prometheus -n monitoring -o yaml # 将 token 保存至 prometheus server 节点的 k8s.token 文件,后期用于权限验证 kubectl describe secret prometheus-token-ff53s -n monitoring vim /apps/prometheus/k8s.token
prometheus 添加 job
vim /app/prometheus/prometheus.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 global: scrape_interval: 15s evaluation_interval: 15s rule_files: scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090" ] - job_name: 'kubernetes-apiserver-monitor' kubernetes_sd_configs: - role: endpoints api_server: https://---master ip---:6443 tls_config: insecure_skip_verify: true bearer_token_file: /apps/prometheus/k8s.token .....
二、staic_config 很简单的静态配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090" ] static_configs: - targets: ['192.168.15.100:9100' ,'192.168.15.101:9100' ] - job_name: 'prometheus-containers' static_configs: - targets: ["192.168.15.100:8080" ,"192.168.15.101:8080" ]
三、consul_sd_configs https://www.consul.io/
https://releases.hashicorp.com/consul/1.11.1/
部署集群
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 192.168.3.101 192.168.3.102 192.168.3.103 # Node1: unzip consul_1.11.1_linux_arm64.zip cp consul /usr/local/bin/ scp consul 192.168.3.102:/usr/local/bin/ scp consul 192.168.3.103:/usr/local/bin/ # consul -h # 分别创建数据目录 mkdir /data/consul/ -p # 启动服务 node1: nohup ./consul agent -server -bootstrap -bind=192.168.15.100 -client=192.168.15.100 -data-dir=/data/consul -ui -node=192.168.15.100 & node2: nohup ./consul agent -bind=192.168.15.101 -client=192.168.15.101 -data-dir=/data/consul -node=192.168.15.101 -join=192.168.15.100 & node3: nohup ./consul agent -bind=192.168.15.102 -client=192.168.15.102 -data-dir=/data/consul -node=192.168.15.102 -join=192.168.15.100 &
测试写入数据
通过 consul 的 API 写入数据
1 2 3 4 5 6 curl -X PUT -d '{"id": "node-exporter100", "name": "node-exporter100", "address": "192.168.15.100","port":9100,"tags":["node-exporter"], "checks":[{"http":"http://192.168.15.100:9100/","interval":"5s"}]}' http://192.168.15.100:8500/v1/agent/service/register curl -X PUT -d '{"id": "node-exporter101", "name": "node-exporter101", "address": "192.168.15.101","port":9100,"tags":["node-exporter"], "checks":[{"http":"http://192.168.15.101:9100/","interval":"5s"}]}' http://192.168.15.101:8500/v1/agent/service/register # 登入 192.168.15.100:8500 验证
配置 prometheus 到 consul 发现服务 主要配置字段:
1 2 3 4 static_configs: #配置数据源 consul_sd_configs: #指定基于 consul 服务发现的配置 rebel_configs: #重新标记 services: [] #表示配 consul 中所有的service
K8s 部署 prometheus 配置文件
vim prometheus-cfg.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - job_name: 'consul' honor_lables: true metrics_path: /metrics scheme: http consul_sd_configs: - server: 192.168 .15 .100 :8500 services: [] - server: 192.168 .15 .101 :8500 services: [] - server: 192.168 .15 .102 :8500 services: [] relabel_configs: - source_labels: ['__meta_consul_tags' ] target_label: 'product' - source_labels: ['__meta_consul_dc' ] target_label: 'idc' - source_labels: ['__meta_consul_service' ] regex: "consul" action: drop
二进制 prometheus 配置文件
vim prometheus.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - job_name: 'consul' honor_lables: true metrics_path: /metrics scheme: http consul_sd_configs: - server: 192.168 .15 .100 :8500 services: [] - server: 192.168 .15 .101 :8500 services: [] - server: 192.168 .15 .102 :8500 services: [] relabel_configs: - source_labels: ['__meta_consul_tags' ] target_label: 'product' - source_labels: ['__meta_consul_dc' ] target_label: 'idc' - source_labels: ['__meta_consul_service' ] regex: "consul" action: drop
重启prometheus
systemctl restart prometheus.service
测试 consul 服务删除
1 curl --request PUT http://192.168.15.100:8500/v1/agent/service/deregister/node-exporter100
四、file_sd_configs 编辑 sd_configs 文件
1 2 3 4 5 6 7 8 9 10 # pwd /apps/prometheus mkdir file_sd vim file_sd/sd_my_server.json [ { "targets": ["192.168.15.100:9100", "192.168.15.101:9100","192.168.15.102:9100"] } ]
prometheus 调用 sd_configs
1 2 3 4 5 6 7 8 9 - job_name: 'file_sd_my_server' file_sd_configs: - files: - /apps/prometheus/file_sd/sd_my_server.json refresh_interval: 10s systemctl restart prometheus
五、DNS 服务发现 1 2 3 没有DNS服务器做实验 ... 像SRV服务发现做不了,那种就是在prome的配置文件中在type值写为SRV 可以在 /etc/hosts 修改一下,做一下A记录服务发现,但没必要...