ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

K8s集群监控部署:Prometheus与Grafana安装配置实战

K8s集群监控部署:Prometheus与Grafana安装配置实战 1. 为什么集群监控绕不开 Prometheus 和 Grafana 这套组合我在几个不同规模的 K8s 集群里都部署过监控栈从最开始用一堆零散脚本凑合到后来老老实实上 prometheus grafana踩的坑足够写一本小册子。Prometheus 负责采集和存储时序数据Grafana 负责把这些数据画成能看懂的图两者搭起来基本就是 K8s 集群监控的事实标准。你会发现不管是官方文档、社区文章还是大厂分享出来的方案绕来绕去最后都回到这套东西上。标题里说的“k8s集群部署Grafana安装和配置”本质上要解决三件事第一集群里跑着成百上千个容器它们的状态、资源、请求延迟怎么拿到第二拿到的数据放在哪、怎么查第三怎么让这些冷冰冰的指标变成一眼能判断问题的大盘。Prometheus 管前两件Grafana 管第三件。这套方案适合谁呢适合刚把 K8s 集群搭起来、准备上生产或者已经在小规模跑业务、但又不想花大钱买商业监控的团队。也适合运维、DevOps、SRE 这些每天跟集群打交道的朋友哪怕你之前只会在 Docker 里跑个端口映射这篇文章也能让你把整套监控栈在集群里跑起来。我先说一个很多人会疑惑的点为什么不在每个节点上装个传统的监控 agent比如 exporter 自建时序库就完事真实原因是 K8s 里的资源是动态的Pod 会漂移、会重建IP 会变服务往往还是通过 Service 暴露的。传统方式要么写死地址要么手工维护采集目标集群一扩容就乱套。而 Prometheus 的设计天然适配这种动态环境——它有一套服务发现的机制能自动从 API Server 里感知到新的目标配合 Operator 还能用声明式的方式管理采集规则这才是它能在 K8s 里站稳脚跟的根本原因。再聊聊 Grafana 为什么不能省。有人觉得自己写个脚本调 Prometheus 的 HTTP API 拿数据就够了。我试过前期看着挺美但一旦指标维度变多、查询逻辑变复杂脚本会迅速失控。Grafana 真正的价值在于它把查询、聚合、展示、告警这四件事统一到一个界面里而且社区里有大量现成的仪表盘模板导入就能用。比如 node_exporter 的标准大盘直接导入 ID 为 1860 的模板几十个指标图立马就有了省下的是整周的工作量。所以本文的路线是先把 Prometheus 在集群里跑通、采集到数据再接 Grafana 做可视化最后顺带把告警链路的思路理一遍。2. 部署前必须理清的整体架构与选型思路2.1 两种主流部署路线Operator 还是手写清单在 K8s 里部署 Prometheus社区主要有两条路一条是手动写 Deployment、Service、ConfigMap自己拼装各个组件另一条是用 kube-prometheus-stack 这个 Helm chart它底层基于 Prometheus Operator。我两种都做过给你一个明确的结论除非你所在的环境有严格的依赖管控否则优先上 Operator 这套。原因很实际。手写清单的时候每一个采集目标、每一条告警规则、每一份 Grafana 面板你都得通过 ConfigMap 挂载进容器改一次重启一次而且 Prometheus 的配置文件是原生的 YAML 格式跟 K8s 的 CRD自定义资源完全是两套语法。一旦集群里服务数量上来维护成本会呈指数级增长。而 Prometheus Operator 把“要监控什么”抽象成了 ServiceMonitor 和 PodMonitor 这类声明式资源——你只要写一个 ServiceMonitor选中带特定标签的 ServiceOperator 就会自动把它转换成 Prometheus 的采集配置全程不用碰原生配置。当然Operator 也不是没代价。它引入了一层抽象排错时你需要多理解几个 CRD 的含义而且版本兼容性有时候会出幺蛾子。但我个人的经验是学 Operator 的成本远远低于长期手工维护配置的成本。2.2 各组件的职责和联动关系在正式动手前咱们把这条链路上的角色一个个摆清楚不然后面看 YAML 会晕。Prometheus Server是核心负责抓取、存储、提供查询接口Alertmanager是告警分发中心Prometheus 自己只负责判断规则是否触发真正的去重、分组、发通知是 Alertmanager 干的Grafana是前端它不存数据只从 Prometheus 查node-exporter部署在每个节点上采集主机级别的 CPU、内存、磁盘、网络kube-state-metrics则负责把 K8s 对象的状态比如 Deployment 的副本数、Pod 的 Phase翻译成指标暴露出来。这几者之间的关系可以用一句话概括exporter 和各类 target 提供原始数据Prometheus 定时去拉Alertmanager 接收 Prometheus 推来的告警Grafana 从 Prometheus 拉数据画图。理解了这个数据流向你在配置 ServiceMonitor 或者调 Grafana 数据源的时候心里就有谱了。2.3 存储和资源规划要提前想清楚Prometheus 默认把数据存在容器本地目录Pod 一重建数据就没了。生产环境一定要挂持久卷。我见过一个案例某团队图省事没挂 PVC结果节点重启导致半个月的历史数据全丢出故障时连个对比基线都没有。所以在部署前先给 Prometheus 和 Grafana 各规划一块 PVC大小根据你的采集规模和保留周期来。一个经验值单节点、采集 1000 个左右时间序列、保留 15 天大概需要 20 到 30 GB。Grafana 那边主要存面板和用户配置1 到 2 GB 足够。资源这块Prometheus 对内存比较敏感每 100 万个活跃时间序列大约吃 1 到 2 GB 内存这个数量级心里要有数。可以先给 Prometheus 2 核 4G 的 requests 起步观察一周再调。Grafana 相对轻量1 核 1G 就能跑得不错。3. 从零开始的集群环境准备与命名空间规划3.1 集群基础检查动手前先确认你的集群状态正常这是老生常谈但每次都有人跳过。用下面几条命令过一遍kubectl get nodes -o wide kubectl get cs kubectl version --short节点必须是 Ready 状态几个核心组件健康客户端和服务端版本不要差太多。我之前遇到过一次诡异的问题kubectl 版本比 API Server 高了两三个小版本导致某些资源的 apply 行为不一致排查了半天。所以版本对齐这件事别嫌烦。如果你的集群是通过 kubeadm 搭的还要确认 API Server 的聚合层相关配置别被改乱了因为 Prometheus Operator 依赖 apiserver 的一些指标接口。不过一般标准安装的集群都没问题这一步更多是排除历史遗留的个性化配置。3.2 命名空间和 Helm 环境准备监控组件我习惯单独放到一个命名空间比如monitoring好处是资源隔离清晰删起来也干净。kubectl create namespace monitoring接着确认 helm 可用。Helm 版本建议 3.x 以上helm version如果没有 helm去官方渠道按你的操作系统装一个这一步不展开。然后添加 prometheus-community 仓库helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update这里插一句拉取 chart 的时候如果网络环境导致部分资源下载慢可以先把 chart 下载到本地再安装命令是helm pull prometheus-community/kube-prometheus-stack下载完是一个 tar 包解压后可以按自己的需要改 values。我强烈建议第一次安装前把 values.yaml 拉下来通读一遍不是照抄而是搞清楚默认打开了哪些组件、默认的告警规则都有哪些后续出问题至少知道去哪找。3.3 存储类的确认如果你的集群有默认 StorageClass创建 PVC 时可以不写 storageClassName直接走默认。检查方式kubectl get storageclass输出里带(default)字样的就是默认存储类。如果没有默认存储类你就得在安装时显式指定名字或者在 values 里给每个组件单独配 storageClass。这一点如果搞错PVC 会一直 PendingPod 起不来报错信息还比较隐晦很多时候只看到挂载失败其实根子在存储类上。4. Prometheus 部署全流程与核心配置拆解4.1 用 Helm 安装 kube-prometheus-stack基础环境就绪后一条命令就能把整套栈铺下去。但别急着直接 install先写一份精简的 values 文件控制关键参数。下面是我常用的一个最小可用配置# values-monitoring.yaml grafana: enabled: true persistence: enabled: true storageClassName: size: 2Gi adminPassword: 改成一个强密码 service: type: NodePort nodePort: 32000 prometheus: prometheusSpec: retention: 15d storageSpec: volumeClaimTemplate: spec: storageClassName: resources: requests: storage: 30Gi resources: requests: cpu: 500m memory: 2Gi limits: memory: 4Gi alertmanager: enabled: true alertmanagerSpec: storage: volumeClaimTemplate: spec: resources: requests: storage: 5Gi几个点解释一下。retention: 15d是数据保留时长按你的磁盘和查询需求权衡太短看不到趋势太长磁盘吃不消。storageClassName: 表示用集群默认的存储类如果集群没有默认类这里要填实际名字。Prometheus 的内存 limits 建议设得比 requests 高一档因为它在大查询时会有内存尖峰。安装命令helm install monitoring prometheus-community/kube-prometheus-stack \ -n monitoring \ -f values-monitoring.yaml装完看 Podkubectl get pods -n monitoring正常的话会看到 prometheus-0、alertmanager-0、grafana-xxx、kube-state-metrics、各个 node-exporter 的 DaemonSet Pod还有 operator 和 admission webhook。如果某几个 Pod 一直 CrashLoopBackOff先看 describe 和 logs最常见的原因就是存储没挂上或者 RBAC 权限不足。4.2 ServiceMonitor 是怎么把服务接入采集的这套栈装完后集群核心组件apiserver、kubelet、node-exporter、kube-state-metrics的监控其实已经默认配好了。但你自己的业务服务要接入监控就得靠 ServiceMonitor。它的原理我在前面提过再展开说一下。假设你有个服务叫order-service暴露了一个/metrics端点端口是 8080。你需要先有一个 Service 指向它然后写一个 ServiceMonitorapiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: order-service-monitor namespace: monitoring labels: release: monitoring spec: namespaceSelector: matchNames: - default selector: matchLabels: app: order-service endpoints: - port: metrics interval: 30s path: /metrics这里有个非常容易踩的坑ServiceMonitor 上的release: monitoring标签必须和 Operator 配置里的serviceMonitorSelector匹配否则 Operator 根本不会理你。默认情况下kube-prometheus-stack 会挑选带有自身 release 名字标签的 ServiceMonitor。很多人写完 ServiceMonitor 发现没数据排查半天问题就出在这个标签上。另一个坑是endpoints.port填的是 Service 里端口的名字不是端口号这两个概念别搞混。验证采集是否生效可以进 Prometheus 的 UI在 Status - Targets 页面看目标是不是 UP。也可以用 PromQL 查一下比如up{joborder-service}返回 1 就说明采集正常。4.3 访问 Prometheus 做一次数据验证默认情况下 Prometheus 的 Service 是 ClusterIP集群外访问不了。临时验证可以端口转发kubectl port-forward -n monitoring svc/monitoring-kube-prometheus-prometheus 9090:9090然后浏览器访问本机 9090。进去之后建议先干两件事一是在 Graph 页面执行up查询看看有多少目标、状态是否正常二是在 Status - Configuration 里确认你的采集配置有没有生效。我习惯用count(up 1)和count(up 0)对比一眼就能看出有多少目标挂了。如果你想让 Prometheus 长期可访问可以把它的 Service 类型改成 NodePort 或者配 Ingress。生产环境我更推荐 Ingress 加认证直接暴露 NodePort 有安全风险。说到安全Prometheus 2.24 以后支持了基础的 web 认证可以通过配置开启别把没认证的 Prometheus 直接暴露到公网。5. Grafana 安装配置与看板落地实操5.1 确认 Grafana 部署并首次登录kube-prometheus-stack 默认已经把 Grafana 装好了我们前面也配了 NodePort。查看服务kubectl get svc -n monitoring | grep grafana然后用节点IP:32000访问默认用户名 admin密码就是我们在 values 里设的那个。第一次登录强烈建议立刻改密码并创建单独的只读账号给团队成员用。我碰到过团队成员之间共用 admin 账号的情况有人不小心删了大盘或者改了数据源追责都追不到。如果 NodePort 方式访问不了先确认防火墙和节点安全组有没有放行。另外如果是云环境还得看节点本身的网络策略。排查顺序是Service 的 NodePort 是否正确、kube-proxy 是否正常、节点端口是否被占用。这几个排查完基本就能定位。5.2 对接 Prometheus 数据源Grafana 装好后数据源一般自动配好了指向集群内的 Prometheus Service。你可以在 Configuration - Data Sources 里确认。如果发现数据源连接失败最常见的原因有两个一是 URL 写错集群内访问要用完整的 Service 名加命名空间形如http://monitoring-kube-prometheus-prometheus.monitoring:9090二是网络策略或者命名空间隔离导致 Grafana 访问不到 Prometheus。我还遇到过一种情况Grafana 报 “failed to upgrade legacy queries datasource ... was not found”这通常是因为之前手动删除过数据源或者数据源 ID 变化导致旧面板引用的数据源失效。解决办法是重新创建一个数据源然后把老面板里的数据源引用批量替换过来。Grafana 新版本支持在数据源设置里指定一个固定的 UID给数据源设一个稳定的 UID以后就算删了重建只要 UID 不变面板就不会失效这个习惯我强烈建议养成。数据源配好后点 “Save Test”看到绿色的成功提示才算真正通了。这一步别偷懒很多人面板导入后一片空白就是因为数据源压根没连通。5.3 导入现成大盘模板Grafana 的社区大盘模板是它最大的优势之一。导入路径是左侧菜单 Dashboards - Import然后输入模板 ID。几个我常用且口碑不错的模板 ID用途说明1860Node Exporter Full主机级资源监控CPU、内存、磁盘、网络一应俱全315Kubernetes Cluster集群整体视角包含节点、Pod、容器资源6417Kubernetes Cluster (via Prometheus)另一套常用的 K8s 集群大盘13332Kube State Metrics v2面向 K8s 对象状态副本、重启次数等导入的时候要注意选择正确的数据源。如果模板里的变量和你的环境不匹配比如集群名对不上可以在模板的变量设置里调整datasource和cluster这类查询变量。导入后先别急着用花十分钟把每个面板点一遍确认数据都有值尤其是那些依赖特定 label 的面板很容易因为 label 命名不同而空白。5.4 告警接入的基本链路标题里没细说告警但既然上了监控告警早晚要做。链路是Prometheus 根据告警规则判断把触发的告警推给 AlertmanagerAlertmanager 做去重、分组、静默然后发到邮件、企业微信、钉钉或 webhook。kube-prometheus-stack 里默认带了一批告警规则你也可以通过 PrometheusRule 这个 CRD 加自己的规则。写告警规则时for 字段很关键它表示条件持续多久才真正触发。比如 CPU 使用率超过 80%如果是瞬时触发告警会响个不停设成for: 5m只有持续 5 分钟才告警噪音会少很多。另一个经验是给告警加好 severity 标签区分 warning 和 critical前端 Alertmanager 就能按级别分开发送不至于半夜被一个 warning 吵醒。Alertmanager 的配置在 values 里通过alertmanager.config注入接入企业微信或者 webhook 需要写 receiver这部分内容比较多本文先点到核心是先保证 Prometheus 能触发告警、Alertmanager 能收到再逐步对接具体的通知渠道。6. 常见问题排查与实操避坑清单6.1 高频问题速查下面这些是我和身边朋友在实际部署中反复遇到的整理成表方便对照现象可能原因处理方向PVC 一直 Pending没有默认 StorageClass 或 storageClassName 写错检查 storageclass显式指定正确类名Prometheus Pod 启动后反复重启内存 limit 太小或存储挂载失败调大 limits检查 PVC 状态ServiceMonitor 加了但没数据release 标签不匹配 Operator 选择器补上正确的 release labelGrafana 面板全空白数据源没连通或时间范围选错检查数据源 Save Test调整时间区间目标大量 DOWN采集目标网络不通或端口名写错检查 Service 端口名与 endpoints.port 一致告警一直重复for 字段没设或设得太短合理设置 for 时长配置分组数据源删后大盘失效数据源 UID 变化重建时固定 UID或批量替换引用6.2 几个文档里不会写的经验第一资源和存储永远比你想的吃得多。我刚开始部署时给 Prometheus 配了 1G 内存结果集群里 service 一多采集目标涨到几千个Prometheus 直接被 OOM Kill。后来学乖了先按经验值给足观察一周再调。监控系统本身要是挂了那真是雪上加霜。第二采集间隔别设太短。有人为了“实时”把 scrape interval 设成 5s结果时间序列数量暴涨磁盘和内存都吃不消。15s 到 30s 对绝大多数业务场景足够了除非你有明确的亚秒级需求。缩短采集间隔带来的成本是线性的甚至更高的收益却往往有限这笔账要算清楚。第三标签基数要控制。Prometheus 的 label 组合会形成独立的时间序列。如果你在指标里塞了个用户 ID 或者请求 URL 这种高基数标签时间序列数量会爆炸内存和查询都会崩。别把订单号、UUID 这类东西做成 label这是把 Prometheus 玩坏的最快方式没有之一。第四升级要谨慎。kube-prometheus-stack 的版本升级偶尔会带来 CRD 变更升级前先看 changelog在测试环境走一遍。生产集群直接helm upgrade一路绿灯的情况不多我至少遇到过两次因为 CRD 不兼容导致 Operator 起不来的情况回滚还算顺利但心跳是实打实加速了。6.3 让这套栈长期稳定运行的建议最后分享几个我坚持的习惯。给监控组件本身也加监控用 Prometheus 的 self metrics 监控它自己的抓取耗时、目标数量、内存使用做到早发现早处理。定期检查磁盘水位Prometheus 的 TSDB 目录增长是持续的磁盘满了会导致写入失败。把 Grafana 的大盘和告警规则纳入版本管理用 Git 存起来别只存在 Grafana 的数据库里机器一坏配置全没的教训太深刻了。我个人在实际操作中的体会是这套组合的上手门槛其实不高真正难的是长期运维中的细节把控——采集什么、不采集什么、告警怎么调、资源怎么扩。把这些想明白你的集群监控才算是真正立住了而不是装完就忘、出事才发现没数据。
返回列表