Go服务需暴露/metrics端点并绑定0.0.0.0,Service与ServiceMonitor标签严格匹配,使用Prometheus Operator而非裸Deployment,kube-state-metrics仅采集K8s对象状态而非应用指标。

你不需要在 Golang 项目代码里“部署” Prometheus 或 kube-state-metrics —— 它们是集群级服务,不是 Go 库,也不是你应用的一部分。真正要做的,是让 Go 服务暴露指标、跑在 Kubernetes 上,并确保 Prometheus 能自动发现并抓取它。
Go 服务必须暴露 /metrics 端点
Prometheus 不会主动“连接”你的服务,而是定期 HTTP GET 请求 /metrics。如果你的 Go 服务没这个端点,它就完全不可见。
- 用官方库最稳妥:
github.com/prometheus/client_golang/prometheus/promhttp - 端口必须和容器
containerPort一致(比如都设为8080),否则 ServiceMonitor 找不到目标 - 别只监听
127.0.0.1:8080—— 必须绑定0.0.0.0:8080,否则 Pod 内其他容器(如 sidecar)或外部 scraper 访问不到 - 示例最小启动代码:
package main <p>import ( "net/http" "github.com/prometheus/client_golang/prometheus/promhttp" )</p><p>func main() { http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil) // 注意:不是 ":8080" + "127.0.0.1" }启动后,进 Pod 执行
curl localhost:8080/metrics应该返回文本格式指标,且第一行是# HELP开头。Service 和 ServiceMonitor 标签必须严格匹配
Prometheus Operator 不靠 DNS 名或 IP 发现目标,全靠标签(
labels)对齐。错一个字母、大小写不一致、namespace 不同,都会导致采集失败。立即学习“go语言免费学习笔记(深入)”;
- 你的
Service必须有app: my-go-app这类 label(不能只在 Deployment 里有) -
ServiceMonitor的spec.selector.matchLabels必须和 Service 的 labels 完全一致 -
ServiceMonitor的endpoints[0].port值,必须等于Service.spec.ports[0].name(不是targetPort,也不是数字端口) - 如果 Service 在
defaultnamespace,而ServiceMonitor在monitoring,需在 Prometheus CR 中显式开启跨 ns 发现:serviceMonitorNamespaceSelector: {}
别用裸 Deployment 部署 Prometheus
直接跑
prom/prometheus的 Deployment 是自找麻烦:数据存在emptyDir里,Pod 重启就丢历史;多副本抢 targets;无法自动发现新服务;告警规则只能挂载进容器,改一次就得重启。- 生产环境必须用
kube-prometheus-stack(基于 Prometheus Operator) - 安装前确认:
kubectl create namespace monitoring,且集群有默认StorageClass - 关键 Helm 参数别漏:
--set prometheus.prometheusSpec.retention="30d"(防磁盘爆满),--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate(显式声明 PVC,不能依赖默认值) - 验证是否生效:运行
kubectl get servicemonitor -n default,再查kubectl get prometheus -n monitoring -o yaml里的serviceMonitorSelector是否命中你的资源
kube-state-metrics 不是你项目的依赖
它不采集你的 Go 代码指标,只把 Kubernetes 对象(Pod、Deployment、Service)的状态转成指标,比如
kube_pod_status_phase{pod="my-go-app-5f6b9c8d4"} == 1。你的 Go 应用是否 Ready、是否被调度成功,它才管;你代码里opsProcessed.Inc()这种业务指标,它完全看不见。- 别在 Go 代码里
import任何叫kube-state-metrics的包 —— 不存在 - 别试图在
main.go里启动它 —— 它是独立容器,通过 YAML 部署在monitoringns 下 - 想确认它是否采集到你的 Pod?直接查它的 endpoint:
kubectl port-forward -n monitoring svc/kube-state-metrics 8080:8080,然后curl localhost:8080/metrics | grep my-go-app - 如果查不到,先看 Pod 是否已进入
Running状态(Pending/Unknown 不会上报),再检查 RBAC 是否允许它 list/watch 你所在的 namespace
最容易被忽略的是:ServiceMonitor 的
port字段和 Service 的ports[0].name必须一字不差,包括大小写;以及 Prometheus 抓取时默认超时是 10s,如果你的/metrics响应慢于这个值,指标就直接被丢弃,连错误日志都不明显。 - 你的


















