第十七章、云原生监控Prometheus入门 17.1什么是Prometheus Prometheus 是一个开源的系统监控和告警工具包。它最初是由 SoundCloud 开发的,目前已经成为云原生计算基金会(CNCF)的第二个毕业项目(仅次于 Kubernetes)。
主要特点包括:
多维度数据模型
时间序列数据由指标名称和键值对标签组成
支持灵活的查询语言 PromQL
数据收集
通过 HTTP 协议采用 pull 模型拉取数据
支持 push 网关来接收短期任务的数据推送
支持服务发现和静态配置
数据存储
使用本地时序数据库存储监控数据
高效的数据压缩算法
支持数据的长期存储
可视化
内置简单的图形界面
可以与 Grafana 等工具集成实现更强大的可视化
告警
支持灵活的告警规则配置
通过 Alertmanager 组件统一处理告警
17.2Prometheus结构解析
1. Prometheus Server-核心组件
核心功能 :Prometheus Server 是整个监控系统的核心,用于从不同的目标(targets)拉取指标数据,存储在时间序列数据库(TSDB)中,并提供查询接口。
主要组件
Retrieval :检索模块,负责从配置的监控目标(如 exporters)中定期拉取(pull)指标数据。
TSDB(Time Series Database) :时间序列数据库,用于存储拉取到的监控数据。
HTTP Server :提供 HTTP API 接口服务 和 Prometheus 查询语言(PromQL)接口,用户和其他服务可以通过它访问数据和执行查询。
数据存储 :Prometheus 通过本地磁盘(如 HDD/SSD)来存储数据。
2. Prometheus Targets-数据采集层
定义 :Prometheus 通过拉取(pull)的方式从不同的监控目标(Targets)收集数据。Targets 包括各种可以提供 Prometheus 格式指标数据的进程或服务。
Jobs 和 Exporters :这些目标可能是应用的实例(称为 Jobs),也可以是特定的 Exporters,如 Node Exporter(收集操作系统数据)或其他第三方导出器。
数据拉取方式 :Prometheus Server 定期从这些目标拉取数据,以便获得最新的监控指标。
3. Pushgateway-数据采集层
作用 :Pushgateway 用于接收短生命周期任务的指标数据。某些任务可能只运行一次或持续时间很短(例如批处理任务),如果直接被 Prometheus 拉取,可能无法及时捕获这些任务的状态。Pushgateway 允许这些任务在退出时推送数据,保证 Prometheus Server 能拉取到这些数据。
数据流向 :短生命周期任务在结束时向 Pushgateway 推送数据,Prometheus Server 再从 Pushgateway 拉取这些数据。
4. Service Discovery-服务发现 支持两种主要的服务发现方式:
kubernetes : 自动发现 K8s 集群中的监控目标
file_sd : 基于文件的服务发现机制
作用 :Prometheus 使用服务发现机制动态发现需要监控的目标。常见的服务发现方式包括 Kubernetes API、静态文件配置(file_sd)等。
Kubernetes Integration :对于 Kubernetes 环境,Prometheus 可以直接通过 Kubernetes API 动态发现 Pod、Service 等资源,实现自动化监控。
5. Alertmanager-告警模块
作用 :Prometheus 中的 Alertmanager 负责处理由 Prometheus Server 生成的告警。Prometheus 使用预先定义的告警规则来触发告警事件(例如某些指标超过阈值)。
告警推送 :Prometheus Server 会根据配置的告警规则将告警推送给 Alertmanager。Alertmanager 负责对告警进行分组、去重、抑制等操作,并根据配置发送到不同的通知渠道。
通知渠道 :Alertmanager 可以将告警通过 Email、PagerDuty 或其他集成工具发送给运维团队。
6. 数据可视化与查询接口(图右下部分) PromQL : Prometheus 的查询语言
Prometheus Web UI :Prometheus 自带的 Web UI 提供了一些基本的可视化和查询功能,用户可以通过 PromQL 执行查询,并查看实时数据。
Grafana :更高级的可视化需求通常会借助 Grafana,它可以直接查询 Prometheus 数据,并提供丰富的图表选项和可定制的仪表板。
API Clients :Prometheus 提供 HTTP API,使得外部应用或脚本可以直接查询 Prometheus 中的数据,以实现自定义分析或集成需求。
7. 数据流向总结 Pull 模式:
Prometheus server 主动从 targets 拉取数据
从 Pushgateway 拉取短期任务的数据
Pull 模式 :Prometheus 的默认数据采集模式是从 Targets 拉取数据,Prometheus Server 定期访问每个目标的 HTTP 指标端点,获取并存储指标。
Push 模式:
告警流:
Prometheus Server 通过配置的告警规则触发告警事件,将其推送给 Alertmanager。Alertmanager 处理告警并发送给指定的通知系统(如 Email、PagerDuty)。
总结 Prometheus 架构的关键在于「拉取模式」的数据采集、「时间序列数据库」的数据存储、「告警管理」的处理方式和「数据可视化」的整合。这个设计使得 Prometheus 在云原生环境中具备了高效、自动化、动态监控的能力,并且与 Kubernetes 等系统无缝集成。
17.3Prometheus常见的自定义资源 在 Kubernetes 环境中部署 Prometheus 时,常见的自定义资源(CRD,Custom Resource Definitions)通常是 Prometheus Operator 提供的。它们主要是为了让 Prometheus 在 K8s 上能自动化地配置和管理,而不是让你每次都手动写繁琐的配置文件。
Prometheus:定义并部署一个或多个 Prometheus 实例,也就是监控系统本身。
Alertmanager:定义并部署 Alertmanager 实例,他负责接受Prometheus 发送的告警,并根据规则将告警通过钉钉、邮件、企业微信等通知到相关人员。
ServiceMonitor:告诉 Prometheus “去监控这个 Service 的指标”,只适用于 Kubernetes 内部服务 。
PodMonitor:与 ServiceMonitor 类似,当服务没有 Service(比如直接通过 Pod IP 访问),就用它来监控单个 Pod。
Probe:通常用于定义监控静态目标,和BlackBox Exporter配合使用,监控官网是否能访问。
ScrapeConfig:用于自定义监控目标,通常用于抓取Prometheus集群外部的目标数据。
AlertmanagerConfig:用于定义Alertmanager 的配置,告诉 Alertmanager 如何处理告警 (路由、分组、抑制规则等)。
PrometheusRule:定义告警规则,也就是告诉 Prometheus “什么时候该报警” (比如阈值、持续时间)。
17.3.1Prometheus资源配置详解 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: prometheus namespace: monitoring spec: replicas: 3 image: quay.io/prometheus/prometheus:v3.1.0 serviceAccountName: prometheus alerting: alertmanagers: - namespace: monitoring name: alertmanager-main apiVersion: v2 port: web resources: requests: memory: 400Mi cpu: 100m limits: memory: 800Mi cpu: 200m nodeSelector: kubernetes.io/os: linux storage: volumeClaimTemplate: spec: storageClassName: fast-ssd resources: requests: storage: 20Gi serviceMonitorSelector: matchLabels: app: prometheus podMonitorSelector: matchLabels: app: prometheus ruleSelector: matchLabels: app: prometheus securityContext: fsGroup: 2000 runAsNonRoot: true runAsUser: 1000 retention: "30d" retentionSize: "15GB" portName: web evaluationInterval: 30s scrapeInterval: 30s
17.3.2Alertmanager资源配置详解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: monitoring.coreos.com/v1 kind: Alertmanager metadata: name: alertmanager namespace: monitoring labels: app: alertmanager app.kubernetes.io/name: alertmanager app.kubernetes.io/component: alerting app.kubernetes.io/part-of: monitoring app.kubernetes.io/instance: k8s app.kubernetes.io/version: 0.23 .0 spec: replicas: 3 image: quay.io/prometheus/alertmanager:v0.23.0 nodeSelector: kubernetes.io/os: linux
17.3.3ServiceMonitor资源配置详解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: grafana-monitor namespace: monitoring labels: app.kubernetes.io/name: servicemonitor app.kubernetes.io/component: microservice-monitor app.kubernetes.io/part-of: monitoring app.kubernetes.io/version: 1.0 .0 spec: selector: matchLabels: app.kubernetes.io/name: grafana endpoints: - port: app-metrics path: /actuator/prometheus interval: 30s scrapeTimeout: 10s
17.3.4PodMonitor资源配置详解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: myapp-pod-monitor namespace: monitoring labels: app.kubernetes.io/name: podmonitor app.kubernetes.io/component: app-metrics app.kubernetes.io/part-of: monitoring app.kubernetes.io/version: 1.0 .0 spec: selector: matchLabels: app: myapp namespaceSelector: matchNames: - prod podMetricsEndpoints: - port: metrics path: /metrics interval: 30s scrapeTimeout: 10s scheme: http
17.3.5Probe 在 Prometheus Operator 中,Probe 用来监控非 K8s Service 的目标,例如外部 HTTP 服务、TCP 端口探活等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 apiVersion: monitoring.coreos.com/v1 kind: Probe metadata: name: external-probe-example namespace: monitoring labels: app.kubernetes.io/name: probe app.kubernetes.io/component: monitoring app.kubernetes.io/part-of: prometheus spec: jobName: probe-external-example interval: 30s scrapeTimeout: 10s prober: url: http://blackbox-exporter.monitoring.svc:9115 scheme: http module: http_2xx targets: staticConfig: static: - https://www.google.com - https://www.github.com
在 Prometheus Operator 中,一个 Probe 只能对应 一个探测任务 (它只有一个 prober、一个 module)。 所以如果想同时探测 HTTP 服务 和 TCP 端口(比如 Redis、MySQL) ,需要为它们分别定义 多个 Probe 资源 。
示例:增加 Redis 和 MySQL 的探测
需要写 3 个探测任务:
HTTP 探测 (外部网站)
Redis 探测 (TCP 6379 端口)
MySQL 探测 (TCP 3306 端口)
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 58 59 60 61 62 63 64 65 66 67 68 apiVersion: monitoring.coreos.com/v1 kind: Probe metadata: name: probe-http-external namespace: monitoring spec: jobName: probe-http-external interval: 30s scrapeTimeout: 10s prober: url: blackbox-exporter.monitoring.svc:9115 scheme: http module: http_2xx targets: staticConfig: static: - https://www.google.com - https://www.github.com --- apiVersion: monitoring.coreos.com/v1 kind: Probe metadata: name: probe-redis namespace: monitoring spec: jobName: probe-redis interval: 30s scrapeTimeout: 5s prober: url: blackbox-exporter.monitoring.svc:9115 scheme: http module: tcp_connect targets: staticConfig: static: - redis-service.default.svc.cluster.local:6379 - 192.168 .1 .10 :6379 --- apiVersion: monitoring.coreos.com/v1 kind: Probe metadata: name: probe-mysql namespace: monitoring spec: jobName: probe-mysql interval: 30s scrapeTimeout: 5s prober: url: blackbox-exporter.monitoring.svc:9115 scheme: http module: tcp_connect targets: staticConfig: static: - mysql-service.default.svc.cluster.local:3306 - 192.168 .1 .20 :3306
17.3.6ScrapeConfig ScrapeConfig 和 ServiceMonitor / PodMonitor 的区别在于:
ServiceMonitor / PodMonitor / Probe → 针对 Kubernetes 应用、Pod、外部探测,算是“高级抽象”。
ScrapeConfig → 原生 Prometheus 的 scrape_configs 的 CRD 版本,灵活度高,可以配置任何 Prometheus 支持的采集方式(包括文件发现、Consul、静态目标等)。
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 apiVersion: monitoring.coreos.com/v1alpha1 kind: ScrapeConfig metadata: name: redis-exporter-scrape namespace: monitoring labels: app.kubernetes.io/name: scrapeconfig app.kubernetes.io/component: monitoring app.kubernetes.io/part-of: prometheus spec: jobName: redis-exporter scrapeInterval: 30s scrapeTimeout: 10s honorLabels: true scheme: http metricsPath: /scrape staticConfigs: - targets: - redis://redis.default:6379 labels: env: prod exporter: redis relabelings: - sourceLabels: [__address__ ] targetLabel: __param_target - sourceLabels: [__param_target ] targetLabel: instance - targetLabel: __address__ replacement: redis-exporter.monitoring:9121
17.3.7Relabeling详解 17.3.8AlertmanagerConfig 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 apiVersion: monitoring.coreos.com/v1alpha1 kind: AlertmanagerConfig metadata: name: alertmanager-config-example namespace: monitoring spec: route: receiver: default-receiver groupBy: ['alertname' , 'severity' ] groupWait: 30s groupInterval: 5m repeatInterval: 3h routes: - matchers: - name: severity value: critical matchType: = receiver: critical-receiver continue: false receivers: - name: default-receiver emailConfigs: - to: ops-team@example.com from: alertmanager@example.com smarthost: smtp.example.com:587 authUsername: alertmanager@example.com authPassword: name: smtp-secret key: password - name: critical-receiver webhookConfigs: - url: 'http://alert-webhook-service.monitoring.svc:8080/' sendResolved: true
17.3.9PrometheusRule PrometheusRule 是 Prometheus Operator 提供的一种 CRD,用于集中管理告警规则(alerting rules)和录制规则(recording rules)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: example-prometheus-rules namespace: monitoring labels: role: alert-rules prometheus: k8s spec: groups: - name: example.rules interval: 30s rules: - alert: HighErrorRate expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05 for: 10m labels: severity: warning annotations: summary: "High error rate detected" description: "More than 5% of requests are failing with 5xx errors on {{ $labels.job }} for 10m."
17.3.10Prometheus资源分类 安装:Operator、Prometheus、Alertmanager、Grafana
监控:ServiceMonitor、Probe、PodMonitor、ScrapeConfig
告警:PrometheusRule
通知:AlertmanagerConfig
17.4Prometheus安装
笔记中选择Kube-Prometheus Stack的方式进行安装。
Kube-Prometheus项目地址:https://github.com/prometheus-operator/kube-prometheus/
首先需要通过该项目地址,找到和自己Kubernetes版本对应的Kube Prometheus Stack的版本:(我的k8s集群版本是v1.31.4,选择release-0.14、release-0.15、release-0.16都可以,我这里选择release-0.14版本)
1. 下载对应的release-0.14版本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 创建目录:17-prometheus是学习本章节目录,监控章节的所有文件都在该目录中完成 [root@k8s-master01 pra] mkdir -p /root/pra/17-prometheus # 进入目录 [root@k8s-master01 pra]# cd 17-prometheus/ # 拉取对应版本的文件包 [root@k8s-master01 17-prometheus]# git clone -b release-0.14 https://github.com/prometheus-operator/kube-prometheus.git Cloning into 'kube-prometheus'... remote: Enumerating objects: 20464, done. remote: Counting objects: 100% (3886/3886), done. remote: Compressing objects: 100% (262/262), done. remote: Total 20464 (delta 3715), reused 3700 (delta 3605), pack-reused 16578 (from 1) Receiving objects: 100% (20464/20464), 12.32 MiB | 3.03 MiB/s, done. Resolving deltas: 100% (14089/14089), done.
如果上述clone命令无法拉取也可以下载压缩包,上传到服务器的目录中:
1 2 3 4 [root@k8s-master01 17-prometheus]# git clone -b release-0.14 https://github.com/prometheus-operator/kube-prometheus.git Cloning into 'kube-prometheus'... fatal: unable to access 'https://github.com/prometheus-operator/kube-prometheus.git/': Failed connect to github.com:443; Connection timed out # 如果遇到网络问题无法在线拉取可以参考下图解决
进入目标目录:
1 2 3 4 5 6 7 [root@k8s-master01 17-prometheus]# ll total 4 drwxr-xr-x 12 root root 4096 Nov 12 17:38 kube-prometheus # 进入manifests目录,所有的安装文件都在manifests目录中 [root@k8s-master01 17-prometheus]# cd kube-prometheus/manifests
2.安装Prometheus Operator: 1 2 3 4 5 6 7 8 9 10 11 12 [root@k8s-master01 manifests]# kubectl create -f setup/ customresourcedefinition.apiextensions.k8s.io/alertmanagerconfigs.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/prometheusagents.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/scrapeconfigs.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com created customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com created namespace/monitoring created
安装Prometheus 核心组件:
要修改镜像地址的文件包含下面所有文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 路径:~/kube-prometheus-release-0.14/manifests [root@k8s-master01 manifests]# grep "image:" *.yaml alertmanager-alertmanager.yaml: image: quay.io/prometheus/alertmanager:v0.27.0 blackboxExporter-deployment.yaml: image: quay.io/prometheus/blackbox-exporter:v0.25.0 blackboxExporter-deployment.yaml: image: ghcr.io/jimmidyson/configmap-reload:v0.13.1 blackboxExporter-deployment.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.18.1 grafana-deployment.yaml: image: grafana/grafana:11.2.0 kubeStateMetrics-deployment.yaml: image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.13.0 kubeStateMetrics-deployment.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.18.1 kubeStateMetrics-deployment.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.18.1 nodeExporter-daemonset.yaml: image: quay.io/prometheus/node-exporter:v1.8.2 nodeExporter-daemonset.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.18.1 prometheusAdapter-deployment.yaml: image: registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.12.0 prometheusOperator-deployment.yaml: image: quay.io/prometheus-operator/prometheus-operator:v0.76.2 prometheusOperator-deployment.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.18.1 prometheus-prometheus.yaml: image: quay.io/prometheus/prometheus:v2.54.1
修改alertmanager的副本数和镜像下载地址:
1 2 3 4 5 #在创建之前需要决定你集群的副本数,假设我这里是测试环境,所以只创建一个副本,如果是生产环境建议至少3个副本 #alertmanager副本数在alertmanager-alertmanager.yaml配置文件中修改 #主要是副本数和镜像下载地址的配置: image: quay.io/prometheus/alertmanager:v0.27.0 #如果自己有镜像仓库可以改为自己的仓库地址,下图已经修改为我自己的镜像仓库地址了 replicas: 3 #根据实际情况修改副本的数量,我配置的是1
修改prometheus的副本数和镜像下载地址:
1 2 3 4 5 # 在创建之前需要决定你集群的副本数,假设我这里是测试环境,所以只创建一个副本,如果是生产环境建议至少3个副本 # prometheus副本数在 prometheus-prometheus.yaml配置文件中修改 # 主要是副本数和镜像下载地址的配置: image: quay.io/prometheus/alertmanager:v0.27.0 #如果自己有镜像仓库可以改为自己的仓库地址,下图已经修改为我自己的镜像仓库地址了 replicas: 3 #根据实际情况修改副本的数量,我配置的是1
修改kubeStateMetrics-deployment.yaml配置文件中镜像的下载地址:
1 # kubeStateMetrics-deployment.yaml配置文件中的镜像地址我改为我自己的仓库地址,事先已经将镜像同步到自己的仓库中
接下来安装prometheus的技术栈:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # 注意所在目录manifests [root@k8s-master01 manifests]# pwd /root/pra/17-prometheus/kube-prometheus/manifests # 安装prometheus技术栈 [root@k8s-master01 manifests]# kubectl create -f . [root@k8s-master01 manifests]# kubectl get po -n monitoring NAME READY STATUS RESTARTS AGE alertmanager-main-0 0/2 Init:0/1 0 9m54s blackbox-exporter-75c7985cb8-xkxrs 0/3 ContainerCreating 0 11m grafana-664dd67585-mh7tb 0/1 ImagePullBackOff 0 11m kube-state-metrics-bbcd9ff4f-8c5vq 0/3 ContainerCreating 0 11m node-exporter-7b428 2/2 Running 0 11m node-exporter-m2g8z 2/2 Running 0 11m node-exporter-nvpz5 2/2 Running 0 11m node-exporter-w7lrs 2/2 Running 0 11m node-exporter-wwtnm 0/2 ContainerCreating 0 11m prometheus-adapter-77f8587965-5x7bn 0/1 ImagePullBackOff 0 11m prometheus-adapter-77f8587965-wgp55 0/1 ImagePullBackOff 0 11m prometheus-k8s-0 0/2 Init:0/1 0 9m54s prometheus-operator-6f9479b5f5-4zpfm 2/2 Running 0 11m
虽然上述三个配置文件修改了镜像的下载地址,但是查看pod会发现还是会有一些pod由于镜像地址的问题无法启动pod,接下继续修改无法启动pod的那些镜像地址:
思路一:通过describe查看无法启动的pod使用的镜像是什么,然后利用github同步到我自己的阿里云仓库中,在把配置文件中的镜像地址修改为我自己的阿里云仓库地址。(这里就不演示了)
1 2 3 4 5 # 下面是几个pod的资源配置所在的文件 blackbox-exporter-75c7985cb8-xkxrs的镜像在blackboxExporter-deployment.yaml文件中 grafana-664dd67585-mh7tb 的镜像在grafana-deployment.yaml文件中 prometheus-adapter-77f8587965-5x7bn的镜像在prometheusAdapter-deployment.yaml文件中 node-exporter-w7lrs的镜像在nodeExporter-daemonset.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 # 用prometheus-adapter-77f8587965-5x7bn举例 [root@k8s-master01 manifests]# kubectl edit pod -n monitoring prometheus-adapter-77f8587965-5x7bn # 找到spec.containers.image参数,修改为自己的镜像仓库(前提是已经将镜像同步到自己的仓库中了) 42 image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/prometheus-adapter:v0.12.0 # 修改后保存退出,程序会自动更新配置,再次检查pod,已经正常运行 [root@k8s-master01 manifests]# kubectl get pod -n monitoring NAME READY STATUS RESTARTS AGE alertmanager-main-0 2/2 Running 0 15h blackbox-exporter-75c7985cb8-xkxrs 3/3 Running 0 15h grafana-664dd67585-mh7tb 1/1 Running 0 15h kube-state-metrics-bbcd9ff4f-8c5vq 3/3 Running 0 15h node-exporter-7b428 2/2 Running 0 15h node-exporter-m2g8z 2/2 Running 0 15h node-exporter-nvpz5 2/2 Running 0 15h node-exporter-w7lrs 2/2 Running 0 15h node-exporter-wwtnm 2/2 Running 0 15h prometheus-adapter-77f8587965-5x7bn 1/1 Running 0 15h prometheus-adapter-77f8587965-wgp55 1/1 Running 0 15h prometheus-k8s-0 2/2 Running 0 12h prometheus-operator-6f9479b5f5-4zpfm 2/2 Running 0 15h # 让我们来详细解释一下这些 Pod 的功能和作用: 1.prometheus-operator-6f9479b5f5-4zpfm:这是整个 Prometheus 监控栈的控制器,负责管理和维护 Prometheus 相关的自定义资源(CRD),自动化部署和管理 Prometheus 实例、配置等 2.prometheus-k8s-0:核心的 Prometheus 服务器实例,负责收集、存储时序数据,执行数据查询和告警规则评估 3.alertmanager-main-0:负责告警管理和通知,处理来自 Prometheus 的告警,提供告警分组、抑制、静默等功能,支持多种通知方式(邮件、Slack、webhook等) 4.grafana-664dd67585-mh7tb:可视化平台,提供丰富的数据可视化界面,支持创建各种监控面板,可以展示 Prometheus 采集的数据 5.node-exporter-*(多个实例):部署在每个节点上的数据采集器,收集主机级别的监控指标,如:CPU、内存、磁盘、网络等系统层面的数据 6.kube-state-metrics-bbcd9ff4f-8c5vq:收集 Kubernetes 对象的状态指标,监控 Pod、Deployment、StatefulSet 等资源的状态,提供集群层面的监控数据 7.blackbox-exporter-75c7985cb8-xkxrs:用于探测服务的可用性,支持 HTTP、HTTPS、DNS、TCP、ICMP 等协议探测,可以监控服务的响应时间、可用性等 8.prometheus-adapter-77f8587965-*(两个实例):实现了自定义指标 API,使 Kubernetes HPA 可以使用 Prometheus 指标进行自动扩缩容,将 Prometheus 指标转换为 Kubernetes 可用的指标格式 # 这些组件协同工作形成了一个完整的监控体系: node-exporter 收集每个节点的系统级别资源的数据。 kube-state-metrics 采集 Kubernetes 资源的状态数据。 blackbox-exporter 用于探测外部服务的可用性。 Prometheus :采集和存储指标数据。 Alertmanager 处理和分发告警。 Grafana 提供指标的可视化展示。 Prometheus Operator 管理整个监控栈,管理和部署 Prometheus 及其相关组件。 Prometheus Adapter 将 Prometheus 指标数据暴露给 Kubernetes HPA,用于自动伸缩。使监控指标可用于集群的自动化运维。 # 这样的架构既能监控基础设施,也能监控应用服务,同时支持告警和可视化,是一个非常完整的监控解决方案。
3.访问Grafana和Prometheus 新版本添加了NetworkPolicy,导致无法访问Grafana和Prometheus等服务,执行删除即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@k8s-master01 manifests]# kubectl delete networkpolicy --all -n monitoring networkpolicy.networking.k8s.io "alertmanager-main" deleted networkpolicy.networking.k8s.io "blackbox-exporter" deleted networkpolicy.networking.k8s.io "grafana" deleted networkpolicy.networking.k8s.io "kube-state-metrics" deleted networkpolicy.networking.k8s.io "node-exporter" deleted networkpolicy.networking.k8s.io "prometheus-adapter" deleted networkpolicy.networking.k8s.io "prometheus-k8s" deleted networkpolicy.networking.k8s.io "prometheus-operator" deleted # 再次查看已经没有相关资源 [root@k8s-master01 manifests]# kubectl get networkpolicy -n monitoring No resources found in monitoring namespace.
将alertmanager-main、grafana、prometheus-k8s三个Service改成NodePort类型:
将Grafana的Service改成NodePort类型:
1 2 3 4 5 6 7 8 9 10 11 12 [root@k8s-master01 manifests]# kubectl edit svc -n monitoring grafana apiVersion: v1 kind: Service ... selector: app.kubernetes.io/component: grafana app.kubernetes.io/name: grafana app.kubernetes.io/part-of: kube-prometheus sessionAffinity: None type: NodePort #将type的原值ClusterIP改为NodePort status: loadBalancer: {}
查看Grafana的Service暴露的端口,通过该端口访问grafana:
1 2 3 4 #grafana的NodePort为30391 [root@k8s-master01 manifests]# kubectl get svc -n monitoring grafana NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana NodePort 10.96.250.130 <none> 3000:30391/TCP 20h
之后可以通过任意一个安装了kube-proxy服务的节点IP+32293 端口即可访问到Grafana,如果浏览器无法访问执行删除网络策略:
1 2 3 4 5 6 7 8 9 10 # 删除网络策略 [root@k8s-master01 manifests]# kubectl delete networkpolicy --all -n monitoring networkpolicy.networking.k8s.io "alertmanager-main" deleted networkpolicy.networking.k8s.io "blackbox-exporter" deleted networkpolicy.networking.k8s.io "grafana" deleted networkpolicy.networking.k8s.io "kube-state-metrics" deleted networkpolicy.networking.k8s.io "node-exporter" deleted networkpolicy.networking.k8s.io "prometheus-adapter" deleted networkpolicy.networking.k8s.io "prometheus-k8s" deleted networkpolicy.networking.k8s.io "prometheus-operator" deleted
Grafana默认登录的账号密码为admin/admin。
首次登录会提示更改密码,如果不修改点击skip跳过即可。
简单体验导入监控模板:
访问grafana页面,http://192.168.0.200:32293/?orgId=1
通过https://grafana.com/grafana/dashboards官方地址,输入关键字[Linux主机详情] 找适合的监控模板:
复制模板的连接,在http://192.168.0.200:32293/?orgId=1中导入模板:
复制模板连接:
在grafana控制台导入-输入模板连接后点击[加载]:
导入后监控数据显示如下:
可以创建不同类型的文件夹,在文件夹中导入监控模板:
然后相同的方式更改Prometheus的Service为NodePort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@k8s-master01 manifests]# kubectl edit svc -n monitoring prometheus-k8s # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: Service metadata: creationTimestamp: "2024-11-12T10:34:08Z" labels: app.kubernetes.io/component: prometheus ... sessionAffinityConfig: clientIP: timeoutSeconds: 10800 type: NodePort #修改type的值为NodePort status: loadBalancer: {} [root@k8s-master01 manifests]# kubectl get svc -n monitoring prometheus-k8s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE prometheus-k8s NodePort 10.96.250.138 <none> 9090:31470/TCP,8080:30887/TCP 22h
通过31470 端口即可访问到Prometheus的WebUI:
默认安装完成后,会有几个告警,先忽略。
该页面默认是不需要登录的,如果需要在生产环境访问,可以利用ingress代理配置账号密码!
17.5云原生和非云原生应用的监控流程 1.Prometheus的数据来源 基于云原生理念开发的程序会暴露 /metrics接口(中文意思是度量,指标的意思),提供各项监控指标的数据
非云原生开发的程序需要安装 Exporter (中文意思是出口,输出),提供各项监控指标的数据
常用的Exporter工具
类型
Exporter
数据库
MySQL Exporter, Redis Exporter, MongoDB Exporter, MSSQL Exporter
硬件
Apcupsd Exporter,IoT Edison Exporter, IPMI Exporter, Node Exporte
消息队列
Beanstalkd Exporter, Kafka Exporter, NSQ Exporter, RabbitMQ Exporter
存储
Ceph Exporter, Gluster Exporter, HDFS Exporter, ScaleIO Exporter
HTTP服务
Apache Exporter, HAProxy Exporter, Nginx Exporter
API服务
AWS ECS Exporter, Docker Cloud Exporter, Docker Hub Exporter, GitHub Exporter
监控系统
Collectd Exporter, Graphite Exporter, InfluxDB Exporter, Nagios Exporter, SNMP Exporter
其他
Blackbox Exporter, JIRA Exporter, Jenkins Exporter, Confluence Exporter
2.Prometheus如何拿到监控数据
当云原生应用metrics接口和 非云原生exporter 提供监控数据,Prometheus是如何拿到这些监控数据的呢?
利用一个叫ServiceMonitor 的资源来拿到监控数据。下面介绍ServiceMonitor :
ServiceMonitor 是 Prometheus Operator 提供的一个自定义资源(Custom Resource Definition, CRD),专门用于在 Kubernetes 中配置和管理 Prometheus 监控目标的方式 。ServiceMonitor 通过声明式配置,简化了 Kubernetes 环境中的监控设置,不再需要手动修改 Prometheus 的配置文件。它可以帮助 Prometheus 自动发现 Kubernetes 中的 Service,从而采集应用的监控数据。
ServiceMonitor配置解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # 下面是一个基本的配置,能满足大多数场景,让我们来解析每个参数的意思 kind: ServiceMonitor #声明这是一个 ServiceMonitor 资源对象 apiVersion: monitoring.coreos.com/v1 #指定使用 monitoring.coreos.com/v1 API 版本 metadata: #定义资源的元数据,包含一些与资源相关的基本信息,如名称、命名空间和标签。 name: es-monitor #定义这个ServiceMonitor资源的名字是es-monitor namespace: monitoring #指定该资源将部署在 "monitoring" 命名空间中 labels: #为该ServiceMonitor添加标签 app: elasticsearch #标签的具体key和value k8s-app: elasticsearch-exporter #标签的具体key和value spec: # 定义了 ServiceMonitor 的详细配置,用来指定如何发现服务和采集数据。 endpoints: #定义了服务暴露的监控指标的端点配置(也就是被监控端的配置)。Prometheus 通过这些信息来获取服务的监控数据。 - port: http #指定要监控的端口名称为 "http";Prometheus 会从名为 http 的端口拉取数据。这个端口指向的是 Service 中定义的端口名称(portName) honorLabels: true #设置为 true,表示保留原始标签,Prometheus 会保留从服务暴露的 metrics 端点拉取到的原始标签,这对于进一步的数据分析和查询非常有用,确保不会丢失重要的标签信息。 path: /metrics #指定获取指标数据的接口路径为 "/metrics",通常这是所有支持 Prometheus 格式的服务会暴露的指标路径。 scheme: http #该配置指定了访问端点时使用 HTTP 协议。如果你的服务支持 HTTPS,则可以将其设置为 https。 interval: 10s #指定 Prometheus 每次拉取指标的时间间隔。 jobLabel: es-exporter #Prometheus 使用这个标签 es-exporter 来标识这个采集任务。这对于多任务或多作业的环境中,帮助区分不同的监控任务。也可以不配置该参数 selector: #指定Prometheus 从哪些 Service 中采集数据,类似于标签选择器。 matchLabels: #标签选择器,也就是从下面定义的标签中查找service来采集数据 app: elasticsearch # namespaceSelector: #命名空间选择器,也就是定义从哪个命名空间查找service matchNames: #定义命名空间 - monitoring #命名空间的名字是monitoring,意思是从该命名空间匹配带标签是 app: elasticsearch 的service采集数据
3.Prometheus监控流程
第十八章、云原生监控Prometheus实践 18.1云原生应用监控-Etcd Etcd属于云原生应用,是k8s核心组件之一,它自带了/metrics接口:
1 2 3 4 5 6 7 # 在安装了etcd组件的服务器上 查看etcd服务的端口,以k8s-master01为例: [root@k8s-master01 manifests]# netstat -lntup|grep etcd tcp 0 0 192.168.0.200:2379 0.0.0.0:* LISTEN 1084/etcd tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 1084/etcd tcp 0 0 192.168.0.200:2380 0.0.0.0:* LISTEN 1084/etcd # etcd 目前默认使用2379端口提供HTTP API服务,2380端口和peer通信(这两个端口已经被IANA(互联网数字分配机构)官方预留给etcd)。 即etcd默认使用2379端口对外为客户端提供通讯,使用端口2380来进行服务器间内部通讯。 # 如果是监控etcd指标,则需要跟2379端口通信
访问etcd的metrics接口:
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 # 本地访问可以使用http,但是Prometheus不能用127.0.0.1,只能通过192.168.0.200:2379访问,所以需要带着etcd的证书访问才会有数据返回 # 本地访问 [root@k8s-master01 manifests]# curl 127.0.0.1:2379/metrics .... # HELP etcd_debugging_disk_backend_commit_write_duration_seconds The latency distributions of commit.write called by bboltdb backend. # TYPE etcd_debugging_disk_backend_commit_write_duration_seconds histogram etcd_debugging_disk_backend_commit_write_duration_seconds_bucket{le="0.001"} 91885 etcd_debugging_disk_backend_commit_write_duration_seconds_bucket{le="0.002"} 155332 etcd_debugging_disk_backend_commit_write_duration_seconds_bucket{le="0.004"} 215254 # 证书访问 [root@k8s-master01 etcd-service-monitor]# curl -s --cacert /etc/kubernetes/pki/etcd/etcd-ca.pem --cert /etc/kubernetes/pki/etcd/etcd.pem --key /etc/kubernetes/pki/etcd/etcd-key.pem https://192.168.0.200:2379/metrics # 如何查找自己etcd的证书? # 证书的位置可以在 Etcd 配置文件中获得(注意配置文件的位置,不同的集群位置可能不同, # Kubeadm 安装方式可能会在/etc/kubernetes/manifests/etcd.yml 中): # 二进制安装方式,执行systemctl status etcd命令,找到配置文件--config-file=/etc/etcd/etcd.config.yml # 在/etc/etcd/etcd.config.yml文件中查看证书的路径 # 可以使用命令过滤出来: [root@k8s-master01 etcd-service-monitor]# grep -E "key-file|cert-file|trusted-ca-file" /etc/etcd/etcd.config.yml cert-file: '/etc/kubernetes/pki/etcd/etcd.pem' key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem' trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem' cert-file: '/etc/kubernetes/pki/etcd/etcd.pem' key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem' trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem' # 也可以cat 配置文件查看: [root@k8s-master01 manifests]# cat /etc/etcd/etcd.config.yml
使用带参数的指令获取etcd监控指标:
1 2 3 4 5 6 7 8 9 [root@k8s-master01 manifests]# curl -s --cacert /etc/kubernetes/pki/etcd/etcd-ca.pem --cert /etc/kubernetes/pki/etcd/etcd.pem --key /etc/kubernetes/pki/etcd/etcd-key.pem https://192.168.0.200:2379/metrics # 结果如下: .... # TYPE process_open_fds gauge process_open_fds 335 # HELP process_resident_memory_bytes Resident memory size in bytes. # TYPE process_resident_memory_bytes gauge promhttp_metric_handler_requests_total{code="200"} 6 promhttp_metric_handler_requests_total{code="500"} 0
二进制安装的etcd没有自动为我们创建etcd的service,需要我们手动创建etcd的service:
1.创建etcd的service 针对云原生应用etcd,需要创建Service,Endpoints 和ServiceMonitor资源
创建Etcd的Service和Endpoints :
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 # 编写资源配置 [root@k8s-master01 etcd-service-monitor]# vim etcd-service.yaml # 假如下面配置内容 apiVersion: v1 # Service的API版本 kind: Service # 定义资源的类型,这里是Service metadata: # 定义资源的元数据 name: etcd-monitoring # Service的名称,如果需要手动配置endpoints,这个service名称必须与endpoints的名称相同 namespace: kube-system # 定义资源所在的命名空间。 labels: # 定义资源的标签,这里建议和Endpoints 资源的标签保持一致 k8s-app: etcd component: etcd spec: # 定义资源的具体规格 type: ClusterIP # 集群内部访问的service类型 ports: # 定义Service的端口 - name: metrics # metrics端口名称,需要和后面的 ServiceMonitor 保持一致 port: 2379 # 定义Service暴露的端口 protocol: TCP # 使用TCP协议,默认值,不加该参数也可以 targetPort: 2379 # etcd服务的实际监听端口,和Endpoints.subsets.ports.port的端口保持一致 --- # 配套的Endpoints配置(如果etcd是静态部署的(比如直接部署在主机上),需要手动配置Endpoints) apiVersion: v1 # Endpoints的API版本 kind: Endpoints # Endpoints类型 ,创建的资源类型是Endpoints metadata: #定义资源的元数据 name: etcd-monitoring # Endpoints的名称,必须与Service的名称相同 namespace: kube-system # Endpoints所在的命名空间 ,必须与Service的命名空间相同。 labels: # Endpoints的标签,最好与Service的标签相同 k8s-app: etcd component: etcd subsets: # Endpoints的子集,定义了每个Endpoint的地址和端口,必须与Service的端口相同。 - addresses: # 定义Endpoint的地址,可以是Pod的IP地址,也可以是其他服务或节点的IP地址 - ip: "192.168.0.200" # 替换为实际的etcd节点IP,有几个节点就写几个IP - ip: "192.168.0.201" - ip: "192.168.0.202" ports: # 定义Endpoint的端口,必须与Service的端口相同。 - name: metrics # metrics端口名称,和service中.sepc.ports.name字段保持一致 port: 2379 # 以实际外部服务etcd监听端口为准 protocol: TCP # 使用TCP协议,默认值,不加该参数也可以 ------------------- 在手动创建Service和Endpoints时需要注意以下问题: Service.metadata.name 和 Endpoints.metadata.name 的值必须相同 Service.metadata.namespace 和 Endpoints.metadata.namespace 的值必须相同 Service.metadata.labels 和 Endpoints.metadata.labels 的值可以不相同,但是为了方便建议相同 Service.spec.ports.name 和 Endpoints.subsets.ports.name 的值必须保持一致 Service.spec.ports.targetPort 和 Endpoints.subsets.ports.port 的值必须保持一致 Service.spec.ports.protocol 和 Endpoints.subsets.ports.protocol 的值必须保持一致 Endpoints.subsets.ports.port的端口是由实际服务监听的端口号决定,例如MySQL实际监听3306端口,这个就应该配置3306 Service.spec.ports.targetPort的端口号由Endpoints.subsets.ports.port决定,所以两个保持一致 Service.spec.ports.port是自定义的service对外暴露的端口号,这个可以自己定义,也可以和targetPort保持一致 -------------------
创建该资源并查看 Service 的 ClusterIP:
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 # 创建前先看下kube-system命名空间是没有相应的资源 [root@k8s-master01 etcd-service-monitor]# kubectl get service -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 144d kubelet ClusterIP None <none> 10250/TCP,10255/TCP,4194/TCP 2d20h metrics-server ClusterIP 10.96.78.88 <none> 443/TCP 144d snapshot-controller ClusterIP 10.96.85.201 <none> 80/TCP 51d # 创建资源 [root@k8s-master01 etcd-service-monitor]# kubectl create -f etcd-service.yaml service/etcd-monitoring created endpoints/etcd-monitoring created # 创建后可以看到在 kube-system命名空间etcd-monitoring 名字的service [root@k8s-master01 etcd-service-monitor]# kubectl get service -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE etcd-monitoring ClusterIP 10.96.8.216 <none> 2379/TCP 32s kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 144d kubelet ClusterIP None <none> 10250/TCP,10255/TCP,4194/TCP 2d20h metrics-server ClusterIP 10.96.78.88 <none> 443/TCP 144d snapshot-controller ClusterIP 10.96.85.201 <none> 80/TCP 51d [root@k8s-master01 etcd-service-monitor]# kubectl get -f etcd-service.yaml NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/etcd-monitoring ClusterIP 10.96.8.216 <none> 2379/TCP 6s NAME ENDPOINTS AGE endpoints/etcd-monitoring 192.168.0.200:2379,192.168.0.201:2379,192.168.0.202:2379 6s
通过ClusterIP进行访问测试:
1 2 3 4 5 6 [root@k8s-master01 etcd-service-monitor]# curl -s --cacert /etc/kubernetes/pki/etcd/etcd-ca.pem --cert /etc/kubernetes/pki/etcd/etcd.pem --key /etc/kubernetes/pki/etcd/etcd-key.pem https://10.96.8.216:2379/metrics -k|tail -5 # HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code. # TYPE promhttp_metric_handler_requests_total counter promhttp_metric_handler_requests_total{code="200"} 2 promhttp_metric_handler_requests_total{code="500"} 0 promhttp_metric_handler_requests_total{code="503"} 0
接下来创建 Etcd 证书的 Secret(证书路径根据实际环境进行更改):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 创建etcd的secret,将这个secret挂载到prometheus的pod中,因为prometheus请求etcd的metrics接口需要证书,secret有命名空间隔离性,需要跟prometheus的pod在同一个命名空间中 [root@k8s-master01 etcd-service-monitor]# kubectl create secret generic etcd-ssl \ --from-file=/etc/kubernetes/pki/etcd/etcd-ca.pem \ --from-file=/etc/kubernetes/pki/etcd/etcd.pem \ --from-file=/etc/kubernetes/pki/etcd/etcd-key.pem -n monitoring # 命令解释: kubectl:Kubernetes 命令行工具,用于与 Kubernetes API 进行交互。 create secret:kubectl 子命令,用于创建 Secret 资源。Secret 用于在 Kubernetes 中安全地存储敏感信息,比如密码、证书、密钥等。 generic:表示创建一个“通用”类型的 Secret(即 Opaque 类型),可以存储任意数据。 etcd-ssl:创建的Secret名称,名字是etcd-ssl。这个名称用于标识这个 Secret,后续引用这个 Secret 时可以使用该名称。 -n monitoring::指定 Secret 创建到的命名空间(namespace)。在这里,将 Secret 创建在 monitoring 命名空间下,这样只有该命名空间中的 Pod 或应用能够引用和访问此 Secret --from-file:用于将文件中的内容作为 Secret 的数据存储。可以多次使用此参数添加多个文件。 etcd-ca.pem 文件是 etcd 的 CA(Certificate Authority,证书颁发机构)证书,用于验证证书链的可信度 etcd.pem 文件是 etcd 服务端的 SSL 证书,用于身份验证。 etcd-key.pem 文件是 etcd 的私钥,用于加密和解密与 etcd 的 SSL 通信。
将证书挂载至 Prometheus 容器(由于 Prometheus 是 Operator 部署的,所以只需要修改Prometheus 资源即可):
1 2 3 4 5 6 7 8 9 10 # Prometheus资源是 Prometheus Operator 所管理的自定义资源(Custom Resource,CR) [root@k8s-master01 etcd-service-monitor]# kubectl get prometheus -n monitoring NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE k8s 2.54.1 1 1 True True 3d # 编辑名字是k8s的prometheus资源 [root@k8s-master01 etcd-service-monitor]# kubectl edit prometheus k8s -n monitoring # 在spec级别下添加证书配置 secrets: - etcd-ssl
保存退出后,Prometheus 的 Pod (prometheus-k8s-0)会自动重启,重启完成后,查看证书是否挂载(任意一个Prometheus 的 Pod 均可):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@k8s-master01 etcd-service-monitor]# kubectl get po -n monitoring NAME READY STATUS RESTARTS AGE alertmanager-main-0 2/2 Running 4 (12m ago) 3d3h blackbox-exporter-75c7985cb8-xkxrs 3/3 Running 6 (12m ago) 3d3h grafana-75dcfd79-sk29h 1/1 Running 1 (12m ago) 2d5h kube-state-metrics-bbcd9ff4f-8c5vq 3/3 Running 7 (9m34s ago) 3d3h node-exporter-7b428 2/2 Running 2 (11m ago) 3d3h node-exporter-m2g8z 2/2 Running 2 (11m ago) 3d3h node-exporter-nvpz5 2/2 Running 2 (11m ago) 3d3h node-exporter-w7lrs 2/2 Running 2 (12m ago) 3d3h node-exporter-wwtnm 2/2 Running 4 (12m ago) 3d3h prometheus-adapter-77f8587965-5x7bn 1/1 Running 4 (10m ago) 3d3h prometheus-adapter-77f8587965-wgp55 1/1 Running 2 (9m38s ago) 3d3h prometheus-k8s-0 0/2 Init:0/1 0 2s prometheus-operator-6f9479b5f5-4zpfm 2/2 Running 3 (9m48s ago) 3d3h # 待pod重启完成,进入prometheus-k8s-0的pod中验证证书是否挂载成功: [root@k8s-master01 etcd-service-monitor]# kubectl exec -ti -n monitoring prometheus-k8s-0 -c prometheus -- sh /prometheus $ /prometheus $ ls -l /etc/prometheus/secrets/etcd-ssl/ #证书已经成功挂载 total 0 lrwxrwxrwx 1 root 2000 18 Nov 15 13:39 etcd-ca.pem -> ..data/etcd-ca.pem lrwxrwxrwx 1 root 2000 19 Nov 15 13:39 etcd-key.pem -> ..data/etcd-key.pem lrwxrwxrwx 1 root 2000 15 Nov 15 13:39 etcd.pem -> ..data/etcd.pem
2.创建ServiceMonitor 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 # 配置ServiceMonitor并介绍配置参数 [root@k8s-master01 etcd-service-monitor]# vim etcd-servicemonitor.yaml # ServiceMonitor资源配置内容如下: kind: ServiceMonitor #定义资源类型为 ServiceMonitor,这是用于 Prometheus Operator 中监控服务的资源类型。 apiVersion: monitoring.coreos.com/v1 #该字段指定了 API 的版本,monitoring.coreos.com/v1 是 ServiceMonitor 的标准 API 版本。 metadata: #定义该资源的元数据部分,用于定义资源的名称和标签命名空间等信息。 name: etcd-servicemonitor #定义该 ServiceMonitor 资源的名称为 etcd-servicemonitor。 namespace: monitoring #定义该 ServiceMonitor 资源所在的命名空间为 monitoring。 labels: #定义该 ServiceMonitor 资源的标签,用于标识该资源。 app: etcd-servicemonitor #标签的键为 app,值为 etcd-servicemonitor。Prometheus(由 Prometheus Operator 管理)通过 .spec.serviceMonitorSelector 字段来决定:“我只监控那些带有特定标签的 ServiceMonitor” 。因为在prometheus资源中"serviceMonitorSelector: {}" 定义了空选择器,空选择器匹配所有资源。(kubectl get prometheus -n monitoring k8s -oyaml|grep serviceMonitorSelector) 如果Prometheus的.spec.serviceMonitorSelector不是空选择器,那么ServiceMonitor这里定义的标签就要和Prometheus的.spec.serviceMonitorSelector中定义的标签保持一致。 spec: #定义该 ServiceMonitor 资源的具体配置。 jobLabel: etcd #指定从 Service 的标签中获取的作业名称标签,使用 Service 中 key 为 "etcd" 的标签值作为 job 名称,etcd这个值是Service中定义的标签key。 namespaceSelector: #命名空间选择器,用于指定监控哪些命名空间下的 Service。 matchNames: #名字空间匹配列表,从该列表中定义的命名空间下找目标 Service。 - kube-system #找kube-system 命名空间下的 Service。 selector: #选择器,用于指定监控哪些 Service。 matchLabels: #标签匹配器 etcd: monitoring #找标签是app=etcd的Service。也就是从namespaceSelector.matchNames中定义的命名空间下,选择标签是app=etcd的Service。 endpoints: #定义监控的目标端点。 - port: metrics #这个port字段的值对应 Service.spec.ports.name的值保持一致,必须与 Service 的定义一致。 interval: 30s #配置 Prometheus 拉取该服务指标的间隔时间,表示每 30 秒拉取一次。 scheme: https #设置请求协议为 https。如果其他服务不需要证书验证,可以设置为 http。 tlsConfig: #配置 TLS 证书验证。 caFile: /etc/prometheus/secrets/etcd-ssl/etcd-ca.pem #指定 CA 证书文件的路径, 这个路径Prometheus 容器内的路径,而不是 Kubernetes 主机的路径。 certFile: /etc/prometheus/secrets/etcd-ssl/etcd.pem #指定客户端证书文件的路径。这个路径Prometheus 容器内的路径,而不是 Kubernetes 主机的路径。 keyFile: /etc/prometheus/secrets/etcd-ssl/etcd-key.pem #指定客户端私钥文件的路径。这个路径Prometheus 容器内的路径,而不是 Kubernetes 主机的路径。 insecureSkipVerify: true #是否跳过证书验证,true 表示跳过,false 表示不跳过。如果你在开发/测试环境中使用自签名证书,这个可以设置为 true,但在生产环境中建议为 false。 ---------------------------------------------- # 配置ServiceMonitor资源时产生的疑问解答: 背景:prometheus相关的pod服务是部署在monitoring命名空间中,而要监控的etcd是二进制安装的服务,为etcd创建的service是在kube-system命名空间中,为etcd的service配置的ServiceMonitor资源是部署在monitoring命名空间中。 问题1:ServiceMonitor 与 Prometheus 的关系:ServiceMonitor 不需要与 Prometheus Pod 在同一个命名空间,Prometheus 可以发现并使用不同命名空间中的 ServiceMonitor,关键是要在 Prometheus CR (Custom Resource) 中正确配置,serviceMonitorNamespaceSelector 和 serviceMonitorSelector 问题2:ServiceMonitor 与被监控 Service 的关系:ServiceMonitor 不需要与被监控的 Service 在同一个命名空间,通过 ServiceMonitor资源中的namespaceSelector 字段可以指定要监控的 Service 所在的命名空间,可以监控多个命名空间中的 Service 问题3:ServiceMonitor资源的配置中spec.jobLabel的使用: # Service 配置 apiVersion: v1 kind: Service metadata: name: etcd-service labels: etcd: monitoring # 这个标签将被用作 job 名称,标签的key作为ServiceMonitor.spec.jobLabel的名称 ... --- # ServiceMonitor 配置 apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: etcd-monitor spec: jobLabel: etcd # 使用 Service 中 key 为 "etcd" 的标签值作为 job 名称 selector: matchLabels: etcd: monitoring # 这样配置在 Prometheus 中的表现为: # 没有配置 jobLabel 时 my_metric{job="etcd-service", ...} # 配置了 jobLabel: etcd 后 my_metric{job="monitoring", ...} # 使用场景:当你需要自定义 Prometheus 中显示的 job 名称时 # 想要使用 Service 中的特定标签作为作业标识时 # 在有多个相同类型服务时,需要区分不同实例的监控数据 问题4:ServiceMonitor中tlsConfig的作用: # ServiceMonitor 资源中的 tlsConfig 是用来配置 Prometheus 与目标服务(例如 etcd 服务)之间的 TLS/SSL 安全连接的。具体而言,tlsConfig 用来指定 Prometheus 在抓取目标服务的 /metrics 端点时,如何处理 HTTPS 请求的证书校验和加密配置。tlsConfig中配置的证书文件是 Prometheus 容器内的路径,而不是 Kubernetes 宿主机的路径。 # caFile这是 Prometheus 用于验证 etcd 服务端证书的 CA 证书 (Certificate Authority) # certFile这是 Prometheus 客户端使用的证书文件,用于客户端认证。 # keyFile这是 Prometheus 客户端的私钥文件,配合 certFile 来进行客户端认证。。 问题5:已经在Prometheus的pod中挂载了证书文件为什么还要在ServiceMonitor中配置tlsConfig?: # 答:在 Prometheus 中挂载了相关的证书 和 在 ServiceMonitor 中配置 tlsConfig 是两个不同的概念,虽然它们看似相关,但它们的目的和作用是不同的。让我们深入理解为什么即使证书已经挂载到 Prometheus 中,仍然需要在 ServiceMonitor 中配置 tlsConfig。Prometheus 中挂载的证书的作用:挂载的目的仅仅是将证书文件放置在 Prometheus 容器的文件系统中,供 Prometheus 使用。证书文件可以被 Prometheus 访问使用,但 Prometheus 不会自动知道每个抓取任务应该如何使用这些证书,除非你在 ServiceMonitor 中明确指定。tlsConfig 是 ServiceMonitor 的一部分,用于配置 Prometheus 在抓取 HTTPS 端点时,如何使用证书处理 TLS/SSL 协议、证书校验和客户端认证。换句话说就是当你有多个服务需要使用证书进行通信时,需要将每个服务的证书都挂载到Prometheus的容器中,这时Prometheus并不知道哪个服务应该使用哪个证书,这是就需要在ServiceMonitor定义tlsConfig来告诉Prometheus如何使用证书,所以这两个配置缺一不可:①证书挂载:提供文件访问能力;②tlsConfig:指导证书使用方式
创建这个ServiceMonitor资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 创建资源 [root@k8s-master01 etcd-service-monitor]# kubectl create -f etcd-servicemonitor.yaml servicemonitor.monitoring.coreos.com/etcd-servicemonitor created # 查看资源创建情况etcd-servicemonitor [root@k8s-master01 etcd-service-monitor]# kubectl get servicemonitors.monitoring.coreos.com -n monitoring NAME AGE alertmanager-main 3d4h blackbox-exporter 3d4h coredns 3d4h etcd-servicemonitor 14s grafana 3d4h kube-apiserver 3d4h kube-controller-manager 3d4h kube-scheduler 3d4h kube-state-metrics 3d4h kubelet 3d4h node-exporter 3d4h prometheus-adapter 3d4h prometheus-k8s 3d4h prometheus-operator 3d4h
通过prometheus的service暴露的端口在网页端查看是否存在etcd的监控:
点击页面的[Status]—[Targets]
按照下图的选择,能看到配置的ServiceMonitor资源名称(etcd-servicemonitor),则说明配置的正确。
3.Grafana配置etcd监控模板 接下来打开Grafana,添加 Etcd 的监控面板:
首先去https://grafana.com/grafana/dashboards找合适的模板:输入条件,在结果中找适合自己的模板。
以下图中的模板为例:打开模板复制连接(https://grafana.com/grafana/dashboards/9733-etcd-for-k8s-cn/),在grafana的控制台中添加:
在grafana中新建模板:【导入模板】-【加载模板链接】-【自定义模板名字】-【选择数据源】-点击【import】即可导入。
配置完成后可以看到下图的监控指标:
18.2非云原生监控 本节将使用 MySQL 作为一个测试用例,演示如何使用 Exporter 监控非云原生应用。
如果已经有现成的mysql就不需要创建了,我这里是没有,所以部署一个用于测试的MySQL实例来演示。
1.部署测试实例 直接部署一个MySQL服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # 简单运行一个mysql的deployment服务,该命令不适用生产环境 [root@k8s-master01 ~]# kubectl create deployment mysql --image=registry.cn-beijing.aliyuncs.com/k8s-liujunwei/mysql:5.7.44 # 此时pod状态是error,pod无法重启 [root@k8s-master01 ~]# kubectl logs mysql-689b5868c8-vpqfz -c mysql 2024-11-16 13:00:02+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.44-1.el7 started. 2024-11-16 13:00:02+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' 2024-11-16 13:00:02+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.44-1.el7 started. 2024-11-16 13:00:02+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified You need to specify one of the following as an environment variable: - MYSQL_ROOT_PASSWORD - MYSQL_ALLOW_EMPTY_PASSWORD - MYSQL_RANDOM_ROOT_PASSWORD # 设置mysql的密码,否则pod是不能正常启动的 [root@k8s-master01 ~]# kubectl set env deployment mysql MYSQL_ROOT_PASSWORD=mysql deployment.apps/mysql env updated # 查看pod的状态是否正常 [root@k8s-master01 ~]# kubectl get po NAME READY STATUS RESTARTS AGE mysql-85d75646bc-9nw68 1/1 Running 0 23s
2.为MySQL服务创建service: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 可以使用命令为deployment创建一个service [root@k8s-master01 ~]# kubectl expose deploy mysql --port 3306 service/mysql exposed # kubectl get svc -l ap 也可以通过编写yaml文件: kind: Service apiVersion: v1 metadata: name: mysql-service labels: app: mysql spec: type: ClusterIP ports: - name: mysql port: 3306 targetPort: 3306 selector: app: mysql 命令和yaml的方式二选一即可。
检查service是否可用:
1 2 3 4 5 6 7 [root@k8s-master01 etcd-service-monitor]# telnet 10.96.150.170 3306 Trying 10.96.150.170... Connected to 10.96.150.170. Escape character is '^]'. J 5.7.446d0t'4OyA!&CYVE%Dmysql_native_passwordXshell !#08S01Got packets out of orderConnection closed by foreign host.
3.在mysql中创建一个监控用户: 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 # 进入pod中创建监控使用的用户并授予相应的权限 [root@k8s-master01 etcd-service-monitor]# kubectl exec -ti mysql-85d75646bc-9nw68 -- bash bash-4.2# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 Server version: 5.7.44 MySQL Community Server (GPL) Copyright (c) 2000, 2023, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. # 创建用户 mysql> create user 'exporter' @'%' identified by 'exporter' with max_user_connections 10; Query OK, 0 rows affected (0.00 sec) #with max_user_connections 10参数作用是限制用户最大的连接数是10 # 授权 mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter' @'%' ; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
4.配置 MySQL Exporter 采集 MySQL 监控数据: 方式一:使用ConfigMap形式配置MySQL账号密码 创建 MySQL Exporter 的 ConfigMap、Deployment、Service:
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 # MySQL Exporter 的 ConfigMap只要是用来保存连接目标MySQL的一些连接信息, apiVersion: v1 kind: ConfigMap metadata: name: mysql-exporter-config namespace: monitoring data: .my.cnf: | [client] user=exporter #MySQL的连接用户 password=exporter #用户的密码 host=mysql-service.default.svc.cluster.local #mysql的主机地址 port=3306 #mysql的端口号 --- # 下面是创建 MySQL Exporter的 Deployment apiVersion: apps/v1 kind: Deployment metadata: name: mysql-exporter namespace: monitoring spec: replicas: 1 selector: matchLabels: app: mysql-exporter template: metadata: labels: app: mysql-exporter spec: containers: - name: mysql-exporter image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/mysqld-exporter args: - --config.my-cnf=/etc/mysql-exporter/.my.cnf ports: - containerPort: 9104 name: metrics volumeMounts: - name: mysql-config mountPath: /etc/mysql-exporter readOnly: true livenessProbe: httpGet: path: / port: 9104 initialDelaySeconds: 30 timeoutSeconds: 5 readinessProbe: httpGet: path: / port: 9104 initialDelaySeconds: 10 timeoutSeconds: 5 volumes: - name: mysql-config configMap: name: mysql-exporter-config --- # 创建service apiVersion: v1 kind: Service metadata: name: mysql-exporter namespace: monitoring labels: app: mysql-exporter spec: type: ClusterIP ports: - port: 9104 targetPort: 9104 name: metrics protocol: TCP selector: app: mysql-exporter --- # 创建 ServiceMonitor apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: mysql-servicemonitor namespace: monitoring labels: release: prometheus spec: endpoints: - interval: 30s port: metrics path: /metrics scheme: http selector: matchLabels: app: mysql-exporter namespaceSelector: matchNames: - monitoring
创建上述资源:(可以在一个文件中写多个资源,也可以分开写,每个资源单独一个文件)
1 2 3 4 kubectl create -f mysql-exporter-configmap.yaml kubectl create -f mysql-exporter-deployment.yaml kubectl create -f mysql-export-service.yaml kubectl create -f mysql-exporter-servicemonitiort.yaml
方式二:使用Secret形式定义MySQL账号密码 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 # 配置一个secret,用来mysql exporter存储mysql的连接信息。 apiVersion: v1 kind: Secret metadata: name: mysql-exporter-secret namespace: monitoring type: Opaque stringData: .my.cnf: |- [client] host=192.168.0.117 #host定义mysql服务器的IP地址,如果mysql服务器是在k8s集群外部,直接定义为mysql服务器的IP地址即可。 #host=mysql-service.default.svc.cluster.local #mysql的主机地址,这种配置是mysql服务部署在k8s集群内部,如果mysql服务器在k8s集群内部,则需要使用服务名来定义,mysql-service是MySQL服务的service名称,default是mysql-service的命名空间 port=3306 #mysql服务的端口 user=exporter #监控使用的用户 password=wawxy1314@ #监控用户的密码 --- # 配置Deployment,用于部署mysql-exporter。 apiVersion: apps/v1 kind: Deployment metadata: name: mysql-exporter namespace: monitoring labels: #定义该Deployment资源的标签 app: mysql-exporter spec: replicas: 1, selector: #选择器,用来根据 标签 选择要管理的pod,要跟下面template.metadatalabels中配置的标签保持一致 matchLabels: app: mysql-exporter template: #定义pod的模板 metadata: #pod的元数据 labels: #这里定义的是pod的标签 app: mysql-exporter #定义pod的标签,要和上面的spec.selector.matchLabels中定义的保持一致 spec: containers: - name: mysql-exporter image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/bitnami_mysqld-exporter:0.14.0 env: - name: TZ value: "Asia/Shanghai" args: - --config.my-cnf=/etc/mysql/.my.cnf ports: - containerPort: 9104 name: metrics volumeMounts: - name: mysql-config mountPath: /etc/mysql volumes: - name: mysql-config secret: secretName: mysql-exporter-secret --- # 配置Service,用于将mysql-exporter暴露给集群内部的其他服务。 apiVersion: v1 kind: Service metadata: name: mysql-exporter namespace: monitoring labels: app: mysql-exporter spec: selector: #这里的标签选择器是定义要关联pod的标签,作用是根据标签将流量转发到相应的pod上 app: mysql-exporter ports: - port: 9104 targetPort: 9104 name: metrics --- # 配置ServiceMonitor,用于Prometheus Operator发现并抓取mysql-exporter的metrics数据。 apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: mysql-exporter namespace: monitoring labels: # 定义该ServiceMonitor资源的标签 release: prometheus spec: selector: #标签选择器 matchLabels: #匹配标签 app: mysql-exporter #意思是匹配具有app=mysql-exporter标签的service namespaceSelector: #定义service所在的命名空间 matchNames: #命名空间匹配,也就是从哪个命名空间找具有上述标签的service - monitoring endpoints: - port: metrics #该字段与上述service资源中的port字段对应(Service.spec.ports.name),用于指定抓取的metrics端口 interval: 30s scheme: http path: /metrics
检查是否能正常获取到Metrics数据:
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 [root@k8s-master01 mysql-exporter]# kubectl get po -n monitoring mysql-exporter-b8cccdfcf-h6986 -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mysql-exporter-b8cccdfcf-h6986 1/1 Running 0 93m 172.16.85.195 k8s-node01 <none> <none> # 通过pod的ip测试是否能拿到mysql的监控数据(172.16.85.195是mysql exporter的pod 的 ip地址) [root@k8s-master01 mysql-exporter]# curl 172.16.85.195:9104/metrics |tail -10 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 155k 0 155k 0 0 1984k 0 --:--:-- --:--:-- --:--:-- 2018k # TYPE process_virtual_memory_max_bytes gauge process_virtual_memory_max_bytes 1.8446744073709552e+19 # HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served. # TYPE promhttp_metric_handler_requests_in_flight gauge promhttp_metric_handler_requests_in_flight 1 # HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code. # TYPE promhttp_metric_handler_requests_total counter promhttp_metric_handler_requests_total{code="200"} 181 promhttp_metric_handler_requests_total{code="500"} 0 promhttp_metric_handler_requests_total{code="503"} 0 # 通过service的ip测试是否能拿到mysql的监控数据(10.96.212.123是mysql exporter的service 的 ip地址) [root@k8s-master01 mysql-exporter]# kubectl get svc -n monitoring mysql-exporter NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-exporter ClusterIP 10.96.212.123 <none> 9104/TCP 95m # 通过mysql exporter的service 的 ip地址获取监控数据 [root@k8s-master01 mysql-exporter]# curl 10.96.212.123:9104/metrics |tail -10 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 155k 0 155k 0 0 3136k 0 --:--:-- --:--:-- --:--:-- 3171k # TYPE process_virtual_memory_max_bytes gauge process_virtual_memory_max_bytes 1.8446744073709552e+19 # HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served. # TYPE promhttp_metric_handler_requests_in_flight gauge promhttp_metric_handler_requests_in_flight 1 # HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code. # TYPE promhttp_metric_handler_requests_total counter promhttp_metric_handler_requests_total{code="200"} 191 promhttp_metric_handler_requests_total{code="500"} 0 promhttp_metric_handler_requests_total{code="503"} 0
上述的两种配置密码的方式二选一配置即可(ConfigMap和Secret).
所有资源创建完成后在prometheus的web端查看是否有mysql的监控指标:
可以看到已经自动发现了配置的mysql-servicemonitor,状态是up
5.Grafana配置mysql监控模板 导入 Grafana Dashboard,地址:https://grafana.com/grafana/dashboards/14057-mysql/,https://grafana.com/grafana/dashboards/6239-mysql/ (两个模板连接二选一,)导入步骤和之前类似,在此不再演示。导入完成后,即可在 Grafana 看到监控数据:
1.在grafana控制台配置模板前需要在Prometheus确定能发现配置mysql-servicemonitor,
2.在grafana控制台配置模板前需要在Prometheus确定能发现mysql指标,这里的指标不能只有mysql_up或者mysqld_exporter_build_info
如果输入mysql关键字只有下图两个指标,是不对的,表示mysql exporter并没有拿到各项指标数据,需要进一步排查错误。这里遇到的就是在mysql中创建的exporter用户密码不正确导致的。
6.Service Monitor找不到监控主机排查步骤 ①确认Service Monitor是否成功创建
②确认Service Monitor关联的service标签是否配置正确
③确认Prometheus是否生成了相关配置
④确认Service Monitor匹配的Service存在
⑤确认通过Service能够访问程序的Metrics接口
⑥确认Service服务配置的端口名字(Service.spec.ports.name)和Service Monitor中(ServiceMonitor.spec.endpoints.port)配置的一致
一、排查案例KubeControllerManager:
以上图KubeControllerManager 和KubeScheduler 为案例讲解排查过程:
以下方法不仅仅是针对KubeControllerManager或者KubeScheduler的排查思路,所有用到Service Monitor资源的均可以按照该流程排查问题。
第一步:确认Service Monitor是否成功创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #KubeControllerManager [root@k8s-master01 mysql-exporter]# kubectl get servicemonitors.monitoring.coreos.com -n monitoring NAME AGE alertmanager-main 7d22h blackbox-exporter 7d22h coredns 7d22h etcd-servicemonitor 4d17h grafana 7d22h kube-apiserver 7d22h kube-controller-manager 7d22h kube-scheduler 7d22h kube-state-metrics 7d22h kubelet 7d22h mysql-exporter 25h node-exporter 7d22h prometheus-adapter 7d22h prometheus-k8s 7d22h prometheus-operator 7d22h #kube-scheduler和 kube-controller-manager是存在的
第二步:确认Service Monitor关联的service标签是否配置正确
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 # 检查servicemonitors资源中选择的sevice资源标签 [root@k8s-master01 mysql-exporter]# kubectl get servicemonitors.monitoring.coreos.com -n monitoring kube-controller-manager -oyaml .... insecureSkipVerify: true jobLabel: app.kubernetes.io/name namespaceSelector: matchNames: - kube-system #匹配的命名空间是kube-system selector: matchLabels: app.kubernetes.io/name: kube-controller-manager #在kube-system命名空间中匹配具有app.kubernetes.io/name=kube-controller-manager标签的service # 检查检查目标命名空间中是否有标签值是app.kubernetes.io/name=kube-controller-manager的service [root@k8s-master01 mysql-exporter]# kubectl get service -n kube-system -l app.kubernetes.io/name=kube-controller-manager No resources found in kube-system namespace. #没有目标service # 可以看到并没有此标签的Service,所以导致了找不到需要监控的目标,此时可以手动创建该Service和Endpoint指向自己的Controller Manager: vim kube-controller-manager-svc.yaml # 创建yaml文件,添加下面配置 kind: Service apiVersion: v1 metadata: name: kube-controller-manager namespace: kube-system labels: app.kubernetes.io/name: kube-controller-manager #这里定义的标签和servicemonitors保持一致 spec: type: ClusterIP ports: - name: https-metrics port: 10257 targetPort: 10257 protocol: TCP --- kind: Endpoints apiVersion: v1 metadata: name: kube-controller-manager namespace: kube-system subsets: - addresses: - ip: 192.168.0.200 #这里的ip改为自己的ControllerManager的ip,有几个ControllerManager节点就写几个ip - ip: 192.168.0.201 - ip: 192.168.0.202 ports: - name: https-metrics port: 10257 protocol: TCP # 创建上述kube-controller-manager-svc.yaml资源(创建Service和Endpoints) [root@k8s-master01 kube-controller-manager]# kubectl create -f kube-controller-manager-svc.yaml service/kube-controller-manager created endpoints/kube-controller-manager created [root@k8s-master01 kube-controller-manager]# kubectl get -f kube-controller-manager-svc.yaml NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kube-controller-manager ClusterIP 10.96.228.24 <none> 10257/TCP 4h31m NAME ENDPOINTS AGE endpoints/kube-controller-manager 192.168.0.200:10257,192.168.0.201:10257,192.168.0.202:10257 4h31m # 因为请求kube-controller-manager的接口也要使用https,所以也需要配置证书(可以参考etcd的证书配置方法,一个道理) # 首先找到证书,创建一个secret,这个secret要给prometheus-k8s-0使用,所以要个prometheus-k8s-0的pod在同一个命名空间中 kubectl create secret generic kube-controller-manager-ssl \ --from-file=/etc/kubernetes/pki/ca.pem \ --from-file=/etc/kubernetes/pki/admin.pem \ --from-file=/etc/kubernetes/pki/admin-key.pem -n monitoring # 将secret证书挂载至 Prometheus 容器(由于 Prometheus 是 Operator 部署的,所以只需要修改Prometheus 资源即可): [root@k8s-master01 kube-controller-manager]# kubectl edit prometheus -n monitoring k8s scrapeConfigSelector: {} scrapeInterval: 30s secrets: #在secrets下添加刚才创建的secret名字,是kube-controller-manager-ssl - etcd-ssl #这个是etcd的证书 - kube-controller-manager-ssl #这个是新增的kube-controller-manager证书的名字 securityContext: fsGroup: 2000 # 保存退出后,Prometheus 的 Pod (prometheus-k8s-0)会自动重启,重启完成后,查看证书是否挂载(任意一个Prometheus 的 Pod 均可): [root@k8s-master01 kube-controller-manager]# kubectl exec -ti prometheus-k8s-0 -n monitoring -- sh /prometheus $ ls -l /etc/prometheus/secrets/ etcd-ssl/ kube-controller-manager-ssl/ /prometheus $ ls -l /etc/prometheus/secrets/kube-controller-manager-ssl/ total 0 lrwxrwxrwx 1 root 2000 20 Nov 20 10:27 admin-key.pem -> ..data/admin-key.pem lrwxrwxrwx 1 root 2000 16 Nov 20 10:27 admin.pem -> ..data/admin.pem lrwxrwxrwx 1 root 2000 13 Nov 20 10:27 ca.pem -> ..data/ca.pem # 编辑kube-controller-manager的ServiceMonitor,配置tlsConfig中证书文件部分 [root@k8s-master01 kube-controller-manager]# kubectl edit servicemonitors.monitoring.coreos.com -n monitoring kube-controller-manager metricRelabelings: - action: drop regex: process_start_time_seconds sourceLabels: - __name__ path: /metrics/slis port: https-metrics scheme: https tlsConfig: #配置证书文件在pod名字是prometheus-k8s-0中的路径 caFile: /etc/prometheus/secrets/kube-controller-manager-ssl/ca.pem #Prometheus 的 Pod (prometheus-k8s-0)中的路径 certFile: /etc/prometheus/secrets/kube-controller-manager-ssl/admin.pem ##Prometheus 的 Pod (prometheus-k8s-0)中的路径 insecureSkipVerify: true keyFile: /etc/prometheus/secrets/kube-controller-manager-ssl/admin-key.pem ##Prometheus 的 Pod (prometheus-k8s-0)中的路径 jobLabel: app.kubernetes.io/name namespaceSelector: matchNames: - kube-system selector: matchLabels: app.kubernetes.io/name: kube-controller-manager
在prometheus控制台查看是否成功:
下面已经看不到之前的报错了(KubeControllerManagerDown)
可以看到kube-controller-manager的状态也都是up,这就表示已经处理好了。
二、排查案例KubeScheduler: ①确认Service Monitor是否成功创建
②确认Service Monitor关联的service标签是否配置正确
③确认Prometheus是否生成了相关配置
④确认Service Monitor匹配的Service存在
⑤确认通过Service能够访问程序的Metrics接口
⑥确认Service服务配置的端口名字(Service.spec.ports.name)和Service Monitor中(ServiceMonitor.spec.endpoints.port)配置的一致
第一步:排查是否有KubeScheduler的Service Monitor
第二步:确认Service Monitor关联的service标签是否配置正确
检查kube-system命名空间中是否存在标签是app.kubernetes.io/name=kube-scheduler的Service:
1 2 kubectl get service -n kube-system -l app.kubernetes.io/name=kube-scheduler # 通过该命令看到没有找到相应的service资源,见下图
接下来手动为scheduler创建Service和Endpoint,指向安装的kube-scheduler
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 # 手动创建Service和Endpoint资源: vim kube-scheduler-svc.yaml # 创建yaml文件,添加下面配置 kind: Service apiVersion: v1 metadata: name: kube-scheduler namespace: kube-system labels: app.kubernetes.io/name: kube-scheduler #这里定义的标签和servicemonitors保持一致 spec: ports: - name: https-metrics #如果是通过ServiceMonitor资源对其进行监控,这里的name要和ServiceMonitor.spec.endpoints.port字段保持一致 port: 10259 targetPort: 10259 protocol: TCP --- kind: Endpoints apiVersion: v1 metadata: name: kube-scheduler namespace: kube-system subsets: - addresses: - ip: 192.168.0.200 ##这里的ip改为自己的kube-scheduler的ip,有几个kube-scheduler节点就写几个ip - ip: 192.168.0.201 - ip: 192.168.0.202 ports: - name: https-metrics port: 10259 protocol: TCP # 创建上述kube-scheduler-svc.yaml资源(创建Service和Endpoints) [root@k8s-master01 kube-scheduler]# kubectl replace -f kube-scheduler-svc.yaml service/kube-scheduler replaced endpoints/kube-scheduler replaced [root@k8s-master01 kube-scheduler]# kubectl get -f kube-scheduler-svc.yaml NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kube-scheduler ClusterIP 10.96.9.215 <none> 10259/TCP 23m NAME ENDPOINTS AGE endpoints/kube-scheduler 192.168.0.200:10259,192.168.0.201:10259,192.168.0.202:10259 23m
测试通过创建的service的ip是否能获取到监控数据:
1 2 curl --cacert /etc/kubernetes/pki/ca.pem --cert /etc/kubernetes/pki/admin.pem --key /etc/kubernetes/pki/admin-key.pem https://10.96.9.215:10259/metrics -k|tail -5 # 通过下图可以看到通过service的ip能获取到监控数据
因为请求kube-scheduler的接口也要使用https,所以也需要配置证书(可以参考etcd和kube-controller-manager的证书配置方法,一个道理)
1 2 3 4 5 # 首先找到证书,创建一个secret,这个secret要给prometheus-k8s-0使用,所以要个prometheus-k8s-0的pod在同一个命名空间中 kubectl create secret generic kube-scheduler-ssl \ --from-file=/etc/kubernetes/pki/ca.pem \ --from-file=/etc/kubernetes/pki/admin.pem \ --from-file=/etc/kubernetes/pki/admin-key.pem -n monitoring
将secret证书挂载至 Prometheus 容器(由于 Prometheus 是 Operator 部署的,所以只需要修改Prometheus 资源即可):
1 2 3 4 5 kubectl edit prometheus -n monitoring k8s secrets: #在secrets下添加刚才创建的secret名字,是kube-scheduler-ssl - etcd-ssl #这个是etcd的证书 - kube-controller-manager-ssl #这个是kube-controller-manager证书的名字 - kube-scheduler-ssl #这个是为kube-scheduler创建的secret
保存退出后,Prometheus 的 Pod (prometheus-k8s-0)会自动重启,重启完成后,查看证书是否挂载(任意一个Prometheus 的 Pod 均可):
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 # 等待pod(prometheus-k8s-0)自动重启,查看证书是否挂载成功 [root@k8s-master01 kube-scheduler]# kubectl exec -ti prometheus-k8s-0 -n monitoring -- sh /prometheus $ ls -l /etc/prometheus/secrets/ total 0 drwxrwsrwt 3 root 2000 140 Nov 22 09:04 etcd-ssl drwxrwsrwt 3 root 2000 140 Nov 22 09:04 kube-controller-manager-ssl drwxrwsrwt 3 root 2000 140 Nov 22 09:04 kube-scheduler-ssl /prometheus $ ls -l /etc/prometheus/secrets/kube-scheduler-ssl/ total 0 lrwxrwxrwx 1 root 2000 20 Nov 22 09:04 admin-key.pem -> ..data/admin-key.pem lrwxrwxrwx 1 root 2000 16 Nov 22 09:04 admin.pem -> ..data/admin.pem lrwxrwxrwx 1 root 2000 13 Nov 22 09:04 ca.pem -> ..data/ca.pem # 编辑kube-scheduler的ServiceMonitor,配置tlsConfig中证书文件部分 [root@k8s-master01 kube-scheduler]# kubectl edit servicemonitors.monitoring.coreos.com -n monitoring kube-scheduler metricRelabelings: - action: drop regex: process_start_time_seconds sourceLabels: - __name__ path: /metrics/slis port: https-metrics scheme: https tlsConfig: #配置证书文件,证书路径是名字为prometheus-k8s-0 的 pod中的路径 caFile: /etc/prometheus/secrets/kube-scheduler-ssl/ca.pem # #Prometheus 的 Pod (prometheus-k8s-0)中的路径,不是宿主机的路径 certFile: /etc/prometheus/secrets/kube-scheduler-ssl/admin.pem #Prometheus 的 Pod (prometheus-k8s-0)中的路径,不是宿主机的路径 keyFile: /etc/prometheus/secrets/kube-scheduler-ssl/admin-key.pem # #Prometheus 的 Pod (prometheus-k8s-0)中的路径,不是宿主机的路径 insecureSkipVerify: true jobLabel: app.kubernetes.io/name namespaceSelector: matchNames: - kube-system selector: matchLabels: app.kubernetes.io/name: kube-scheduler metricRelabelings:
在prometheus控制台查看是否还存在报错:
下面已经看不到之前的报错了(KubeSchedulerDown)
可能存在的问题:
可能会遇到Service不通的问题,因为在集群搭建时,可能ControllerManager和Scheduler是监听的127.0.0.1就导致无法被外部访问,此时需要更改它的监听地址为0.0.0.0:
1 2 3 4 5 6 7 8 9 10 11 # 查看服务监听地址: [root@k8s-master01 kube-scheduler]# netstat -lntup|grep kube-controlle tcp6 0 0 :::10257 :::* LISTEN 1126/kube-controlle [root@k8s-master01 kube-scheduler]# netstat -lntup|grep kube-scheduler tcp6 0 0 :::10259 :::* LISTEN 1125/kube-scheduler # 如果监听的地址是127.0.0.1,就需要修改对应服务的配置文件,将监听地址改为0.0.0.0,服务的配置文件路径根据自己的位置修改。例如: sed -i "s#address=127.0.0.1#address=0.0.0.0#g" /usr/lib/systemd/system/kube-controller-manager.service # 修改后重启 systemctl daemon-reload systemctl restart kube-controller-manager
18.3黑盒监控 黑盒监控 (Blackbox Monitoring)
定义 :黑盒监控指的是通过模拟用户请求来监控外部服务或系统的可用性和性能,而不是直接监控这些服务的内部指标。这种监控方式通常用于检查网络服务的健康状态,如HTTP、HTTPS、DNS、TCP等协议的响应时间、状态码等。
特点 :
从用户的视角来评估服务的可用性和性能。
不需要对被监控的系统有深入的内部了解。
主要关注外部表现,如响应时间、状态码、是否可达等。
通常使用blackbox_exporter来实现。
应用 :
网站监控:检查网站是否可达,响应时间是否在可接受范围内。
DNS监控:验证DNS解析是否正常工作。
API监控:监控API的响应时间、状态码。
网络服务监控:检查TCP连接的建立时间、丢包率等。
白盒监控 (Whitebox Monitoring)
定义 :白盒监控指的是直接从系统内部获取指标数据,监控系统的内部状态和性能。这种监控方式需要对被监控的系统有深入的了解,能够获取到系统的内部运行情况。
特点 :
直接监控系统的内部指标,如CPU使用率、内存使用、磁盘I/O、网络流量等。
需要对系统的内部结构和运行机制有详细的了解。
可以提供更详细的性能数据和问题诊断信息。
通常通过Prometheus的exporter来暴露系统的内部指标。
应用 :
系统资源监控:监控CPU、内存、磁盘、网络等资源的使用情况。
应用性能监控:监控应用程序的内部指标,如请求处理时间、错误率等。
数据库监控:监控数据库的性能指标,如查询时间、连接数等。
容器和Kubernetes监控:监控容器和Kubernetes集群的内部状态。
总结
黑盒监控 关注的是服务的外部表现,适用于检查服务的可用性和用户体验,但无法提供关于系统内部状态的详细信息。
白盒监控 则深入到系统内部,提供更详细的性能数据和问题诊断信息,但需要对系统有深入的了解。
新版Prometheus Stack已经默认安装了BlackboxExporter(黑盒监控),可以通过以下命令查看:
1 2 kubectl get po -n monitoring #
同时也会创建一个Service,可以通过该Service访问BlackboxExporter并传递一些参数:
1 kubectl get service -n monitoring
可以通过blackbox-exporter的service的ip地址对网站进行探测:
比如检测下www.baidu.com (使用任何一个公网域名或者公司内的域名探测即可)网站的状态,可以通过如下命令进行检查:
1 2 3 4 5 6 7 8 9 10 11 [root@k8s-master01 kube-scheduler]# curl -s "http://10.96.69.178:19115/probe?target=www.baidu.com&module=http_2xx" | tail -5 # TYPE probe_ip_protocol gauge probe_ip_protocol 4 # HELP probe_success Displays whether or not the probe was a success # TYPE probe_success gauge probe_success 1 # probe是blackbox-exporter服务的接口地址。 # target是检测的目标。 # module是使用哪个模块进行探测。 # https://github.com/prometheus/blackbox_exporter进行安装。
1.监控站点 Prometheus支持的 额外抓取配置(additionalScrapeConfigs),通过配置额外抓取配置来实现对某些网站的监控。
当 Prometheus Operator 默认生成的 scrape_configs 无法覆盖特殊场景(如黑盒监控、自定义导出器)时,additionalScrapeConfigs 提供了一种灵活扩展机制。
Prometheus Operator 会自动检测 additionalScrapeConfigs,将其内容合并到主 Prometheus 的配置中(scrape_configs 部分)。
通过prometheus的静态配置对某个网站进行监控—黑盒监控
第一步:创建一个空文件,然后通过该文件创建一个secret,那么这个secret即可作为prometheus的静态配置:
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 # 创建一个空文件prometheus-additional.yaml,用它来创建secret [root@k8s-master01 blackbox-exporter]# touch prometheus-additional.yaml # 创建secret [root@k8s-master01 blackbox-exporter]# kubectl create secret generic prometheus-additional-config --from-file=prometheus-additional.yaml -n monitoring secret/prometheus-additional-config created # 查看创建的secret [root@k8s-master01 blackbox-exporter]# kubectl get secrets -n monitoring prometheus-additional-config NAME TYPE DATA AGE prometheus-additional-config Opaque 1 47s # 修改prometheus的配置,这里的prometheus是一个CRD(自定义资源定义),由Prometheus Operator管理,修改CRD会自动触发Operator重新配置Prometheus [root@k8s-master01 blackbox-exporter]# kubectl edit prometheus -n monitoring k8s # 在 Prometheus 的配置中,additionalScrapeConfigs 是 Prometheus Operator 提供的一个参数,用于扩展和动态管理 scrape_configs(抓取配置)。它的作用是指定一组额外的抓取配置,这些配置通过一个 Kubernetes Secret 提供,并与 Prometheus 的默认 scrape_configs 合并 serviceMonitorNamespaceSelector: {} serviceMonitorSelector: {} additionalScrapeConfigs: #定义额外抓取配置 name: prometheus-additional-config #对应上述创建的secret的名称 key: prometheus-additional.yaml #key对应是的上述创建的secret时指定的文件名 optional: true #可选参数,true表示即使Secret不存在也不会报错,提供了配置的容错性便于后续增量更新 version: 2.54.1 status: availableReplicas: 1 conditions:
主要是在prometheus资源中增加下面配置:
1 2 3 4 additionalScrapeConfigs: #定义额外抓取配置 name: prometheus-additional-config #对应上述创建的secret的名称 key: prometheus-additional.yaml #key对应是的上述创建的secret时指定的文件名 optional: true #可选参数,true表示即使Secret不存在也不会报错,提供了配置的容错性便于后续增量更新
添加上述配置后保存退出,无需重启 Prometheus 的 Pod 即可生效。之后在prometheus-additional.yaml文件内编辑一些静态配置,此处用黑盒监控的配置进行演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@k8s-master01 blackbox-exporter]# vim prometheus-additional.yaml # 添加下面配置 - job_name: 'blackbox' # 任务名称 metrics_path: /probe # 指标获取路径 params: module: [http_2xx] # 使用的探测模块 static_configs: - targets: #targets模块下配置的是要监控的网站域名 - http://gaoxin.kubeasy.com # 监控目标 - https://www.baidu.com relabel_configs: # 标签重写规则,固定写法 - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:19115 #Blackbox Exporter 的地址
可以看到此处的内容,基本和命令行配置的内容一致,只需要添加对应的 job 即可。之后通过该文件热更新该 Secret:
1 2 3 # 热更新secret命令 [root@k8s-master01 blackbox-exporter]# kubectl create secret generic prometheus-additional-config --from-file=prometheus-additional.yaml --dry-run=client -oyaml|kubectl replace -f - -n monitoring secret/prometheus-additional-config replaced
检查secret是否被更新:
1 2 3 4 5 6 7 8 9 10 11 12 [root@k8s-master01 blackbox-exporter]# kubectl get secrets -n monitoring prometheus-additional-config -oyaml apiVersion: v1 data: prometheus-additional.yaml: I+a3u+WKoOS4i+mdoumFjee9rg0KLSBqb2JfbmFtZTogJ2JsYWNrYm94JyAgICAgICAgICAgICAgICAjIOS7u+WKoeWQjeensA0KICBtZXRyaWNzX3BhdGg6IC9wcm9iZSAgICAgICAgICAgICAgICMg5oyH5qCH6I635Y+W6Lev5b6EDQogIHBhcmFtczoNCiAgICBtb2R1bGU6IFtodHRwXzJ4eF0gICAgICAgICAgICAgICMg5L2/55So55qE5o6i5rWL5qih5Z2XDQogIHN0YXRpY19jb25maWdzOg0KICAgIC0gdGFyZ2V0czogI3RhcmdldHPmqKHlnZfkuIvphY3nva7nmoTmmK/opoHnm5HmjqfnmoTnvZHnq5nln5/lkI0NCiAgICAgICAgLSBodHRwOi8vZ2FveGluLmt1YmVhc3kuY29tICAgIyDnm5Hmjqfnm67moIcNCiAgICAgICAgLSBodHRwczovL3d3dy5iYWlkdS5jb20NCiAgcmVsYWJlbF9jb25maWdzOiAgICAgICAgICAgICAgICAgICMg5qCH562+6YeN5YaZ6KeE5YiZ77yM5Zu65a6a5YaZ5rOVDQogICAgLSBzb3VyY2VfbGFiZWxzOiBbX19hZGRyZXNzX19dDQogICAgICB0YXJnZXRfbGFiZWw6IF9fcGFyYW1fdGFyZ2V0DQogICAgLSBzb3VyY2VfbGFiZWxzOiBbX19wYXJhbV90YXJnZXRdDQogICAgICB0YXJnZXRfbGFiZWw6IGluc3RhbmNlDQogICAgLSB0YXJnZXRfbGFiZWw6IF9fYWRkcmVzc19fDQogICAgICByZXBsYWNlbWVudDogYmxhY2tib3gtZXhwb3J0ZXI6MTkxMTU= kind: Secret metadata: creationTimestamp: "2024-11-22T14:40:30Z" name: prometheus-additional-config namespace: monitoring resourceVersion: "18827266" uid: efc2196d-fbc4-4425-8c05-d94963289e21 type: Opaque
可以看到上述secret已经有内容了,可以使用base64解码查看内容是否是我们配置的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@k8s-master01 blackbox-exporter]# echo """I+a3u+WKoOS4i+mdoumFjee9rg0KLSBqb2JfbmFtZTogJ2JsYWNrYm94JyAgICAgICAgICAgICAgICAjIOS7u+WKoeWQjeensA0KICBtZXRyaWNzX3BhdGg6IC9wcm9iZSAgICAgICAgICAgICAgICMg5oyH5qCH6I635Y+W6Lev5b6EDQogIHBhcmFtczoNCiAgICBtb2R1bGU6IFtodHRwXzJ4eF0gICAgICAgICAgICAgICMg5L2/55So55qE5o6i5rWL5qih5Z2XDQogIHN0YXRpY19jb25maWdzOg0KICAgIC0gdGFyZ2V0czogI3RhcmdldHPmqKHlnZfkuIvphY3nva7nmoTmmK/opoHnm5HmjqfnmoTnvZHnq5nln5/lkI0NCiAgICAgICAgLSBodHRwOi8vZ2FveGluLmt1YmVhc3kuY29tICAgIyDnm5Hmjqfnm67moIcNCiAgICAgICAgLSBodHRwczovL3d3dy5iYWlkdS5jb20NCiAgcmVsYWJlbF9jb25maWdzOiAgICAgICAgICAgICAgICAgICMg5qCH562+6YeN5YaZ6KeE5YiZ77yM5Zu65a6a5YaZ5rOVDQogICAgLSBzb3VyY2VfbGFiZWxzOiBbX19hZGRyZXNzX19dDQogICAgICB0YXJnZXRfbGFiZWw6IF9fcGFyYW1fdGFyZ2V0DQogICAgLSBzb3VyY2VfbGFiZWxzOiBbX19wYXJhbV90YXJnZXRdDQogICAgICB0YXJnZXRfbGFiZWw6IGluc3RhbmNlDQogICAgLSB0YXJnZXRfbGFiZWw6IF9fYWRkcmVzc19fDQogICAgICByZXBsYWNlbWVudDogYmxhY2tib3gtZXhwb3J0ZXI6MTkxMTU="""|base64 -d #可以看到解密出来的配置是我们配置的内容 # 添加下面配置 - job_name: 'blackbox' # 任务名称 metrics_path: /probe # 指标获取路径 params: module: [http_2xx] # 使用的探测模块 static_configs: - targets: #targets模块下配置的是要监控的网站域名 - http://gaoxin.kubeasy.com # 监控目标 - https://www.baidu.com relabel_configs: # 标签重写规则,固定写法 - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:19115
检查Prometheus的Web 界面中查看是否存在该配置:
通过下图可以看到Prometheus已经成功看到该配置,状态也是up,接下来就可以配置监控模板了。
在grafana控制台中配置监控模板(模板连接地址https://grafana.com/grafana/dashboards/13659-blackbox-exporter-http-prober/):
导入网站监控模板:
最后可以看到监控界面即可:
如果需要新增加站点监控,直接编辑prometheus-additional.yaml文件,然后再次执行热更新secret的命令即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 例如,要新增加www.ibstd.cn站点的监控,在targets模块下增加监控目标即可 [root@k8s-master01 blackbox-exporter]# vim prometheus-additional.yaml # 添加下面配置 - job_name: 'blackbox' # 任务名称 metrics_path: /probe # 指标获取路径 params: module: [http_2xx] # 使用的探测模块 static_configs: - targets: #targets模块下配置的是要监控的网站域名 - http://gaoxin.kubeasy.com # 监控目标 - https://www.baidu.com - https://www.ibstd.cn #这是新增加的监控目标网站 relabel_configs: # 标签重写规则,固定写法 - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:19115 #Blackbox Exporter 的地址
修改prometheus-additional.yaml文件后保存退出,执行热更新的命令即可:
1 2 # 通过下面的命令热更新secret kubectl create secret generic prometheus-additional-config --from-file=prometheus-additional.yaml --dry-run=client -oyaml|kubectl replace -f - -n monitoring
18.4Prometheus监控外部windows主机 监控 Linux主机 的 Exporter 是:https://github.com/prometheus/node_exporter,
监控 Windows主机的 Exporter 是:https://github.com/prometheus-community/windows_exporter。
首 先 下 载 对 应 的 Exporter 至 Windows 主 机 ( MSI 文 件 下 载 地 址 :https://github.com/prometheus-community/windows_exporter/releases):
下载后直接在要监控的windows主机上安装,Windows Exporter 会暴露一个 9182 端口,可以通过该端口访问到 Windows 的监控数据。
接下来在静态配置文件中添加以下配置:
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 [root@k8s-master01 blackbox-exporter]# cat prometheus-additional.yaml # 添加下面配置 - job_name: 'blackbox' # 任务名称 metrics_path: /probe # 指标获取路径 params: module: [http_2xx] # 使用的探测模块 static_configs: - targets: #targets模块下配置的是要监控的网站域名 - http://gaoxin.kubeasy.com # 监控目标 - https://www.baidu.com - https://www.ibstd.cn relabel_configs: # 标签重写规则,固定写法 - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:19115 # 下面部署是新增加对windows主机监控的部分, - job_name: 'WindowsMonitor' static_configs: - targets: - "192.168.0.103:9182" #这里是被监控电脑的ip地址,如果有多个参考上述站点的监控格式写多个即可 labels: server_type: 'windows' relabel_configs: - source_labels: [__address ] target_label: instance # Targets 配置的是监控主机,如果是多台 Windows 主机,配置多行即可,当然每台主机都需要配置 Exporter。
对该静态文件进行热更新:
1 2 #通过下面的命令热更新secret kubectl create secret generic prometheus-additional-config --from-file=prometheus-additional.yaml --dry-run=client -oyaml|kubectl replace -f - -n monitoring
之后可以在 Prometheus Web UI 看到监控数据表示配置正确:
上述都显示没问题了在grafana中导入监控模板:https://grafana.com/grafana/dashboards/12566-3-windows-exporter-0-7-0-for-prometheus-windows/
18.5PromQL语法初体验 PromQL Web UI 的 Graph 选项卡提供了简单的用于查询数据的入口,对于 PromQL 的编写和校验都可以在此位置,如图所示:
输入 up,然后点击 Execute,就能查到监控正常的 Target:
通过标签选择器过滤出job 为node-exporter 的监控,语法为:**up{job=”node-exporter”}**:
注意此时是 **up{job=”node-exporter”}**属于绝对匹配,PromQL 也支持如下表达式:
!=:不等于;
=~:表示等于符合正则表达式的指标;
!:和=类似,=表示正则匹配,!表示正则不匹配。
如果想要查看主机监控的指标有哪些,可以输入 node,会提示所有主机监控的指标:
假 如 想 要 查 询 Kubernetes 集 群 中 每 个 宿 主 机 的 磁 盘 总 量 , 可 以 使 用node_filesystem_size_bytes
查询指定分区大小 **node_filesystem_size_bytes{mountpoint=”/“}**:
或者是查询分区不是/boot,且磁盘是/dev/开头的分区大小(结果不再展示):
1 node_filesystem_size_bytes{device=~'/dev/.*',mountpoint!='/boot'}
查询主机 k8s-master01 在最近 5 分钟可用的磁盘空间变化:
1 node_filesystem_avail_bytes{instance="k8s-master01",mountpoint='/',device='/dev/mapper/centos_k8s--master01-root'}[5m]
目前支持的范围单位如下:
s:秒
m:分钟
h:小时
d:天
w:周
y:年
查询10分钟之前磁盘可用空间,只需要指定offset参数即可:
1 node_filesystem_avail_bytes{instance="k8s-master01",mountpoint='/',device='/dev/mapper/centos_k8s--master01-root'}offset 10m
查询 10 分钟之前,5 分钟区间的磁盘可用空间的变化:
1 node_filesystem_avail_bytes{instance="k8s-master01",mountpoint='/',device='/dev/mapper/centos_k8s--master01-root'}[5m] offset 10m
18.6PromQL操作符 通过 PromQL 的语法查到了主机磁盘的剩余空间数据,查询结果如下:
可以通过以下命令将字节转换为 GB 或者 MB:
1 node_filesystem_avail_bytes{mountpoint='/'}/1024/1024/1024
也可以将 1024 / 1024 / 1024 改为**(1024 ^ 3)**:
可以看到5个节点的/分区剩余空间都不足5G
1 node_filesystem_avail_bytes{mountpoint='/'}/(1024^3)
上述使用的“/”为数学运算的“除”,“^”为幂运算,同时也支持如下运算符:
+: 加
-: 减
*: 乘
/: 除
^: 幂运算
%: 求余
查询 k8s-master01 根区分磁盘可用率(剩余空间/总空间=可用率),可以通过如下指令进行计算:
1 2 node_filesystem_avail_bytes{mountpoint='/',instance='k8s-master01'}/node_filesystem_size_bytes{mountpoint='/',instance='k8s-master01'} # 通过下图可以看到可用率大概22%左右
在宿主机上执行df -h 可以看到 Use%使用率78%,所有可用率22%,上面计算的准确
查询所有主机根分区的可用率:
1 node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'}
也可以将结果乘以 100 直接得到百分比:
1 (node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'})*100
找到集群中根分区空间可用率小于25%的主机:
1 (node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'})*100 <25
PromQL也支持如下判断:
==: (相等)
!= :(不相等)
>:(大于)
< :(小于)
>= :(大于等于)
<= :(小于等于)
磁盘可用率大于 25%小于等于 60%的主机:
1 25 < ((node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'})*100)<=50
也可以用 and 进行联合查询:(磁盘可用率大于 25%小于等于 60%的主机:)
1 node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'}*100>25 and node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'}*100<=50
除了支持 and 外,也支持 or 和 unless :
and:并且,条件都满足
or:或者,满意一个条件即可
ubless:排除
查询主机磁盘剩余空间,并且排除掉shm和tmpfs的磁盘:
1 node_filesystem_size_bytes unless node_filesystem_size_bytes{device=~'shm|tmpfs'}
18.7PromQL常用函数 使用 sum 函数统计当前监控目标所有主机根分区剩余的空间:
1 sum(node_filesystem_size_bytes{mountpoint='/'})/1024^3
也可以用同样的方式计算所有的请求总量:以grafana_http_request_duration_seconds_count指标为例
1 2 # 统计请求总数 sum(grafana_http_request_duration_seconds_count)
根据 statuscode 字段进行统计请求数据:
1 sum(grafana_http_request_duration_seconds_count) by (status_code)
根据 statuscode 和 handler 两个指标进一步统计:
1 sum(grafana_http_request_duration_seconds_count) by (handler,status_source)
根据上述的结果,找到排名前五的:topk
1 topk(5,sum(grafana_http_request_duration_seconds_count) by (handler,status_source))
取最后三个数据:bottomk
1 bottomk(3,sum(grafana_http_request_duration_seconds_count) by (handler,status_source))
找出统计结果中最小的数据:
1 min(node_filesystem_avail_bytes{mountpoint="/"})
最大的数据:
1 max(node_filesystem_avail_bytes{mountpoint="/"})
平均值:
1 avg(node_filesystem_avail_bytes{mountpoint="/"})
四舍五入,向上取最接近的整数,2.79 3:
1 ceil(node_filesystem_files_free{mountpoint="/"} / 1024 / 1024)
向下取整数, 2.79 ==》 2:
1 floor(node_filesystem_files_free{mountpoint="/"} / 1024 / 1024)
对结果进行正向排序:
1 sort(sum(http_request_total) by (handler, statuscode))
对结果进行逆向排序:
1 sort_desc(sum(http_request_total) by (handler, statuscode))
函数 predict_linear 可以用于预测分析和预测性告警,比如可以根据一天的数据,预测 4 个小时后,磁盘分区的空间会不会小于 0:
1 predict_linear(node_filesystem_files_free{mountpoint="/"}[1d], 4*3600) < 20
除了上述的函数,还有几个比较重要的函数,比如 increase、rate、irate。其中 increase 是计算在一段时间范围内数据的增长(只能计算 count 类型的数据),rate 和 irate 是计算增长率。比如查询某个请求在 1 小时的时间增长了多少:
1 increase(grafana_http_request_duration_seconds_count{handler="/api/datasources/uid/:uid/resources/*", method="GET"}[1h])
将 1h 增长的数量除以该时间即为增长率:(除以3600秒,即每秒增长率)
1 increase(grafana_http_request_duration_seconds_count{handler="/api/datasources/uid/:uid/resources/*", method="GET"}[1h])/3600
相对于 increase,rate 可以直接计算出某个指标在给定时间范围内的增长率,比如还是计算1h 的增长率,可以用 rate 函数进行计算:
1 rate(grafana_http_request_duration_seconds_count{handler='/api/health'}[1h] )
irate :长尾效应
第十九章、云原生Alertmanager告警 待补充