摘要: 本文记录了在 Kubernetes 1.36(代号 Haru)集群上,基于 kube-prometheus main 分支,从零搭建一套完整监控体系的全过程。涵盖版本兼容性检查、内网镜像替换、Grafana 调优、NetworkPolicy 处理以及 Nginx 反向代理配置等实战细节,适合内网/离线环境参考
一、为什么选择 kube-prometheus?
kube-prometheus 是 Prometheus Operator 官方提供的一站式监控方案,一套 YAML 文件即可部署以下全套组件:
相比 Helm Chart 方式,kube-prometheus 直接提供静态 YAML 清单,更适合内网离线环境——不需要 Helm,不需要联网拉 Chart,改好镜像地址直接 kubectl apply。
二、版本兼容性检查
这是部署前最关键的一步。kube-prometheus 的 main 分支跟随最新 K8s 版本,我们需要确认版本对应关系。
2.1 环境信息
/
2.2 下载代码
访问 GitHub克隆代码即可:
git clone https://g.1ab.asia/https://github.com/prometheus-operator/kube-prometheus.git三、镜像替换:从公网到内网仓库
3.1 检索所有用到的镜像
进入 manifests 目录,一条命令找出所有镜像引用:
cd kube-prometheus/manifests
grep "image:" ./*输出结果如下:
./alertmanager-alertmanager.yaml: image: quay.io/prometheus/alertmanager:v0.32.1
./blackboxExporter-deployment.yaml: image: quay.io/prometheus/blackbox-exporter:v0.28.0
./blackboxExporter-deployment.yaml: image: ghcr.io/jimmidyson/configmap-reload:v0.15.0
./blackboxExporter-deployment.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.22.0
./grafana-deployment.yaml: image: grafana/grafana:13.0.1
./kubeStateMetrics-deployment.yaml: image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.19.0
./kubeStateMetrics-deployment.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.22.0
./nodeExporter-daemonset.yaml: image: quay.io/prometheus/node-exporter:v1.11.1
./nodeExporter-daemonset.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.22.0
./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.91.0
./prometheusOperator-deployment.yaml: image: quay.io/brancz/kube-rbac-proxy:v0.22.0
./prometheus-prometheus.yaml: image: quay.io/prometheus/prometheus:v3.12.0共计 10 个不同的镜像(kube-rbac-proxy 被多个组件复用)。
3.3 批量操作脚本
在一台能同时访问公网和内网仓库的机器上执行:
#!/bin/bash
REGISTRY="register.abc.cn"
images=(
"quay.io/prometheus/alertmanager:v0.32.1"
"quay.io/prometheus/blackbox-exporter:v0.28.0"
"ghcr.io/jimmidyson/configmap-reload:v0.15.0"
"quay.io/brancz/kube-rbac-proxy:v0.22.0"
"grafana/grafana:13.0.1"
"registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.19.0"
"quay.io/prometheus/node-exporter:v1.11.1"
"registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.12.0"
"quay.io/prometheus-operator/prometheus-operator:v0.91.0"
"quay.io/prometheus/prometheus:v3.12.0"
)
for img in "${images[@]}"; do
echo ">>> Pulling $img"
docker pull "$img"
echo ">>> Tagging $img -> $REGISTRY/$img"
docker tag "$img" "$REGISTRY/$img"
echo ">>> Pushing $REGISTRY/$img"
docker push "$REGISTRY/$img"
echo ">>> Done: $img"
echo "---"
done3.4 修改 YAML 文件中的镜像地址
使用 sed 批量替换:
cd manifests/
# 替换所有镜像地址为内网仓库
sed -i 's|quay.io/|register.abc.cn/quay.io/|g' *.yaml
sed -i 's|ghcr.io/|register.abc.cn/ghcr.io/|g' *.yaml
sed -i 's|grafana/grafana|register.abc.cn/grafana/grafana|g' *.yaml
sed -i 's|registry.k8s.io/|register.abc.cn/registry.k8s.io/|g' *.yaml替换后再次验证:
grep "image:" ./*确认所有镜像都已指向 register.abc.cn 前缀即可。
四、Grafana 服务暴露:改为 NodePort
默认 Grafana Service 是 ClusterIP 类型,只能在集群内访问。我们将其改为 NodePort,配合后续 Nginx 反向代理对外提供服务。
修改 manifests/grafana-service.yaml:
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: grafana
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 13.0.1
name: grafana
namespace: monitoring
spec:
ports:
- name: http
nodePort: 30002
port: 3000
targetPort: http
selector:
app.kubernetes.io/component: grafana
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: kube-prometheus
type: NodePort关键改动:
•
type: ClusterIP→type: NodePort• 新增
nodePort: 30002,指定固定端口
⚠️ 注意:NodePort 范围为 30000-32767,确保 30002 未被其他服务占用。
五、Grafana 资源调优:解决查询崩溃问题
5.1 问题描述
kube-prometheus 默认给 Grafana 设置的资源限制非常保守:
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi在实际使用中,当执行大范围时间区间查询或加载多个 Dashboard 时,200Mi 的内存限制极易触发 OOMKilled,导致 Grafana Pod 反复重启。
5.2 调整方案
将 limits 提升至 2000m CPU / 2000Mi 内存,requests 保持不变:
resources:
limits:
cpu: 2000m
memory: 2000Mi
requests:
cpu: 100m
memory: 100Mi修改 manifests/grafana-deployment.yaml 中对应的 resources 段即可。完整的 Deployment 文件较长,核心改动部分如下:
# manifests/grafana-deployment.yaml(节选)
spec:
template:
spec:
containers:
- name: grafana
image: register.abc.cn/grafana/grafana:13.0.1 # 已替换为内网镜像
resources:
limits:
cpu: 2000m # ← 从 200m 提升
memory: 2000Mi # ← 从 200Mi 提升
requests:
cpu: 100m
memory: 100Mi💡 经验值参考:
• 小型集群(<50 节点):limits 500m/500Mi 通常够用
• 中型集群(50-200 节点):建议 1000m/1000Mi
• 大型集群(200+ 节点)或 Dashboard 较多:建议 2000m/2000Mi 起步
六、部署 kube-prometheus
6.1 部署顺序
必须先部署 setup 目录(包含 CRD、Namespace、RBAC 等基础资源),再部署 manifests 目录:
# 第一步:部署 CRD 和基础资源(使用 server-side apply)
kubectl apply --server-side -f ./setup
# 第二步:部署所有监控组件
kubectl create -f ./⚠️ setup 目录必须使用 --server-side 参数,因为部分 CRD 资源体积较大,客户端 apply 可能因 annotations 超长而失败。
6.2 验证部署状态
kubectl get pods -n monitoring预期所有 Pod 均为 Running 状态:
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 2/2 Running 0 5m
alertmanager-main-1 2/2 Running 0 5m
alertmanager-main-2 2/2 Running 0 5m
blackbox-exporter-xxx 3/3 Running 0 5m
grafana-xxx 1/1 Running 0 5m
kube-state-metrics-xxx 3/3 Running 0 5m
node-exporter-xxx 2/2 Running 0 5m
prometheus-adapter-xxx 1/1 Running 0 5m
prometheus-k8s-0 2/2 Running 0 5m
prometheus-k8s-1 2/2 Running 0 5m
prometheus-operator-xxx 2/2 Running 0 5m七、删除 NetworkPolicy(重要!)
kube-prometheus 默认为 Prometheus、Grafana、Alertmanager 创建了 NetworkPolicy,限制了只允许特定来源的流量。在大多数内网环境中,这会导致外部无法直接访问这些服务。
需要手动删除这三个 NetworkPolicy:
kubectl delete -f manifests/prometheus-networkPolicy.yaml
kubectl delete -f manifests/grafana-networkPolicy.yaml
kubectl delete -f manifests/alertmanager-networkPolicy.yaml💡 安全建议: 如果你的集群部署了 Calico 等支持 NetworkPolicy 的 CNI,且对网络安全有更高要求,建议不删除而是修改 NetworkPolicy 规则,放行特定 IP 段。
八、Nginx 反向代理配置
为了让团队通过域名 + HTTPS 访问 Grafana,我们在前端 Nginx 上配置反向代理。
8.1 HTTP 自动跳转 HTTPS
server {
listen 80;
server_name grafana.abc.cn;
rewrite ^ https://$server_name$request_uri? permanent;
}8.2 HTTPS 主配置
server {
listen 443 ssl;
server_name grafana.abc.cn;
ssl_certificate /opt/ssl/all.abc.cn/abc.cn.pem;
ssl_certificate_key /opt/ssl/all.abc.cn/abc.cn.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers 'HIGH:!aNULL:!MD5:!SHA:!DSS';
ssl_prefer_server_ciphers on;
# Grafana 主代理
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_pass http://ip:30002;
}
# Grafana Live WebSocket 支持(实时面板刷新)
location /api/live/ws {
proxy_pass http://ip:30002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}配置要点:
⚠️ 需要在 Nginx 的 http 块中定义 $connection_upgrade 变量:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}8.3 验证访问
配置完成后:
1. 访问 https://grafana.abc.cn
2. 默认账号密码:admin / admin(首次登录会要求修改密码)
3. 进入 Dashboard 页面,即可看到预置的 K8s 集群监控面板
九、部署后的检查清单
部署完成后,建议按以下清单逐项确认:
# ✅ 1. 所有 Pod 正常运行
kubectl get pods -n monitoring | grep -v Running
# ✅ 2. Prometheus Targets 正常(Web UI → Status → Targets)
# 所有 targets 状态应为 UP
# ✅ 3. Grafana 数据源连通(Data Sources → Prometheus → Test)
# ✅ 4. Dashboard 数据正常显示
# 重点关注:K8s Resources Cluster、Nodes、Pods 等核心面板
# ✅ 5. Alertmanager 可访问
# https://grafana2.abc.cn 同节点 9093 端口
# ✅ 6. 资源使用正常,无 OOMKilled
kubectl get pods -n monitoring -o wide
kubectl top pods -n monitoring
z
十、常见问题 FAQ
Q1:Pod 一直 ImagePullBackOff?
确认内网仓库地址可被所有 K8s 节点访问,且节点已配置仓库认证(如需要):
# 在每个节点上测试拉取
crictl pull register.abc.cn/grafana/grafana:13.0.1Q2:Grafana 面板显示 "No Data"?
检查 Prometheus 数据源配置是否正确,通常 URL 为 http://prometheus-k8s.monitoring.svc:9090。
Q3:NetworkPolicy 删了还是不生效?
确认你的 CNI 插件支持 NetworkPolicy。如果用的是 Flannel 等不支持的 CNI,NetworkPolicy 本身就不会生效,无需删除。
Q4:prometheus-operator 的 CRD 冲突?
如果集群已有旧版 CRD,使用 --server-side --force-conflicts 参数:
kubectl apply --server-side --force-conflicts -f ./setup十一、总结
本文完整记录了在 K8s 1.36 + 内网离线环境 下部署 kube-prometheus 的全流程:
下载代码 → 镜像替换 → Grafana NodePort → 资源调优 → 部署 → 删除 NetworkPolicy → Nginx 代理关键经验总结:
1. 版本对齐是前提 —— main 分支对应最新 K8s,务必确认兼容性矩阵
2. 镜像替换要彻底 —— 用 grep 全量检索,不要遗漏任何 YAML 文件
3. Grafana 默认 limit 太低 —— 生产环境至少给到 1000Mi 内存
4. NetworkPolicy 是隐形杀手 —— 部署后访问不通,首先排查它
5. WebSocket 配置别遗漏 —— Grafana 13.x 的 Live 功能需要单独的 WS 代理配置