5月27日 17:56
如何在 K8s 中部署 Prometheus 监控?
Prometheus 是 Kubernetes 生态中最主流的监控方案。本文覆盖 Helm 快速部署和 Prometheus Operator 生产级部署两种方式,并给出 ServiceMonitor 配置、自动发现、常用指标和排错要点。
一、部署方式选择
| 方式 | 适用场景 | 复杂度 |
|---|---|---|
| Helm + kube-prometheus-stack | 快速体验、测试环境 | 低 |
| Prometheus Operator | 生产环境、需要 CRD 管理 | 中 |
两种方式都推荐部署到独立命名空间(如 monitoring),避免与业务负载混用。
二、Helm 快速部署
2.1 安装 kube-prometheus-stack
kube-prometheus-stack 是社区维护的一体化 Chart,打包了 Prometheus、Alertmanager、Grafana 及常用 Exporter。
bash# 添加仓库 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update # 安装到 monitoring 命名空间 helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespace
2.2 验证部署状态
bashkubectl get pods -n monitoring # 预期看到 prometheus-operator、prometheus-prometheus、alertmanager、grafana 等 Pod 均为 Running
2.3 访问 Grafana 仪表盘
bash# 端口转发访问 Grafana kubectl port-forward svc/prometheus-grafana 3000:80 -n monitoring # 浏览器打开 http://localhost:3000,默认账号 admin/prom-operator
安装完成后 Grafana 已内置 Kubernetes 集群监控仪表盘,无需额外配置。
三、Prometheus Operator 部署(生产推荐)
Prometheus Operator 通过 CRD 管理 Prometheus 实例,无需手动维护配置文件,是生产环境的推荐方案。
3.1 核心 CRD 说明
| CRD | 作用 |
|---|---|
| Prometheus | 定义 Prometheus 实例,指定副本数、资源限制、存储卷 |
| Alertmanager | 定义告警管理器实例 |
| ServiceMonitor | 声明式配置监控目标,按 Label 选择 Service |
| PodMonitor | 直接按 Pod Label 选择监控目标(跳过 Service) |
| PrometheusRule | 管理告警规则和记录规则 |
3.2 部署 Operator
bash# 使用 kubectl apply 安装 Operator 及 CRD kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/example/rbac/prometheus-operator-deployment.yaml
3.3 创建 Prometheus 实例
yamlapiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: k8s namespace: monitoring spec: replicas: 2 serviceAccountName: prometheus-k8s serviceMonitorSelector: matchLabels: team: frontend resources: requests: cpu: 500m memory: 1Gi limits: cpu: "2" memory: 4Gi storage: volumeClaimTemplate: spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 50Gi
关键参数说明:
replicas: 2— 生产环境建议至少 2 副本实现高可用serviceMonitorSelector— 只匹配带有对应 Label 的 ServiceMonitorstorage— 必须配置 PersistentVolume,否则重启后数据丢失
四、ServiceMonitor 配置监控目标
ServiceMonitor 是 Operator 模式下配置采集目标的核心资源,通过 Label 选择器自动发现 Service。
yamlapiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: my-app namespace: monitoring labels: team: frontend # 需与 Prometheus 的 serviceMonitorSelector 匹配 spec: selector: matchLabels: app: my-app endpoints: - port: metrics interval: 30s path: /metrics namespaceSelector: matchNames: - default
配置要点:
labels.team必须与 Prometheus CR 的serviceMonitorSelector匹配,否则不会被抓取namespaceSelector指定从哪些命名空间发现 Serviceinterval不宜设置过短(< 15s),避免对目标服务造成压力
五、Kubernetes 自动发现
除 ServiceMonitor 外,也可通过原生 Prometheus 配置实现 Pod 自动发现:
yamlscrape_configs: - job_name: 'kubernetes-pods' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port] action: replace target_label: __address__ regex: (.+) replacement: ${1}
使用方式:在 Pod 的 annotation 中添加 prometheus.io/scrape: "true" 和 prometheus.io/port: "9090",Prometheus 即可自动采集。
建议:Operator 模式下优先使用 ServiceMonitor,自动发现适用于无法修改 CRD 的场景。
六、常用指标速查
| 类别 | 指标名 | 用途 |
|---|---|---|
| 容器 CPU | container_cpu_usage_seconds_total | 计算 CPU 使用率 |
| 容器内存 | container_memory_working_set_bytes | 实际使用内存(OOM 判定依据) |
| Pod 状态 | kube_pod_status_phase | Pod 运行状态统计 |
| 节点内存 | node_memory_MemAvailable_bytes | 节点可用内存 |
| 网络流量 | container_network_receive_bytes_total | 容器入站流量 |
CPU 使用率计算示例(PromQL):
shellrate(container_cpu_usage_seconds_total{container!="",pod!=""}[5m])
七、生产环境注意事项
- 资源限制必须设置 — Prometheus 内存占用随时间序列数增长,不设上限会 OOM 并影响节点上其他 Pod
- 持久化存储不可省略 — 默认使用 emptyDir,Pod 重启数据全部丢失,必须配置
volumeClaimTemplate - 采集间隔不宜过短 — 15s 是下限推荐值,大规模集群建议 30s-60s
- 使用 recording rules 降频 — 对高频查询的指标用 recording rule 预计算,减少实时查询压力
- 告警规则分优先级 — P0 级告警走即时通知(PagerDuty/电话),P1/P2 走邮件/IM
常见排错
| 现象 | 原因 | 解决 |
|---|---|---|
| Target 显示 0/0 active | ServiceMonitor Label 不匹配 | 检查 team Label 是否与 Prometheus CR 的 selector 一致 |
| Prometheus Pod CrashLoopBackOff | 内存不足 | 增大 resources.limits.memory |
| 指标数据缺失 | 采集目标未暴露 /metrics | 检查 Service 端口和 annotation |