k8s1.21.3,部署kube-prometheus0.9版本,通过ServiceMonitor获取命名空间test下业务指标,遇到问题

错误日志:

ts=2025-09-15T03:38:50.037Z caller=klog.go:116 level=error component=k8s_client_runtime func=ErrorDepth msg="pkg/mod/k8s.io/client-go@v0.29.3/tools/cache/reflector.go:229: Failed to watch *v1.Endpoints: failed to list *v1.Endpoints: endpoints is forbidden: User \"system:serviceaccount:monitoring:prometheus-k8s\" cannot list resource \"endpoints\" in API group \"\" in the namespace \"test

解决方案:

你给出的报错关键信息是:

 
endpoints is forbidden: User "system:serviceaccount:monitoring:prometheus-k8s" cannot list resource "endpoints" in API group "" in the namespace "test"

这说明 prometheus-k8s 这个 ServiceAccount 没有权限去 list/watch wps-gray 命名空间下的 endpoints,所以 Prometheus Operator 无法通过 ServiceMonitor 去发现目标。

在 kube-prometheus 0.9(Prometheus Operator v0.47 左右)里,prometheus-k8s 的权限是通过 ClusterRole + ClusterRoleBindingRole + RoleBinding 授权的,你需要为它加上 wps-gray 命名空间的权限。


解决方案

你需要在 wps-gray 命名空间下创建一个 Role + RoleBinding,授予 prometheus-k8sendpointsservicespods 等资源的 list/watch 权限。

1. 创建 Role

 
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: wps-gray name: prometheus-endpoints-role rules: - apiGroups: [""] resources: - endpoints - services - pods verbs: ["get", "list", "watch"]

2. 创建 RoleBinding

 
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: wps-gray name: prometheus-endpoints-rolebinding subjects: - kind: ServiceAccount name: prometheus-k8s namespace: monitoring roleRef: kind: Role name: prometheus-endpoints-role apiGroup: rbac.authorization.k8s.io

验证

  1. 应用上面两个 YAML:

 
kubectl apply -f role.yaml kubectl apply -f rolebinding.yaml
  1. 等待 Prometheus Operator 重新同步 targets,查看 Prometheus UI Status -> Targets 页面,应该能看到 wps-gray 命名空间的指标目标被发现。


其他注意点

  • 如果后续要让 Prometheus 采集其他命名空间的指标,需要为每个目标命名空间都创建类似的 Role 和 RoleBinding。

  • 如果集群管理员允许,也可以用 ClusterRole + ClusterRoleBinding 一次性授予所有命名空间的访问权限:

 
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus-k8s-endpoints rules: - apiGroups: [""] resources: ["endpoints","services","pods"] verbs: ["get","list","watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus-k8s-endpoints roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus-k8s-endpoints subjects: - kind: ServiceAccount name: prometheus-k8s namespace: monitoring

这样就不需要对每个命名空间都单独配置。


要不要我帮你直接生成一份 通用 ClusterRole + ClusterRoleBinding,方便后续新增命名空间也能直接被 Prometheus 发现?这样只要创建 ServiceMonitor 就能生效。

 
您说:
需要
 
ChatGPT 说:

明白,那我给你生成一份通用的 ClusterRole + ClusterRoleBinding,一次性授予 prometheus-k8s 访问所有命名空间 endpoints/services/pods 的权限,这样以后只要创建 ServiceMonitor 就能直接被发现,不需要再额外加 Role/RoleBinding。


通用权限配置

 
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus-k8s-endpoints rules: - apiGroups: [""] resources: - endpoints - services - pods verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus-k8s-endpoints roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus-k8s-endpoints subjects: - kind: ServiceAccount name: prometheus-k8s namespace: monitoring

应用方法

 
kubectl apply -f prometheus-k8s-clusterrole.yaml

验证步骤

  1. 确认权限生效

 
kubectl auth can-i list endpoints --as=system:serviceaccount:monitoring:prometheus-k8s --namespace=test

如果返回 yes,说明权限已生效。

  1. 检查 Prometheus Target
    过 30~60 秒后,进入 Prometheus UI → Status → Targets,应该能看到 test 命名空间下的目标处于 UP


这样配置的优点:
✅ 统一管理,不需要逐个命名空间添加 Role/RoleBinding
✅ 后续业务扩展时,只要创建 ServiceMonitor 就能采集

缺点:
⚠️ 赋予了 prometheus-k8s 跨命名空间的读取权限,如果安全要求非常高,建议只在需要的命名空间配置 Role/RoleBinding。


要不要我帮你把 ServiceMonitor 配置 也一起检查一下,确保匹配到 test 命名空间的 Service?这样可以避免目标被权限放通了但还是没被发现的情况。

posted @ 2025-09-15 14:29  GaoYanbing  阅读(11)  评论(0)    收藏  举报