一、prometheus服务发现概述
1、服务发现概述
由于prometheus是通过pull的形式来去目标主机上拉取数据,就是说prometheus服务器必须知道要监控的目标主机的地址等信息,当新增主机的时候,就需要手动增加prometheus的配置文件,很麻烦,所以出现了服务发现,来自动发现被监控的主机,并加入到配置中,然后prometheus再定时的拉取目标主机暴漏的指标。
本次主要讲解基于kubernetes的服务发现
2、服务发现的类型
- file_sd_config:基于文件的服务发现
- dns_sd_config:基于DNS的服务发现
- kubernetes_sd_config:基于kubernetes的服务发现
- consul_sd_config:基于consul的服务发现
二、kubernetes_sd_config配置文件分析
1、配置文件编写流程
prometheus自动发现的核心之处在于relabel_configs的相关配置,首先是通过source_labels配置以__meta_开头的这些元数据标签,声明要匹配的资源,然后通过regex匹配规则找到相关的资源对象,最后再对采集过来的指标做二次处理,比如保留、过来、替换等操作。
2、配置文件示例
global:
# 间隔时间
scrape_interval: 30s
# 超时时间
scrape_timeout: 10s
# 另一个独立的规则周期,对告警规则做定期计算
evaluation_interval: 30s
# 外部系统标签用于区分prometheus服务实例
external_labels:
prometheus: monitoring/k8s
prometheus_replica: prometheus-k8s-1
scrape_configs:
# 定义job名称,一个能够被抓取监控数据的endpoint叫做Instance,有着同样目的的Instance集合叫做Job。
- job_name: "prometheus"
# Honor_labels 控制 Prometheus 如何处理已存在于抓取数据中的标签与 Prometheus 将在服务器端附加的标签(“作业”和“实例”标签、手动配置的目标标签以及由服务发现实现生成的标签)之间的冲突。
# 如果honor_labels 设置为“true”,标签冲突通过从抓取的数据中保留标签值并忽略冲突的服务器端标签来解决。
# 如果 Honor_labels 设置为“false”,则通过将抓取数据中的冲突标签重命名为“exported_<original-label>”来解决标签冲突(
# 将 Honor_labels 设置为“true”对于联邦和抓取 Pushgateway 等用例很有用,其中应保留目标中指定的所有标签。
honor_labels: true
# Honor_timestamps是否采用抓取数据中存在的时间戳默认为true。设置为“true”,则将使用目标公开的指标的时间戳。设置为“false”,则目标公开的指标的时间戳将被忽略。
honor_timestamps: true
# 抓取目标的频率
scrape_interval: 30s
# 抓取请求超时的时间
scrape_timeout: 10s
# 配置抓取请求的 TLS 设置。(https协议时需要填写证书等相关配置)
#tls_config:
# [ <tls_config> ]
# bearer_token_file
# 使用配置的承载令牌在每个scrape请求上设置`Authorization`标头。 它`bearer_token_file`和是互斥的。
#[ bearer_token: <secret> ]
# 使用配置的承载令牌在每个scrape请求上设置`Authorization`标头。 它`bearer_token`和是互斥的。
# [ bearer_token_file: /path/to/bearer/token/file ]
# 从目标获取指标的资源路径,默认为/metrics
metrics_path: /metrics
# 配置请求使用的协议方案,默认为http
scheme: http
# 基于kubernetes的API server实现自动发现
kubernetes_sd_configs:
# 角色为 endpoints,通过service来发现后端endpoints,每一个service都有对应的endpoints,如果满足采集条件,那么在service、POD中定义的labels也会被采集进去
- role: endpoints
# 标签匹配处理相关配置
relabel_configs:
# 以prometheus服务为例,他的service标签为app=prometheus。因此source_labels选择__meta_kubernetes_service_label_app,他会列出k8s所有服务对象的标签,其他常用的元数据标签如下
# 节点node
# __meta_kubernetes_node_name: 节点对象的名称
# __meta_kubernetes_node_label_<labelname>: 节点对象的每个标签
# __meta_kubernetes_node_address_<address_type>: 如果存在,每一个节点对象类型的第一个地址
# 服务service
# __meta_kubernetes_namespace: 服务对象的命名空间
# __meta_kubernetes_service_cluster_ip: 服务的群集IP地址。(不适用于ExternalName类型的服务)
# __meta_kubernetes_service_external_name: 服务的DNS名称。(适用于ExternalName类型的服务)
# __meta_kubernetes_service_label_<labelname>: 服务对象的标签。
# __meta_kubernetes_service_name: 服务对象的名称
# __meta_kubernetes_service_port_name: 目标服务端口的名称
# __meta_kubernetes_service_port_protocol: 目标服务端口的协议
# __meta_kubernetes_service_type: 服务的类型
# pod
# __meta_kubernetes_namespace: pod对象的命名空间
# __meta_kubernetes_pod_name: pod对象的名称
# __meta_kubernetes_pod_ip: pod对象的IP地址
# __meta_kubernetes_pod_label_<labelname>: pod对象的标签
# __meta_kubernetes_pod_container_name: 目标地址的容器名称
# __meta_kubernetes_pod_container_port_name: 容器端口名称
# __meta_kubernetes_pod_ready: 设置pod ready状态为true或者false
# __meta_kubernetes_pod_phase: 在生命周期中设置 Pending, Running, Succeeded, Failed 或 Unknown
# __meta_kubernetes_pod_node_name: pod调度的node名称
# __meta_kubernetes_pod_host_ip: 节点对象的主机IP
# __meta_kubernetes_pod_uid: pod对象的UID。
# __meta_kubernetes_pod_controller_kind: pod控制器的kind对象.
# __meta_kubernetes_pod_controller_name: pod控制器的名称.
# 端点endpoints
# __meta_kubernetes_namespace: 端点对象的命名空间
# __meta_kubernetes_endpoints_name: 端点对象的名称
# __meta_kubernetes_endpoint_hostname: 端点的Hostname
# __meta_kubernetes_endpoint_node_name: 端点所在节点的名称。
# __meta_kubernetes_endpoint_ready: endpoint ready状态设置为true或者false。
# __meta_kubernetes_endpoint_port_name: 端点的端口名称
# __meta_kubernetes_endpoint_port_protocol: 端点的端口协议
# __meta_kubernetes_endpoint_address_target_kind: 端点地址目标的kind。
# __meta_kubernetes_endpoint_address_target_name: 端点地址目标的名称。
# ingress
# __meta_kubernetes_namespace: ingress对象的命名空间
# __meta_kubernetes_ingress_name: ingress对象的名称
# __meta_kubernetes_ingress_label_<labelname>: ingress对象的每个label。
# __meta_kubernetes_ingress_scheme: 协议方案,如果设置了TLS配置,则为https。默认为http。
# __meta_kubernetes_ingress_path: ingree spec的路径。默认为/。
- source_labels: [__meta_kubernetes_service_label_app]
# 通过正式表达式匹配,条件为service的label标签app=prometheus的资源
regex: prometheus
# 执行动作
# keep:仅收集匹配到regex的源标签,而会丢弃没有匹配到的所有标签,用于选择
# replace:默认行为,不配置action的话就采用这种行为,它会根据regex来去匹配source_labels标签上的值,并将并将匹配到的值写入target_label中
# labelmap:它会根据regex去匹配标签名称,并将匹配到的内容作为新标签的名称,其值作为新标签的值
# drop:丢弃匹配到regex的源标签,而会收集没有匹配到的所有标签,用于排除
# labeldrop:使用regex匹配标签,符合regex规则的标签将从target实例中移除,其实也就是不收集不保存
# labelkeep:使用regex匹配标签,仅收集符合regex规则的标签,不符合的不收集
action: keep
# 添加服务对象的名称空间信息,并替换标签名为namespace
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
# 添加对象的名称信息,并替换为name
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: name
# 添加pod对象的名称信息,并替换为pod
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: pod
三、监控Kubernetes核心组件
1、通过helm部署prometheus
添加helm仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
在helm仓库中搜索prometheus
helm search repo prometheus
将prometheus的chart包下载到本地并解压
helm pull bitnami/prometheus --untar
根据自己的需求修改部分values的值后,部署prometheus
helm install -n monitor prometheus ./../prometheus
查看prometheus的状态
[root@iZbp1igh8gtzjj9sgk4cykZ prometheus]# kubectl -n monitor get pod
NAME READY STATUS RESTARTS AGE
prometheus-alertmanager-0 1/1 Running 0 6d23h
prometheus-server-c86f8cf58-xlgkt 1/1 Running 0 50m
查看service
[root@iZbp1igh8gtzjj9sgk4cykZ prometheus]# kubectl -n monitor get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus-alertmanager NodePort 10.68.139.119 <none> 80:30723/TCP 6d23h
prometheus-server NodePort 10.68.95.2 <none> 80:20328/TCP 6d23h
通过nodeport访问web页面
2、监控Kubernetes核心组件
默认不会监控Kubernetes核心组件,所以需要将默认的configmap的配置文件导出来,修改后,再通过 kubectl apply 进行更新,重启pod生效。
导出配置文件
kubectl -n monitor get configmaps prometheus-server -o yaml >prometheus-configmap.yaml
我们的核心组件都是由systemd进程托管,这些核心组件都自带对外暴露metrics的功能。
1.监控kube-apiserver
说明:因为apiserver是集群的唯一入口,所有的资源创建、访问、管理都需要经过apiserver,在集群内部想要访问apiserver的话,就必须与其进行通讯,因此kubernetes默认会在default名称空间下创建一个名字为Kubernetes的service资源。而这个service的后端对应着集群的apiserver。
[root@iZbp1igh8gtzjj9sgk4cykZ prometheus]# kubectl get svc,endpoints
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 94d
NAME ENDPOINTS AGE
endpoints/kubernetes 172.16.185.245:6443,172.16.185.247:6443,172.16.185.248:6443 94d
服务发现配置
- job_name: kube-apiserver
kubernetes_sd_configs:
- role: endpoints
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:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name]
#元标签
action: keep
#保留标签
regex: default;kubernetes
#要匹配的关键字,也就是default名称空间下的名字为kubernetes的service服务
需要注意的是使用https访问时,需要tls相关配置,可以指定ca证书路径或者insecure_skip_verify: true跳过证书验证。除此之外,还要指定bearer_token_file,否则会提示server returned HTTP status 400 Bad Request
2.监控etcd
etcd默认没有开启指标暴漏,添加启动参数–listen-metrics-urls=http://0.0.0.0:2381,参数就是来指定 Metrics 接口运行在 2381 端口下面的,而且是 http 的协议。
etcd的systemd配置文件
cat /etc/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
ExecStart=/opt/kube/bin/etcd \
--name=etcd-172.16.185.245 \
--cert-file=/etc/kubernetes/ssl/etcd.pem \
--key-file=/etc/kubernetes/ssl/etcd-key.pem \
--peer-cert-file=/etc/kubernetes/ssl/etcd.pem \
--peer-key-file=/etc/kubernetes/ssl/etcd-key.pem \
--trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
--peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
--initial-advertise-peer-urls=https://172.16.185.245:2380 \
--listen-metrics-urls=http://0.0.0.0:2381 \
--listen-peer-urls=https://172.16.185.245:2380 \
--listen-client-urls=https://172.16.185.245:2379,http://127.0.0.1:2379 \
--advertise-client-urls=https://172.16.185.245:2379 \
--initial-cluster-token=etcd-cluster-0 \
--initial-cluster=etcd-172.16.185.245=https://172.16.185.245:2380,etcd-172.16.185.247=https://172.16.185.247:2380,etcd-172.16.185.248=https://172.16.185.248:2380 \
--initial-cluster-state=new \
--data-dir=/var/lib/etcd \
--wal-dir= \
--snapshot-count=50000 \
--auto-compaction-retention=1 \
--auto-compaction-mode=periodic \
--max-request-bytes=10485760 \
--quota-backend-bytes=8589934592
Restart=always
RestartSec=15
LimitNOFILE=65536
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
因为etcd由systemd托管,所以需要配置服务发现的角色为node级别,并且etcd只运行在master节点上,所以要保留角色为master的主机,并将默认的端口替换为2381.
prometheus相关配置文件
- job_name: etcd
kubernetes_sd_configs:
- role: node
scheme: http
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels:
- __meta_kubernetes_node_label_kubernetes_io_role
regex: master
action: keep
- source_labels: [__meta_kubernetes_node_address_InternalIP]
regex: (.+)
target_label: __address__
replacement: ${1}:2381
- source_labels: [__meta_kubernetes_node_name]
action: replace
target_label: node-name
replacement: etcd-${1}
结果查看
3.监控kube-scheduler
kube-scheduler是通过10259端口进行暴漏,查看kube-scheduler的配置文件,如果没有绑定在0.0.0.0,需要进行修改
cat /etc/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/opt/kube/bin/kube-scheduler \
--authentication-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
--authorization-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
--bind-address=0.0.0.0 \
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
--leader-elect=true \
--v=2
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
prometheus配置文件
- job_name: kube-scheduler
metrics_path: /metrics
scheme: https
tls_config:
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels:
- __meta_kubernetes_node_label_kubernetes_io_role
regex: master
action: keep
- source_labels: [__meta_kubernetes_node_address_InternalIP]
regex: (.+)
target_label: __address__
replacement: ${1}:10259
- source_labels: [__meta_kubernetes_node_name]
action: replace
target_label: node-name
replacement: kube-scheduler-${1}
结果查看
4.监控controller-manager
controller-manager是通过10257端口暴漏指标,如果没监听为0.0.0.0,需要修改一下配置。
prometheus配置文件
- job_name: kube-controller-manager
metrics_path: /metrics
scheme: https
tls_config:
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
relabel_configs:
- source_labels:
- __meta_kubernetes_node_label_kubernetes_io_role
regex: master
action: keep
- source_labels: [__meta_kubernetes_node_address_InternalIP]
regex: (.+)
target_label: __address__
replacement: ${1}:10257
- source_labels: [__meta_kubernetes_node_name]
action: replace
target_label: endpoint
replacement: kube-controller-manager-${1}
结果查看
5.监控kube-proxy
kube-proxy在每个节点上都会运行,端口为10249,角色也为node
prometheus配置文件
- job_name: kube-proxy
metrics_path: /metrics
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:10249'
target_label: __address__
action: replace
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- source_labels: [__meta_kubernetes_endpoints_name]
action: replace
target_label: endpoint
- source_labels: [__meta_kubernetes_node_name]
action: replace
target_label: endpoint
replacement: kube-proxy-${1}
结果查看
6.监控kubelet
kube-proxy在每个节点上都会运行,端口为10250,默认就是此端口,不需要变更,角色也为node。
需要注意的是他的指标采集地址为/metrics/cadvisor,需要配置https访问,可以设置insecure_skip_verify: true跳过证书验证
prometheus配置文件
- job_name: kubelet
metrics_path: /metrics/cadvisor
scheme: https
tls_config:
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
结果查看
7、监控coredns
coredns以pod的形式部署在集群中,查看coredns的资源详情
[root@iZbp1igh8gtzjj9sgk4cykZ jws2]# kubectl -n kube-system describe svc kube-dns
Name: kube-dns
Namespace: kube-system
Labels: addonmanager.kubernetes.io/mode=Reconcile
k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=CoreDNS
Annotations: prometheus.io/port: 9153
prometheus.io/scrape: true
Selector: k8s-app=kube-dns
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.68.0.2
IPs: 10.68.0.2
Port: dns 53/UDP
TargetPort: 53/UDP
Endpoints: 172.20.129.252:53,172.20.215.195:53
Port: dns-tcp 53/TCP
TargetPort: 53/TCP
Endpoints: 172.20.129.252:53,172.20.215.195:53
Port: metrics 9153/TCP
TargetPort: 9153/TCP
Endpoints: 172.20.129.252:9153,172.20.215.195:9153
Session Affinity: None
Events: <none>
匹配标签中包含kube-dns的pod资源即可,默认为53端口,需要relable到9153
prometheus配置文件
- job_name: coredns
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels:
- __meta_kubernetes_service_label_k8s_app
regex: kube-dns
action: keep
- source_labels: [__meta_kubernetes_pod_ip]
regex: (.+)
target_label: __address__
replacement: ${1}:9153
- source_labels: [__meta_kubernetes_endpoints_name]
action: replace
target_label: endpoint
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: pod
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: service
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
结果查看
8、监控node-exporter
node_exporter也是每个node节点都运行,因此role使用node即可,默认address端口为10250,替换为9100即可
prometheus配置文件
- job_name: node_exporter
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:9100'
target_label: __address__
action: replace
结果查看