第 41 篇 k8s之监控:Metrics Server 与 Prometheus 快速上手

IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。


在第 6 篇中,我们学会了用 docker stats 实时查看容器的 CPU 和内存使用。在 Docker Compose 的单机环境下,这基本够用------毕竟所有容器都挤在一台宿主机上,出问题了你也可以快速定位。

但在 Kubernetes 集群中,一切都变了。

Pod 可能在节点间漂移,Deployment 可能会静默地增加副本,一个微小的内存泄漏可能在几个小时后压垮整个节点。没有一套好的监控体系,你就像在黑夜里飞行------看不到速度、高度,也看不到前方是否有山峰。

这一篇,我们就来点亮这盏探照灯,从 Metrics ServerPrometheus,系统性地构建起对集群和应用的"上帝视角"。

一、为什么需要专业的监控?

Kubernetes 本身并不会自动告诉你 Pod 是否健康、资源是否充足------它只负责调度。要了解集群的"身体状况",你需要两样东西:

  1. 资源指标(CPU、内存、磁盘等),供 Scheduler 和 HPA 使用。

  2. 应用指标(请求速率、错误率、延迟等),供开发者和运维人员分析。

Docker Compose 时代,我们只能通过 docker statsctop 获取非常有限的实时数据,没有历史趋势,也没有告警能力。而 Kubernetes 生态提供了一条完整的监控链:

Metrics Server → 聚合资源指标,点亮 kubectl top,驱动 HPA。

Prometheus + Grafana → 采集、存储、可视化任何自定义指标,并触发告警。

二、部署 Metrics Server:让 kubectl top 工作

2.1 Metrics Server 的作用

Metrics Server 是 Kubernetes 官方维护的轻量级资源指标聚合器。它从每个节点的 kubelet 收集 CPU 和内存数据,并通过 Metrics API 暴露出来。

没有它:

  • kubectl top 命令会报错。

  • HPA(水平自动伸缩)无法根据 CPU/内存使用率自动调整副本数。

2.2 在 Minikube 中启用

Minikube 通常默认不启用 Metrics Server,我们需要手动开启:

bash 复制代码
minikube addons enable metrics-server

输出:

bash 复制代码
🌟  The 'metrics-server' addon is enabled

验证安装:

bash 复制代码
kubectl get pods -n kube-system -l k8s-app=metrics-server
# NAME                             READY   STATUS    RESTARTS   AGE
# metrics-server-xxxxxxxxxx-xxxxx  1/1     Running   0          60s

2.3 体验 kubectl top

bash 复制代码
# 查看节点资源使用情况
kubectl top nodes

输出:

bash 复制代码
NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
minikube   150m         7%     1200Mi          31%
bash 复制代码
# 查看 Pod 资源使用情况
kubectl top pods -n default

输出:

bash 复制代码
NAME                                CPU(cores)   MEMORY(bytes)
flask-deployment-xxxxxxxxx-xxxxx    25m          95Mi
redis-xxxxxxxxxx-xxxxx              10m          15Mi

现在,kubectl top 成为了你的第一个集群级监控工具。但要记住,它只反映当前时刻的快照,没有历史数据,也没有应用层面的指标。

三、部署 Prometheus + Grafana 监控栈

对于生产级监控,Prometheus 是事实上的标准。它是 CNCF(云原生计算基金会)继 Kubernetes 之后第二个毕业的项目。它基于"拉取"模式工作:Prometheus 服务器定期从目标(如 Pod、Service)的 HTTP 端点抓取指标数据,存储在内部时序数据库中。

我们将使用 kube-prometheus-stack 这个 Helm Chart 来一次性部署 Prometheus、Grafana 和 Alertmanager。

3.1 使用 Helm 部署

bash 复制代码
# 添加 Prometheus Community 仓库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# 安装 kube-prometheus-stack
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace \
  --set grafana.adminPassword=admin123

输出:

bash 复制代码
Release "monitoring" does not exist. Installing it now.
NAME: monitoring
LAST DEPLOYED: Mon May 27 10:00:00 2025
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
NOTES:
...

这条命令部署了以下组件:

3.2 访问 Grafana

Grafana 默认通过 ClusterIP 暴露,我们用 kubectl port-forward 来访问:

bash 复制代码
kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80

然后在浏览器中打开 http://localhost:3000,使用用户名 admin 和你设置的密码登录。

登录后,点击左侧 "Dashboards",你会发现很多预置的仪表板,例如:

  • Kubernetes / Compute Resources / Pod:Pod 的 CPU、内存、网络 IO 仪表板。

  • Kubernetes / Compute Resources / Cluster:集群整体资源概览。

四、监控贯穿案例:Flask 计数器应用

现在,我们要把贯穿始终的 Flask + Redis 计数器应用 接入 Prometheus 监控。

4.1 为 Flask 应用添加指标端点

为了让 Prometheus 能抓取数据,我们的 Flask 应用需要暴露一个 /metrics 端点。我们使用 prometheus_flask_exporter 库。

修改 app.py

bash 复制代码
from prometheus_flask_exporter import PrometheusMetrics
...
app = Flask(__name__)
metrics = PrometheusMetrics(app)  # 自动为每个请求生成计数器/延迟直方图

# 添加一个自定义业务指标:当前访问总数
info = metrics.info('app_info', 'Application info', version='3.0')
...

同时更新 requirements.txt 添加依赖:

bash 复制代码
prometheus_flask_exporter==0.23.1

构建新镜像 flask-redis-counter:3.0-monitoring,推送到 Minikube 环境并更新 Deployment。

4.2 创建 ServiceMonitor 让 Prometheus 发现目标

Prometheus Operator 使用 ServiceMonitor 来自动发现需要抓取的目标。我们只需创建一个 ServiceMonitor 指向我们的 Flask Service。

bash 复制代码
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: flask-app-monitor
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: flask-counter  # 匹配 Flask Service 的标签
  endpoints:
    - port: http
      path: /metrics
      interval: 15s

假设你的 Flask Service 有标签 app: flask-counter 且端口名称为 http(或指定端口号)。

bash 复制代码
kubectl apply -f servicemonitor.yaml

稍等片刻,Prometheus 就会自动发现并开始抓取 Flask 应用的指标。

4.3 在 Grafana 中查看应用指标

回到 Grafana,我们导入一个简单的 Flask 仪表板,或者直接在新仪表板中创建面板:

  1. 点击 "+" → "Import",输入仪表板 ID(如 11572 是一个通用的 Flask 仪表板),Prometheus 数据源选择 Prometheus

  2. 加载后,你会看到:

    • 请求速率 (Request Rate):随着 curl 或浏览器访问,曲线上下波动。

    • 错误率(Error Rate):如果触发了 500 错误,这里的线条会飙升。

    • 请求延迟(Request Duration):P50、P95、P99 延迟分布。

    • 应用自定义指标 :比如我们定义的访问总次数计数器 flask_http_request_total

模拟高负载

使用 wrkabhttp://<Ingress-IP>/counter 发起持续并发请求。你会看到 Grafana 中的 CPU 和请求速率指标迅速攀升。当 CPU 使用率超过我们设定的 HPA 阈值(例如 50%),HPA 会自动增加 Pod 副本数,这在 第 36 篇资源管理 中提到的 ResourceQuota 和后续的弹性伸缩中将发挥关键作用。

此时,文字描述一下仪表板上的变化趋势(因为无法截图):

  • Grafana 仪表板上,flask_http_request_total 计数器持续线性增长,rate(flask_http_request_total[5m]) 显示当前 QPS 稳定在 120 左右。

  • node_cpu_seconds_total 面板显示集群节点 CPU 使用率从 15% 上升到 65%。

  • *container_memory_usage_bytes 面板显示 Flask Pod 内存使用稳定在 100MiB~128MiB 之间,符合我们设置的 Requests/Limits。*

五、告警:让监控主动说话

监控的目的是在问题发生时及时通知我们,而不是等用户投诉后才去查看仪表板。Prometheus 通过 Alertmanager 实现这一功能。

5.1 创建一个告警规则

我们定义一个规则:如果某个 Pod 在最近 5 分钟内频繁重启(超过 2 次),就触发告警。

bash 复制代码
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: pod-restart-alert
  namespace: monitoring
spec:
  groups:
    - name: pod-restart
      rules:
        - alert: PodFrequentlyRestarting
          expr: rate(kube_pod_container_status_restarts_total{namespace="default"}[5m]) > 2
          for: 1m
          labels:
            severity: warning
          annotations:
            summary: "Pod {{ $labels.pod }} is restarting frequently"
            description: "Pod {{ $labels.pod }} in namespace {{ $labels.namespace }} has restarted {{ $value }} times in the last 5 minutes."

应用此规则后,如果某个 Pod(比如配置错误导致 CrashLoopBackOff)频繁重启,Prometheus 会将告警发送给 Alertmanager。

5.2 配置 Alertmanager 通知

kube-prometheus-stackvalues.yaml 中可以配置 Alertmanager 的通知方式(如 Email、Slack、Webhook)。这里我们模拟一个 Slack 通知:

bash 复制代码
alertmanager:
  config:
    receivers:
      - name: 'slack'
        slack_configs:
          - api_url: 'https://hooks.slack.com/services/...'
            channel: '#k8s-alerts'
    route:
      receiver: 'slack'
      group_by: ['alertname']
      group_wait: 10s
      group_interval: 10s
      repeat_interval: 1h

告警效果描述

当你故意将 Flask Deployment 的镜像改为一个不存在的版本(触发 ImagePullBackOff),Alertmanager 会在 1 分钟内检测到 Pod 频繁重启,并发送如下告警到 Slack:

*"Alert: PodFrequentlyRestarting, Severity: warning, Pod flask-deployment-xxxxxxxx-xxxxx has restarted 3 times in the last 5 minutes."*

六、技术演进路线图

从 Docker 到 K8s 的监控能力演进:

  • 单机容器化(Docker)docker statsctop 提供即时快照,无历史,无告警。

  • 单机编排(Compose):同上,依赖宿主机工具。

  • 集群编排(K8s 核心对象) :Metrics Server 提供基础资源指标,支持 kubectl top 和 HPA。

  • 生产级运维(监控、日志等):Prometheus + Grafana + Alertmanager 构建起完整的监控、可视化与告警闭环。

至此,你的集群不再是一个"黑盒"。你可以回答下面这些关键问题:

  • 集群还有多少资源可用?

  • 为什么这个 Deployment 的响应变慢了?

  • 如何提前收到磁盘即将耗尽的通知?

七、本篇总结

  • Metrics Server 是 K8s 资源监控的基石,为 kubectl top 和 HPA 提供数据。

  • Prometheus Stack 提供了从指标采集、存储、可视化(Grafana)到告警(Alertmanager)的一站式方案。

  • 监控实战:我们将 Flask 应用接入 Prometheus,查看了请求速率、错误率等指标,并创建了 Pod 重启告警规则。

通过这篇,你初步构建了 K8s 的"神经系统"。但监控只解决了"发现问题",日志则用于"定位原因"。下一篇------第 42 篇:日志管理:使用 EFK 或 Loki 采集日志,我们将深入日志聚合的世界,用 Loki 优雅地管理所有容器日志。

想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !

相关推荐
Junsir大斗师2 小时前
rocky9.7搭建grafana+loki+prometheus+alloy+node_exporter运维监控平台
linux·运维·grafana·prometheus
呆萌的代Ma2 小时前
解决docker网络问题,通过GitHub Actions打包dockerfile
docker·容器·github
qq_452396232 小时前
第十七篇:《Docker 日志管理:驱动配置与集中收集》
运维·docker·容器
张青贤2 小时前
centos7通过kubekey部署k8s集群
kubernetes·etcd·kubekey
SilentSamsara2 小时前
Python 服务的 K8s 部署:HPA/ConfigMap/Secret 完整配置
开发语言·python·青少年编程·容器·kubernetes
Plastic garden2 小时前
K8s(1)前置ansible准备环境
容器·kubernetes·ansible
lwx9148522 小时前
Kubernets-单节点部署k8s环境
云原生·容器·kubernetes
Dontla2 小时前
WSL2 docker-desktop发行版介绍(用于运行Docker引擎(Docker Engine))(docker-desktop-data)
运维·docker·容器
qq_452396233 小时前
第十六篇:《Docker 安全基础:容器隔离与权限控制》
安全·docker·容器