7

Prometheus-Operator使用ServiceMonitor监控配置时遇坑与解决总结 - YOYOFx

 1 year ago
source link: https://www.cnblogs.com/maxzhang1985/p/17374615.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

摘要#

本文范围: Prometheus-Operator & kube-prometheus 安装;以及在解决使用ServiceMonitor时遇到的坑。

Prometheus Operator 简介#

随着云原生概念盛行,对于容器、服务、节点以及集群的监控变得越来越重要。Prometheus 作为 Kubernetes 监控的事实标准,有着强大的功能和良好的生态。但是它不支持分布式,不支持数据导入、导出,不支持通过 API 修改监控目标和报警规则,所以在使用它时,通常需要写脚本和代码来简化操作。Prometheus Operator 为监控 Kubernetes service、deployment 和 Prometheus 实例的管理提供了简单的定义,简化在 Kubernetes 上部署、管理和运行 Prometheus 和 Alertmanager 集群。

Prometheus Operator 功能如下:

  • 创建/销毁:在 Kubernetes namespace 中更加容易地启动一个 Prometheues 实例,一个特定应用程序或者团队可以更容易使用 Operator。
  • 便捷配置:通过 Kubernetes CRD资源配置 Prometheus 的基本信息,比如版本、(分布式)存储、副本集、高可用等。
  • 通过标签标记目标服务: 基于常见的 Kubernetes label 查询自动生成监控目标配置;不需要学习 Prometheus 特定的配置语言。

它使用如下的 Kubernetes CRD 资源对 Prometheus进行配置:

  • Prometheus
  • Alertmanager
  • ThanosRuler
  • ServiceMonitor
  • PodMonitor
  • Probe
  • PrometheusRule
  • AlertmanagerConfig

参考文档:#

kube-prometheus 包含的软件包:#

  • The Prometheus Operator
  • Highly available Prometheus
  • Highly available Alertmanager
  • Prometheus node-exporter
  • Prometheus Adapter for Kubernetes Metrics APIs
  • kube-state-metrics
  • Grafana

Prometheus Operator 兼容性#

  • Kubernetes 1.16+ ,如需更低版本的 Kubernetes 兼容性,请参考官方文档对应的版本分支。

以下代码分支对应的 Kubernetes 版本如下:

  • release-0.9 1.21,1.22
  • release-0.10 1.22,1.23
  • release-0.11 1.23,1.24
  • release-0.12 1.24,1.25

文章中已验证的版本(PaaS 安装版本)#

  • 本地集群(kind 1.25) release-0.12
  • 腾讯云集群(TKE 1.20) release-0.9

kube-prometheus 安装卸载#

安装#

git clone https://github.com/prometheus-operator/kube-prometheus.git
git checkout release-0.12

cd kube-prometheus

kubectl apply --server-side -f manifests/setup

kubectl wait \
	--for condition=Established \
	--all CustomResourceDefinition \
	--namespace=monitoring
	
kubectl apply -f manifests/

卸载#

kubectl delete --ignore-not-found=true -f manifests/ -f manifests/setup

helm安装#

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus-community/kube-prometheus-stack --namespace monitoring --generate-name

无论哪种安装方式,遇到镜像拉取失败的情况,可以使用如下命令手动拉取镜像并推送到自己的仓库,本文中推送到自己的docker hub仓库中,替换yaml中的image地址,然后再次执行安装命令。

ServiceMonitor#

ServiceMonitor 自定义资源(CRD)能够声明如何监控一组动态服务的定义。它使用标签选择定义一组需要被监控的服务。这样就允许组织引入如何暴露 metrics 的规定,只要符合这些规定新服务就会被发现列入监控,而不需要重新配置系统。
一个 Service 可以公开一个或多个服务端口,通常情况下,这些端口由指向一个 Pod 的多个 Endpoints 支持。这也反映在各自的 Endpoints 对象中。
ServiceMonitorSpec 的 endpoints 部分用于配置需要收集 metrics 的 Endpoints 的端口和其他参数。在一些用例中会直接监控不在服务 endpoints 中的 pods 的端口。

例子#

之前写过一篇 《YoyoGo微服务框架入门系列-使用Prometheus监控Golang服务》 文章中的暴露的指标服务与本例中为同一个。
有如下 Service 指向 labels: k8s-app=dev-yoyogodemo-kind-kind 的 部署(Deployment):

apiVersion: v1
kind: Service
metadata:
  name: dev-yoyogodemo-kind-kind-svc-cluster-sgr
  namespace: klns-administration
  labels:
    k8s-app: dev-yoyogodemo-kind-kind
spec:
  ports:
    - name: default-tcp
      protocol: TCP
      port: 8080
      targetPort: 8080
  selector:
    k8s-app: dev-yoyogodemo-kind-kind

  type: ClusterIP
  sessionAffinity: None

为其创建 ServiceMonitor 资源定义如下:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: dev-yoyogodemo-kind-kind-servicemontor
  namespace: klns-administration
  labels:
    k8s-app: dev-yoyogodemo-kind-kind
spec:
  endpoints:
    - interval: 15s
      path: /app/actuator/metrics
      port: default-tcp
  namespaceSelector:
    matchNames:
    - klns-administration
  selector:
    matchLabels:
      k8s-app: dev-yoyogodemo-kind-kind

采坑#

在默认配置中,此 ServiceMonitor 会因为 Kubenertes RBAC 集群权限问题,导致 ServiceMonitor不生效,表现为在Prometheus 的 targets 中看不到该 ServiceMonitor 的 targets。
查看StatefulSet工作负载 prometheus-k8s 的状态,查看日志,看到如下报错:

services is forbidden: User "system:serviceaccount:monitoring:prometheus-k8s" cannot list services in the namespace monitoring

这是因为默认只配置了get权限 。解决办法是为 ServiceMonitor 添加如下的 ClusterRoleBinding,编辑 prometheus-k8s 角色绑定,添加如下内容:

...
- apiGroups:
    - ""
  resources:
    - services
    - endpoints
    - pods
  verbs:
    - get
    - list
    - watch

修改后重启 StatefulSet: prometheus-k8s; ServiceMonitor就会找到对应 Service 资源的 labels 选择器的Endpoint资源, 并且会被 Prometheus Operator 自动配置为 Prometheus 的 targets。

176287-20230505162855993-213549645.png

当然ServiceMonitor不生效的原因还有很多,比如ServiceMonitor的namespaceSelector和selector不匹配,或者ServiceMonitor的namespaceSelector和Service的namespace不匹配等等。

为什么配置的ServiceMonitor或PodMonitor未生效?#

排查步骤:#

  • 确认Target是否已经被发现,找到目标Prometheus实例,然后在左侧导航栏单击服务发现,然后单击Targets页签,检查相应的Target是否已经被发现。
  • 查看集群CRD中是否存在相应的ServiceMonitor资源。
  • 确认Label Selector是否能选择到期望的Pod或者Service
    # 以上面那个例子为例。执行以下命令,观察返回结果,若无返回结果,则需要调整Label Selector或Namespace Selector,即可筛选出期望的Pod或者Service。
    
    kubectl get service -l k8s-app=dev-yoyogodemo-kind-kind -n klns-administration
    
  • 检查端口设置,端口port字段,需要指定为pod定义中spec.containers[i].ports[i].name,或services定义中spec.ports[i].name字段的值。

推广#

目前正在将Prometheus Operator集成到PaaS项目中,后续会将集成过程中遇到的问题和解决方案分享出来。

kubelilin 多云 PaaS 开源项目: https://github.com/KubeLilin/kubelilin

functional_architecture.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK