Kubernetes监控实战: 使用Prometheus和Grafana

## Kubernetes监控实战: 使用Prometheus和Grafana构建高效可观测体系

**Meta描述:** 深入实战指南,详解如何在Kubernetes集群中部署配置Prometheus监控系统与Grafana可视化平台。涵盖Operator安装、指标抓取、核心仪表盘配置、告警规则编写及最佳实践,提升容器化应用可观测性。

## 一、 Kubernetes监控:复杂环境下的核心挑战

在**Kubernetes**(K8s)主导的云原生时代,容器化应用带来了前所未有的动态性与复杂性。传统的监控手段难以应对Pod(容器组)的频繁启停、服务发现的动态变化以及微服务架构下爆炸式增长的指标数据。**Kubernetes监控**的核心挑战在于:

1. **动态性跟踪**:Pod、Service(服务)、Endpoint(端点)等资源生命周期短暂,监控目标需实时发现。

2. **多维度指标**:需采集基础设施(节点Node)、**Kubernetes**对象(Pod、Deployment部署、StatefulSet有状态集等)及应用层指标。

3. **服务发现集成**:监控系统必须无缝对接Kubernetes API Server(API服务器),自动发现监控目标。

4. **大规模与高性能**:需处理海量时间序列数据,具备高效的存储与查询能力。

5. **统一可观测性**:整合指标(Metrics)、日志(Logs)、追踪(Traces)数据,提供统一视图。

**Prometheus**作为CNCF(云原生计算基金会)毕业项目,凭借其强大的**Pull(拉取)模型**、灵活的**服务发现**机制、高效的**TSDB(时间序列数据库)** 以及强大的**PromQL(Prometheus查询语言)** ,成为**Kubernetes监控**的事实标准。**Grafana**则以其卓越的数据**可视化**能力和丰富的**仪表盘**生态,成为展示**Prometheus**数据的最佳搭档。

## 二、 Prometheus核心架构:专为云原生设计

理解**Prometheus**的核心组件和工作原理是构建监控体系的基石:

1. **Prometheus Server**:

* **Retrieval(抓取器)**:根据配置(`scrape_configs`),通过服务发现(如Kubernetes SD)动态获取目标列表,定期(`scrape_interval`)发起HTTP请求拉取指标数据。

* **Storage(存储)**:使用高效的本地TSDB存储抓取到的指标数据。V3版本后采用WAL(Write-Ahead Log预写日志)和分块存储,性能大幅提升(单实例可轻松处理数百万时间序列)。

* **HTTP Server**:提供Web UI、API(供Grafana查询)和告警规则触发入口。

* **PromQL**:强大的多维数据查询语言,支持聚合、切片、预测等操作。

2. **Exporters(导出器)**:将第三方系统(如节点资源、数据库、中间件、应用)的指标转换为**Prometheus**可识别的格式(通常是/metrics端点暴露的纯文本)。

* 核心Exporters:

* `node_exporter`:采集主机(Node)硬件和OS指标(CPU、内存、磁盘、网络)。

* `kube-state-metrics`:监听Kubernetes API,生成关于集群对象(Pod状态、Deployment副本数、资源请求/限制等)的指标。

* `cAdvisor`:通常内置于Kubelet,提供容器级别的资源使用和性能指标(CPU、内存、文件系统、网络)。**Prometheus**通过Kubelet的`/metrics/cadvisor`端点抓取。

3. **Service Discovery(服务发现)**:**Prometheus**支持多种SD机制。在**Kubernetes**环境中,主要依赖`kubernetes_sd_configs`,自动发现以下角色:

* `node`:集群节点。

* `service`:服务及其关联的Endpoint。

* `pod`:所有Pod(或其子集)。

* `endpoints`:服务Endpoint。

* `ingress`:Ingress对象。

4. **Alertmanager**:独立组件,负责接收**Prometheus Server**发出的告警,进行**分组(Grouping)**、**抑制(Inhibition)**、**静默(Silencing)** 处理,并通过多种渠道(Email、Slack、PagerDuty、Webhook)发送通知。

## 三、 Kubernetes部署Prometheus生态:Operator简化管理

在**Kubernetes**中手动部署和管理原生**Prometheus**配置(ConfigMap、ServiceMonitor等)较为繁琐。**Prometheus Operator**通过自定义资源定义(CRD)极大地简化了这一过程。

### 3.1 安装Prometheus Operator

使用Helm(包管理器)是推荐方式:

```bash

# 添加Prometheus社区仓库

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

helm repo update

# 在命名空间monitoring中安装kube-prometheus-stack

# 该Chart包含Operator、Prometheus、Alertmanager、Grafana及常用Exporters

helm install kube-prom prometheus-community/kube-prometheus-stack \

-n monitoring --create-namespace \

--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \

--set grafana.service.type=LoadBalancer # 根据实际环境调整Service类型

```

### 3.2 部署关键Exporters

* **node_exporter**:Operator通常已通过DaemonSet自动部署到每个节点。

* **kube-state-metrics**:Operator通常也已自动部署。

验证部署状态:

```bash

kubectl get pods,daemonsets,deployments -n monitoring

# 预期输出应包含prometheus-kube-prom-prometheus-0 (StatefulSet), prometheus-kube-prom-operator, node-exporter (DaemonSet), kube-state-metrics等Pod

```

### 3.3 配置Prometheus抓取规则 (ServiceMonitor)

Operator使用`ServiceMonitor` CRD定义抓取目标。示例:监控所有命名空间中带有`prometheus.io/scrape: "true"`注解的Service:

```yaml

# my-app-service-monitor.yaml

apiVersion: monitoring.coreos.com/v1

kind: ServiceMonitor

metadata:

name: my-app-monitor

namespace: monitoring # ServiceMonitor通常部署在Operator所在NS

spec:

selector:

matchLabels:

app: my-important-app # 选择特定标签的Service

# 或使用基于注解的选择器:

# selector:

# matchExpressions:

# - key: prometheus.io/scrape

# operator: Exists

namespaceSelector:

any: true # 监控所有命名空间,或指定特定命名空间列表

endpoints:

- port: web # 匹配Service中名为'web'的端口

interval: 30s # 覆盖全局抓取间隔

path: /metrics # 指标暴露路径,默认为/metrics

# 可配置TLS、认证等

```

应用配置:`kubectl apply -f my-app-service-monitor.yaml`。Operator会自动将规则转换为**Prometheus**的配置。

### 3.4 验证Prometheus目标状态

访问**Prometheus** Web UI(通常通过端口转发`kubectl port-forward svc/prometheus-kube-prom-prometheus -n monitoring 9090:9090`),导航到`Status -> Targets`。所有配置的目标(包括Kubernetes SD自动发现的目标和ServiceMonitor定义的目标)应显示为`UP`状态。

## 四、 核心监控指标解析与PromQL实践

理解关键指标是有效监控的前提。以下是**Kubernetes监控**的核心维度:

### 4.1 基础设施层 (Node)

* **资源利用率**:

* `node_cpu_seconds_total{mode!="idle"}`:非空闲CPU总时间。计算使用率:`1 - avg(rate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)`

* `node_memory_MemAvailable_bytes`:可用内存。计算使用率:`(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes`

* `node_filesystem_avail_bytes{mountpoint="/", device!~"tmpfs|rootfs"}`:根文件系统可用空间。

* `node_network_receive_bytes_total` / `node_network_transmit_bytes_total`:网络流量。

* **关键告警指标**:

* Node内存压力:`node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 10`

* Node CPU负载过高:`sum(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance) / on(instance) count(sum(node_cpu_seconds_total) by (instance, cpu)) by (instance) > 0.8` (5分钟平均负载 > 80%)

* ?磁盘空间不足:`node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100 < 15`

### 4.2 Kubernetes对象层

* **Pod状态** (`kube_pod_status_phase`):

* 统计非Running状态的Pod:`sum(kube_pod_status_phase{phase!="Running"}) by (namespace, phase)`

* Pod重启次数激增:`increase(kube_pod_container_status_restarts_total[5m]) > 3` (5分钟内重启超过3次)

* **工作负载状态**:

* Deployment副本数不足:`kube_deployment_status_replicas_available / kube_deployment_spec_replicas * 100 < 90`

* StatefulSet副本就绪数:`kube_statefulset_status_replicas_ready`

* **资源请求与限制** (`kube_pod_container_resource_*`):

* Pod内存使用接近Limit:`(container_memory_working_set_bytes{container!="", pod!=""} / on(namespace, pod, container) kube_pod_container_resource_limits{resource="memory"}) * 100 > 90`

* CPU Throttling高:`sum(rate(container_cpu_cfs_throttled_periods_total[5m])) by (container, pod, namespace) / sum(rate(container_cpu_cfs_periods_total[5m])) by (container, pod, namespace) * 100 > 30` (5分钟内CPU被限制的时间占比 > 30%)

### 4.3 应用层 (由应用自身暴露)

* HTTP请求延迟:`http_request_duration_seconds_bucket`

* HTTP错误率:`rate(http_requests_total{status_code=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100 > 5`

* 应用特定业务指标(如订单处理速率、队列积压等)。

## 五、 Grafana可视化:构建高效监控仪表盘

**Grafana**是连接**Prometheus**数据的桥梁,提供强大的可视化能力。

### 5.1 配置Grafana数据源

1. 访问Grafana UI(端口转发或通过LoadBalancer Service暴露)。

2. 导航到`Configuration -> Data Sources`。

3. 点击`Add data source`,选择`Prometheus`。

4. URL填写**Prometheus** Service的DNS名(如`http://prometheus-kube-prom-prometheus.monitoring.svc.cluster.local:9090`)。

5. 保存并测试连接。

### 5.2 导入核心Kubernetes仪表盘

社区提供了大量高质量仪表盘模板:

1. **Node Exporter Full** (ID: 1860):全面的主机监控视图。

2. **Kubernetes / Compute Resources / Cluster** (ID: 6417):集群整体资源概览。

3. **Kubernetes / Compute Resources / Namespace (Pods)** (ID: 6418):按命名空间查看Pod资源使用。

4. **Kubernetes / Compute Resources / Pod** (ID: 6419):单个Pod详细资源分析。

5. **Kubernetes / Kubelet** (ID: 10619):Kubelet性能监控。

6. **Prometheus Stats** (ID: 3662):**Prometheus**自身健康状态。

导入步骤:

1. 在Grafana侧边栏选择`Create -> Import`。

2. 输入仪表盘ID(如`1860`)。

3. 选择之前配置的**Prometheus**数据源。

4. 点击`Import`。

### 5.3 构建自定义仪表盘与Panel

**Grafana**的核心是Panel。常用Panel类型:

* **Graph**:展示时间序列数据。

* **Stat**:显示单个重要数值。

* **Table**:以表格形式展示数据。

* **Gauge** / **Bar Gauge**:仪表盘或进度条。

* **Heatmap**:展示数据分布密度。

**示例:创建Pod内存使用率Panel**

1. 新建Dashboard -> Add Panel。

2. 数据源选择Prometheus。

3. 输入PromQL查询:

```promql

# 计算每个Pod的内存使用率 (Working Set / Memory Limit)

(container_memory_working_set_bytes{container!="", pod!="", namespace="namespace"} / on(namespace, pod, container) kube_pod_container_resource_limits{resource="memory", namespace="namespace"}) * 100

```

4. 设置`Legend`格式为`{{pod}} - {{container}}`。

5. 在`Visualization`选项卡选择`Graph`,调整线条、颜色。

6. 添加`Thresholds`(如Warning=80%, Critical=90%)。

7. 设置Panel标题(如"Pod内存使用率(占Limit%)")。

8. 保存Panel和Dashboard。

**利用变量(Variables)实现动态过滤:**

1. 在Dashboard设置 -> Variables -> Add variable。

2. 定义变量:

* `Name`: `namespace`

* `Type`: `Query`

* `Data source`: Prometheus

* `Query`: `label_values(kube_pod_info, namespace)` (获取所有命名空间)

* `Multi-value` / `Include All option`: 按需启用。

3. 在Panel的PromQL中引用变量:`namespace="namespace"`。

## 六、 Alertmanager配置:精准高效的告警管理

告警是监控闭环的关键。**Prometheus**定义告警规则(`PrometheusRule` CRD),**Alertmanager**负责路由和通知。

### 6.1 定义告警规则 (PrometheusRule)

示例:定义Pod频繁重启告警

```yaml

# pod-restart-alert.yaml

apiVersion: monitoring.coreos.com/v1

kind: PrometheusRule

metadata:

name: pod-restart-alerts

namespace: monitoring

spec:

groups:

- name: pod-alerts

rules:

- alert: KubePodCrashLooping

expr: |

# 5分钟内重启次数超过5次,且最近1分钟处于非Running状态

increase(kube_pod_container_status_restarts_total[5m]) > 5

and on(pod, namespace) kube_pod_status_phase{phase!="Running"} == 1

for: 2m # 持续满足条件2分钟才触发

labels:

severity: critical # 设置严重级别

cluster: production-us-east # 附加集群标签

annotations:

summary: "Pod {{ labels.pod }} ({{ labels.namespace }}) is crash looping!"

description: "Pod {{ labels.pod }} in namespace {{ labels.namespace }} has restarted {{ value }} times in the last 5 minutes. This indicates a critical application issue."

runbook_url: "https://wiki.example.com/runbooks/pod-crashloop" # 指向处理文档

```

应用规则:`kubectl apply -f pod-restart-alert.yaml`。规则会被**Prometheus Server**加载。

### 6.2 配置Alertmanager路由与通知

通过`AlertmanagerConfig` CRD(或编辑Alertmanager Secret)配置:

```yaml

# alertmanager-config.yaml (片段)

apiVersion: monitoring.coreos.com/v1alpha1

kind: AlertmanagerConfig

metadata:

name: main-config

namespace: monitoring

spec:

route:

receiver: 'slack-critical' # 默认接收器

group_by: [namespace, alertname, cluster] # 按这些标签分组告警

group_wait: 30s # 初次等待时间,同组内新告警等待

group_interval: 5m # 同一组告警再次发送的间隔

repeat_interval: 4h # 相同告警重复发送的最小间隔

routes: # 子路由树,实现更精细路由

- match:

severity: warning

receiver: 'slack-warning'

continue: false # 匹配后不再继续向下路由

- match:

alertname: KubePodCrashLooping

receiver: 'pagerduty-app-team' # CrashLoop直接呼叫值班

receivers:

- name: 'slack-critical'

slack_configs:

- api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ' # Slack Webhook URL

channel: '#alerts-critical'

title: '{{ template "slack.default.title" . }}'

text: '{{ template "slack.default.text" . }}'

send_resolved: true # 发送恢复通知

- name: 'slack-warning'

slack_configs: [...类似配置...]

- name: 'pagerduty-app-team'

pagerduty_configs:

- routing_key: 'your-pagerduty-integration-key'

description: '{{ .CommonAnnotations.description }}'

severity: 'critical'

# 可配置抑制规则(inhibit_rules)、静默规则(silences)等

```

### 6.3 告警生命周期管理

* **分组(Grouping)**:将相似告警(如相同命名空间下的多个Pod内存不足)合并为一条通知,减少噪音。

* **抑制(Inhibition)**:当更高级别告警触发时,抑制相关低级别告警(如节点宕机时,抑制该节点上所有Pod的告警)。

* **静默(Silencing)**:在已知维护窗口或问题已识别但尚未解决时,临时屏蔽特定告警(通过Grafana或Alertmanager UI操作)。

* **告警状态**:

* `Inactive`:未触发。

* `Pending`:表达式为真,但持续时间未达`for`设置值。

* `Firing`:表达式为真且持续时间已达`for`值,告警已激活发送。

* `Resolved`:表达式不再为真,发送恢复通知(如果接收器配置了`send_resolved`)。

## 七、 高级主题与最佳实践

1. **长期存储与联邦(Federation)**:

* **挑战**:Prometheus TSDB默认本地存储,容量和持久性有限。

* **方案**:

* **Thanos** / **Cortex** / **VictoriaMetrics**:提供全局查询视图、无限存储、数据去重、降采样。

* **Prometheus联邦(Federation)**:上级Prometheus从下级拉取聚合数据。适合分层架构。

* **远程写(Remote Write)**:配置Prometheus将数据实时写入支持Remote Write协议的长期存储后端(如Thanos Receiver, Cortex, InfluxDB, TimescaleDB等)。

2. **高可用(HA)部署**:

* **Prometheus Server**:部署2个或更多副本,使用相同的配置(通过Operator的`prometheusSpec.replicas=2`)。它们独立抓取相同目标,通过Alertmanager的HA去重机制避免重复告警。

* **Alertmanager**:部署多个副本(`alertmanagerSpec.replicas=3`),它们通过Mesh网络自动组成集群,实现状态共享和通知去重。

3. **监控数据安全**:

* **指标端点安全**:为应用/metrics端点启用TLS和基础认证(Basic Auth)或Bearer Token。在ServiceMonitor或PodMonitor中配置相应的`tlsConfig`和`authorization`字段。

* **Prometheus API/Grafana访问控制**:使用Kubernetes Ingress + OAuth2 Proxy、Grafana内置Auth(配置Grafana.ini)、或Service Mesh(如Istio)进行身份认证和授权。

4. **资源配额与优化**:

* **限制资源**:为Prometheus、Alertmanager、Exporters设置合理的`requests/limits`(特别是内存)。TSDB非常吃内存。

* **指标抓取优化**:

* 调整`scrape_interval`(非关键指标可适当拉长间隔)。

* 使用`metric_relabel_configs`在抓取时丢弃不必要的指标(`action: drop`)或标签(`action: labeldrop`)。

* 在应用端使用Prometheus客户端库的注册/注销机制,仅暴露必要指标。

* **TSDB调优**:调整`--storage.tsdb.retention.time`(默认15天)、`--storage.tsdb.min-block-duration` / `--storage.tsdb.max-block-duration`(V2相关)、`--storage.tsdb.wal-compression`(启用WAL压缩)。

5. **日志与追踪集成**:

* **日志**:部署`Loki` + `Promtail`。在Grafana中配置Loki数据源,实现基于LogQL的日志查询,并与指标关联(使用`explore`功能)。

* **分布式追踪**:集成`Jaeger`或`Tempo`。在应用中注入OpenTelemetry或Jaeger Client。在Grafana中配置对应数据源,实现端到端的可观测性。

## 八、 结论:构建持续演进的监控体系

使用**Prometheus**和**Grafana**构建**Kubernetes监控**体系,为云原生应用提供了强大、灵活且可扩展的可观测性基础。通过**Prometheus Operator**简化部署管理,利用**ServiceMonitor**/**PodMonitor**实现动态目标发现,结合**PromQL**深入分析集群和应用状态,并通过**Grafana**实现直观的可视化和仪表盘共享。**Alertmanager**则确保了关键问题能够及时、准确地通知到相关人员。

**成功的监控不仅是工具的堆砌,更是一个持续迭代的过程:**

1. **迭代指标**:根据业务需求和运维经验,持续调整和增加监控指标。

2. **优化告警**:定期评审告警规则的有效性、准确性,优化阈值、路由和通知内容,减少噪音,提高告警的置信度(Signal-to-Noise Ratio)。

3. **容量规划**:随着集群规模增长,持续关注Prometheus的资源消耗(内存、磁盘IO、存储空间),适时引入长期存储方案(如Thanos)或优化策略。

4. **拥抱生态**:积极整合日志(Loki)、追踪(Jaeger/Tempo)等工具,构建真正的统一可观测性平台。

5. **文化驱动**:将监控数据融入日常运维、故障排查、性能优化和容量规划决策中,培养数据驱动的DevOps文化。

通过遵循本文的实战指南和最佳实践,我们能够建立起一个高效、可靠且可持续扩展的**Kubernetes监控**系统,为云原生应用的稳定运行和性能优化提供坚实保障。

---

**附录:常用Prometheus指标速查**

| 指标名称 | 来源 | 核心用途描述 | 关键标签示例 |

| :--------------------------------------------- | :------------ | :----------------------------------------------- | :------------------------------- |

| `node_cpu_seconds_total` | node_exporter | 节点CPU时间(按模式) | `cpu`, `mode` |

| `node_memory_MemAvailable_bytes` | node_exporter | 节点可用内存 | |

| `node_filesystem_avail_bytes` | node_exporter | 文件系统可用空间 | `mountpoint`, `device`, `fstype` |

| `kube_pod_status_phase` | ksm | Pod当前阶段(Running, Pending, Failed等) | `pod`, `namespace`, `phase` |

| `kube_pod_container_status_restarts_total` | ksm | 容器重启次数 | `pod`, `namespace`, `container` |

| `kube_deployment_status_replicas_available` | ksm | Deployment可用副本数 | `deployment`, `namespace` |

| `container_cpu_usage_seconds_total` | cAdvisor | 容器累计CPU使用时间 | `pod`, `container`, `namespace` |

| `container_memory_working_set_bytes` | cAdvisor | 容器内存工作集(实际使用量) | `pod`, `container`, `namespace` |

| `kube_pod_container_resource_limits` | ksm | 容器资源限制(CPU/Memory) | `pod`, `container`, `resource` |

| `kube_pod_container_resource_requests` | ksm | 容器资源请求(CPU/Memory) | `pod`, `container`, `resource` |

| `up` | Prometheus SD | 目标抓取是否成功(1=成功,0=失败) | `job`, `instance` |

| `scrape_duration_seconds` | Prometheus | Prometheus抓取目标耗时 | `job`, `instance` |

| `prometheus_tsdb_head_samples_appended_total` | Prometheus | Prometheus TSDB接收的样本数 | |

---

**技术标签:**

#Kubernetes监控 #Prometheus #Grafana #云原生监控 #容器监控 #DevOps #可观测性 #Alertmanager #ServiceMonitor #PromQL #Thanos #kube-state-metrics #cAdvisor #NodeExporter #监控仪表盘 #告警管理

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容