Kubernetes 集群监控
运维平台采集 Kubernetes 的节点资源、容器资源(cAdvisor)和集群对象状态 (kube-state-metrics),在前端「资源监控 → K8s」面板展示节点、Pod、Deployment、容器等视图。
先回答一个问题:运维平台装在被监控集群里吗?
这决定了你要做什么,两条路差别很大:
| 你的情况 | 要做什么 |
|---|---|
平台就装在被监控集群里(K8s 部署,无论 ops.yaml 还是 k8s-cluster/) | 什么都不用做,装完即有数据。直接跳到验证 |
| 平台在集群外(单机部署,另有 K8s 要监控) | 在被监控集群里装采集组件 |
| 要监控多个 K8s 集群 | 本集群照常自采,其余每个集群各装一套采集组件,见监控多个集群 |
无论哪条路,抓 kubelet / cAdvisor / kube-state-metrics 的都是跑在那个集群里的 Pod, 靠自己挂载的 ServiceAccount 访问 apiserver。所以不需要暴露任何 NodePort, Bearer Token 也不出集群。
1.5.3 移除的集群外拉取(static)方式正相反:要配 Bearer Token、把 apiserver、kubelet、 kube-state-metrics 经三个 NodePort 暴露出来,集群越多暴露面越大。同时移除的还有 「Kubernetes 集群」数据源类型——现在 K8s 不通过数据源配置,UI 上找不到它是正常的。
平台在被监控集群内:装完即有
K8s 形态的部署清单里已经带齐了三样东西,不用另外配:
| 组件 | 在哪 |
|---|---|
ENV_K8S_MONITOR_MODE: "incluster" | ConfigMap(ops.yaml 顶部 / 11-configmap.yaml) |
| Prometheus 的 ServiceAccount + ClusterRole | 同一份 ops.yaml 末尾 / 20-rbac.yaml |
| kube-state-metrics | 同一份 ops.yaml 末尾 / 40-stateless.yaml 的 ops-ksm |
平台自己的 Prometheus 直接采本集群,数据落本地 TSDB,不需要也不要配 remote_write
(配了等于自己推给自己,白多一跳)。
1.5.7 之前的 ops.yaml 单文件清单里没有 RBAC 和 kube-state-metrics,K8s 面板会一直空着。
重新下载 ops.yaml 覆盖 apply 即可补上,不影响已有数据
(新增的是 ServiceAccount / ClusterRole / kube-state-metrics 与三个 ConfigMap 键)。
不想要 K8s 面板:把 ConfigMap 里的 ENV_K8S_MONITOR_MODE 改成 off,并且不装
kube-state-metrics 那几个对象即可。
采集组件模式:平台在集群外,或要监控多个集群
在被监控集群里装一套轻量采集组件:一个专职采 K8s 的 Prometheus + RBAC +
kube-state-metrics。它把指标 remote_write 推回平台,平台侧不需要能反向访问这个集群。
客户环境通常只批出站、不批入站,这个方向差别是决定性的。
解压后先改 30-prometheus-incluster.yaml 里的三个变量,再 apply:
- name: ENV_PROMETHEUS_REMOTE_WRITE_URL
value: "http://运维平台地址:30881/mdis/prometheus/server/api/v1/write"
- name: ENV_PROMETHEUS_REMOTE_WRITE_TOKEN
value: "平台的 ENV_OPS_TOKEN"
- name: ENV_K8S_CLUSTER_NAME
value: "prod-k8s" # 集群标识,面板按它区分,别重名
写入地址按这个公式拼,三段都不能少:
http://<平台网关地址>:<端口> + <子路径> + /prometheus/server/api/v1/write
↑ ↑ ↑
K8s 部署取 ops-gateway 平台的 平台 Prometheus 跑 在
的 NodePort(默认 30881) ENV_OPS_ --web.external-url=
单机部署取 48881 SUB_PATH /prometheus/server/ 下
默认 /mdis
① 别写平台的 :9090。 平台的 ops-prometheus 是 ClusterIP,只在平台自己的集群内可解析,
别的集群连不上。要走网关的对外端口。
② 别漏 /prometheus/server/。 少了这段返回 404。
③ 必须填 token。 网关这条写入入口用 Bearer 鉴权,不填返回 401。填平台的
ENV_OPS_TOKEN(和登录平台用的是同一个)。
三种错误都只在采集端的容器日志里重试,界面上一律表现为「没数据」。填完先自检 (在采集组件的 Pod 里执行):
# 不带 token —— 应该 401,说明入口在、鉴权生效
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
http://运维平台地址:30881/mdis/prometheus/server/api/v1/write
# 带 token —— 应该 400(端点存在,只是拒绝了空请求体)
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
-H 'Authorization: Bearer 平台的ENV_OPS_TOKEN' \
http://运维平台地址:30881/mdis/prometheus/server/api/v1/write
拿到 404 就是地址拼错了;两次都 401 就是 token 不对。
改完 apply:
kubectl apply \
-f k8s-addons/00-namespace.yaml \
-f k8s-addons/10-kube-state-metrics.yaml \
-f k8s-addons/30-prometheus-incluster.yaml
数据流:
┌─ 被监控集群 ──────────────────────────────┐
│ kubelet / cAdvisor ──┐ │
│ kube-state-metrics ──┼─→ 采集 Prometheus │
│ apiserver ───────────┘ (用自己的 SA) │
└────────────────────────────────┬──────────┘
│ remote_write(仅需出站,带 Bearer token)
↓
运维平台网关 :30881/mdis/prometheus/server/api/v1/write
↓
平台 Prometheus(写入本地 TSDB)
↓
Grafana「资源监控 → K8s」面板
采集器只把 kube_* / container_* / kubelet_* / machine_* / node_* 推回平台,
它自身的 Prometheus 运行指标不会推过去占平台存储。
采集组件清单
| 文件 | 作用 | 是否必需 |
|---|---|---|
00-namespace.yaml | 命名空间 mdis-monitoring | ✅ |
10-kube-state-metrics.yaml | kube-state-metrics + RBAC + Service | ✅ |
20-node-exporter.yaml | node_exporter DaemonSet + Service | 可选(节点/容器指标已由 kubelet+cAdvisor 覆盖) |
30-prometheus-incluster.yaml | 集群内 ops-prometheus + RBAC + Service | ✅ |
40-alloy-logs.yaml | 容器日志采集 DaemonSet | 要看容器日志才装,见服务日志接入 |
40-alloy-logs.yaml 管的是日志不是指标,上面的 apply 命令里没有它——它需要先改
ENV_LOKI_PUSH_URL 再装。不装的话 K8s 面板照常有数据,只是「容器控制台」一直空着。
平台已经在采 本集群了,再装一套是重复采集:两份数据带着不同的集群名进同一个 TSDB, 面板下拉里会出现两个都对不上的条目,还白占一份存储。
监控多个集群
每个集群的指标带着 origin_prometheus=<集群名> 标签进平台,「资源监控 → K8s」面板顶部
会出现**「集群」下拉**,切换即可,默认 All(合并展示)。
下面以「平台装在集群 A,再纳管一个集群 B」为例,完整走一遍。
第 1 步:给平台所在的集群 A 起个名字
A 已经在自采,只差一个能认出来的名字。改平台的 ConfigMap:
kubectl -n hap-ops edit configmap ops-config
把 ENV_K8S_CLUSTER_NAME 从默认的 default 改成有意义的名字:
ENV_K8S_CLUSTER_NAME: "main-k8s"
重启 Prometheus 让它生效(这个值在启动时写进 Prometheus 的 external_labels):
kubectl -n hap-ops rollout restart deployment/ops-prometheus
origin_prometheus 是打在指标上的标签,改名后新数据用新名字,旧数据仍是 default,
面板下拉里会同时出现两个条目。要么在刚装完、数据还不多时就改好,要么就一直用 default
——别在攒了几个月数据之后才改。
第 2 步:在集群 B 里装采集组件
先确认 B 能出站访问 A 的网关端口(默认 NodePort 30881),A 不需要能反向访问 B:
# 在集群 B 的任一节点上
curl -s -o /dev/null -w '%{http_code}\n' http://集群A地址:30881/mdis/web/
然后下载 k8s-addons.tar.gz,改
30-prometheus-incluster.yaml 的三个变量:
- name: ENV_PROMETHEUS_REMOTE_WRITE_URL
value: "http://集群A地址:30881/mdis/prometheus/server/api/v1/write"
- name: ENV_PROMETHEUS_REMOTE_WRITE_TOKEN
value: "集群A平台的 ENV_OPS_TOKEN"
- name: ENV_K8S_CLUSTER_NAME
value: "prod-k8s"
apply(在集群 B 的 kubeconfig 下执行):
kubectl apply \
-f k8s-addons/00-namespace.yaml \
-f k8s-addons/10-kube-state-metrics.yaml \
-f k8s-addons/30-prometheus-incluster.yaml
第 3 步:确认推过去了
在集群 B 看采集组件的日志,应该没有 remote_write 相关的重试报错:
kubectl -n mdis-monitoring logs deploy/ops-prometheus | grep -iE '\[k8s\]|remote|error' | tail
回到平台,「资源监控 → K8s」面板顶部的「集群」下拉里应该能看到 main-k8s 和 prod-k8s
两项。也可以直接查平台 Prometheus 有几个集群在报数据:
count by (origin_prometheus) (kube_node_info)
再加第三个、第四个集群
重复第 2 步即可,每个集群只改 ENV_K8S_CLUSTER_NAME,写入地址和 token 都指向同一个平台:
| 集群 | 怎么配 | ENV_K8S_CLUSTER_NAME |
|---|---|---|
| A(平台所在) | 已自采,改 ConfigMap | main-k8s |
| B | 一套采集组件 | prod-k8s |
| C | 一套采集组件 | test-k8s |
| … | … | … |
面板下拉里显示的就是这个名字。两个集群填了同一个名字,指标会混在一起且无法区分。
平台侧不需要任何额外配置。但要留意存储容量:N 个集群的指标都进平台的 TSDB,
集群多或规模大时,按需调大 ENV_PROMETHEUS_RETENTION_SIZE 或扩盘。
验证
ServiceAccount + apiserver proxy 会自动发现 kubelet、cAdvisor、kube-state-metrics 和 pods, 无需暴露 kubelet 端口、无需 kubeconfig。
平台自采本集群(ops.yaml 用 hap-ops,k8s-cluster/ 同名):
kubectl -n hap-ops get deploy kube-state-metrics
kubectl -n hap-ops exec deploy/ops-prometheus -- \
curl -s localhost:9090/prometheus/server/api/v1/targets | grep -o '"job":"k8s-[^"]*"'
采集组件模式(装在被监控集群的 mdis-monitoring):
kubectl -n mdis-monitoring get pods
kubectl -n mdis-monitoring logs deploy/ops-prometheus | grep '\[k8s\]'
启动日志里应有一行 [k8s] incluster 采集已启用,集群标识 origin_prometheus="...";
配了 remote_write 的话紧跟着还有一行推送目标。地址前缀写错时这里会直接给出告警。
两种情况下 k8s-kubelet / k8s-cadvisor / k8s-kube-state-metrics 三个 job 都应为 UP,
随后到前端「资源监控 → K8s」面板即可看到节点与 Pod 视图。