4、prometheus-服务发现k8s api-2

promethes服务发现

本章说明: 适配不同场景的注册中心类型,基于k8s api的prometheus监控

说明:接上章豆包ai

基于Kubernetes API的服务发现

在Kubernetes(K8s)容器集群中,Pod、Node等资源会频繁经历创建、调度、销毁等生命周期变化,传统静态配置或简单服务发现已无法适配。Prometheus通过直接调用Kubernetes API实现的服务发现机制,能实时感知集群资源变动,自动完成监控目标的发现与更新,是容器场景下的最优选择

核心原理:API驱动的动态感知

Prometheus基于Kubernetes API的服务发现,核心是通过"权限认证-资源监听-元标签生成-目标加工"的链路,实现监控目标的全自动化管理,无需第三方注册中心介入,

  • 原理如下:
    1. 权限认证:Prometheus通过K8s的Service Account机制获取API访问权限,确保能合法查询、监听集群资源。
    2. 资源监听 :通过配置kubernetes_sd_configs指定"资源角色"(如Node、Pod、Service),Prometheus会持续监听对应资源的CRUD(创建、读取、更新、删除)事件。
    3. 元标签生成 :发现资源后,Prometheus自动为每个目标生成前缀为__meta_kubernetes_*的元标签,封装资源的核心信息(如Pod命名空间、节点标签、服务端口等)。
    4. 目标加工与抓取 :通过relabel_configs过滤无效目标、提取业务标签、拼接访问地址,最终生成标准化监控目标,按scrape_interval周期抓取指标。
  • **核心优势:**与K8s集群原生集成,无需额外部署组件;支持细粒度资源过滤;能实时同步资源变动,适配容器动态调度特性。

前置条件:K8s权限配置(RBAC)

K8s默认开启RBAC(基于角色的访问控制),需为Prometheus创建Service Account并绑定权限,确保其能访问集群API。以下为标准权限配置流程: 还没学到k8s仅先记录一下

  • 权限配置文件(prometheus-rbac.yaml)

    创建命名空间、Service Account、ClusterRole和ClusterRoleBinding,遵循"最小权限原则"配置权限:

    bash 复制代码
    # 1. 创建独立命名空间(建议监控组件单独部署)
    apiVersion: v1
    kind: Namespace
    metadata:
      name: monitoring
    ---
    # 2. 创建Service Account(Prometheus将使用该账号访问API)
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: prometheus
      namespace: monitoring
    ---
    # 3. 定义集群角色(明确可访问的资源和操作)
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: prometheus
    rules:
    - apiGroups: [""]  # 核心API组(Node、Pod、Service等基础资源)
      resources: ["nodes", "nodes/metrics", "pods", "services", "endpoints"]
      verbs: ["get", "list", "watch"]  # 仅允许查询和监听,禁止修改
    - apiGroups: ["apps"]  # 应用API组(Deployment、StatefulSet等)
      resources: ["deployments", "statefulsets"]
      verbs: ["get", "list", "watch"]
    - nonResourceURLs: ["/metrics"]  # 允许访问节点的/metrics端点
      verbs: ["get"]
    ---
    # 4. 绑定角色与账号(将ClusterRole绑定到Service Account)
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: prometheus
    subjects:
    - kind: ServiceAccount
      name: prometheus
      namespace: monitoring
    roleRef:
      kind: ClusterRole
      name: prometheus
      apiGroup: rbac.authorization.k8s.io
  • 执行部署命令

    bash 复制代码
    # 应用权限配置
    kubectl apply -f prometheus-rbac.yaml
    
    # 验证权限(查看Service Account是否创建成功)
    kubectl get sa -n monitoring
    # 预期输出:NAME         SECRETS   AGE
    #          prometheus    1         10s

配置场景

K8s服务发现支持多种资源角色,以下为Node(节点监控)、Pod(容器应用监控)、Service(服务监控)三大核心场景的完整配置示例,可直接复用。

  • 支持的资源类型及核心标签:

    资源类型 作用 核心元标签示例
    Node 监控 K8s 节点 __meta.kubernetes_node_name(节点名)
    Pod 监控容器实例 __meta.kubernetes_pod_ip(Pod IP)
    Service 监控服务端点 __meta.kubernetes_service_name(服务名)
    Endpoint 监控服务后端 __meta.kubernetes_endpoint_ready(就绪状态)
    Ingress 监控入口路由 __meta.kubernetes_ingress_path(路由路径)
Node资源发现(监控集群节点)

监控K8s集群节点的CPU、内存、磁盘等硬件资源,依赖Node Exporter(需提前在各节点部署,默认暴露9100端口)。在Node角色的服务发现中,Prometheus会自动生成一系列节点相关的元数据标签,可用于目标过滤、标签加工等场景,

  • 核心元数据标签如下:

    元数据标签名称 说明 示例
    __meta.kubernetes_node_name K8s集群中的节点名称 node-10-4-50-130
    __meta.kubernetes_node_label_<labelname> 节点的自定义标签,替换为实际标签名 __meta.kubernetes_node_label_env=production
    __meta.kubernetes_node_labelpresent_<labelname> 节点是否存在指定标签,返回布尔值 __meta.kubernetes_node_labelpresent_env=true
    __meta.kubernetes_node_annotation_<annotation> 节点的自定义注解,替换为实际注解名 __meta.kubernetes_node_annotation_node_type=worker
    __meta.kubernetes_node_annotationpresent_<annotation> 节点是否存在指定注解,返回布尔值 __meta.kubernetes_node_annotationpresent_node_type=true
    __meta.kubernetes_node_address_<address_type> 节点的地址信息,<address_type>为地址类型 __meta.kubernetes_node_address_NodeInternalIP=10.4.50.130

    **注意:**节点监控中instance标签的默认取值来自__meta.kubernetes_node_name(节点名称),而非__address__(节点IP),可通过relabel_configs自定义调整。

  • yml示例

    bash 复制代码
    global:
      scrape_interval: 15s  # 全局抓取间隔
      evaluation_interval: 15s  # 规则评估间隔
    
    scrape_configs:
      - job_name: 'k8s-node-monitor'
        # 配置K8s服务发现,角色为Node
        kubernetes_sd_configs:
          - role: node
            # 可选:限定监控的命名空间(不配置则监控全集群)
            namespaces:
              names: ["monitoring", "default"]
        # 标签重写:过滤目标、添加自定义标签
        relabel_configs:
          # 1. 仅保留生产环境节点(节点标签需提前配置env=production)
          - source_labels: [__meta_kubernetes_node_label_env]
            regex: production
            action: keep
          # 2. 拼接Node Exporter访问地址(节点IP:9100)
          - source_labels: [__address__]
            target_label: __address__
            replacement: "${1}:9100"
          # 3. 将节点名作为自定义标签,便于查询过滤
          - source_labels: [__meta_kubernetes_node_name]
            target_label: node_name
        # 抓取配置
        scheme: http
        metrics_path: /metrics
Pod资源发现(监控业务容器)

监控集群内业务Pod的应用指标(如Java应用的JVM指标、自定义业务指标),需通过Pod注解标记可抓取的目标。在Pod角色的服务发现中,Prometheus会生成丰富的元数据标签,涵盖Pod的命名空间、标签、注解、容器等信息,

  • 核心元数据标签如下:

    元数据标签名称 说明 示例
    __meta_kubernetes_pod_name Pod的名称 demo-app-7f9d6c5f4d-2xqzk
    __meta_kubernetes_pod_namespace Pod所属的命名空间 default
    __meta_kubernetes_pod_label_<labelname> Pod的自定义标签,替换为实际标签名 __meta_kubernetes_pod_label_app=demo-app
    __meta_kubernetes_pod_annotation_<annotation> Pod的自定义注解,替换为实际注解名 __meta_kubernetes_pod_annotation_prometheus_io_scrape=true
    __meta_kubernetes_pod_container_name Pod内容器的名称 demo-app
    __meta_kubernetes_pod_host_ip Pod所在节点的IP地址 10.4.50.130
    __meta_kubernetes_pod_ip Pod的IP地址 10.244.1.5
    __meta_kubernetes_pod_ready Pod的就绪状态(true/false) true
  • yml示例

    bash 复制代码
    scrape_configs:
      - job_name: 'k8s-pod-monitor'
        kubernetes_sd_configs:
          - role: pod  # 资源角色为Pod
        relabel_configs:
          # 1. 仅抓取标注了prometheus.io/scrape=true的Pod(核心过滤规则)
          - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
            regex: true
            action: keep
          # 2. 从Pod注解获取指标路径(默认/metrics,可自定义)
          - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
            regex: (.+)
            target_label: __metrics_path__
            replacement: $1
          # 3. 从Pod注解获取暴露端口(如注解prometheus.io/port: "8080")
          - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
            regex: ([^:]+)(?::\d+)?;(\d+)
            target_label: __address__
            replacement: $1:$2
          # 4. 添加Pod命名空间、名称标签,便于聚合分析
          - source_labels: [__meta_kubernetes_pod_namespace]
            target_label: k8s_namespace
          - source_labels: [__meta_kubernetes_pod_name]
            target_label: k8s_pod_name
          # 5. 过滤掉非业务命名空间的Pod(如kube-system)
          - source_labels: [__meta_kubernetes_pod_namespace]
            regex: kube-system
            action: drop
  • 业务Pod注解配置示例(Deployment.yaml中添加):

    yml 复制代码
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-app
      namespace: default
    spec:
      replicas: 2
      template:
        metadata:
          annotations:
            prometheus.io/scrape: "true"        # 允许Prometheus抓取
            prometheus.io/port: "8080"          # 应用暴露指标的端口
            prometheus.io/path: "/actuator/prometheus"  # 自定义指标路径(如Spring Boot应用)
        spec:
          containers:
          - name: demo-app
            image: demo-app:v1.0
            ports:
            - containerPort: 8080
Service资源发现(监控服务集群)

监控K8s Service对应的后端端点,适合数据库、缓存等有固定服务地址的中间件监控场景。在Service角色的服务发现中,Prometheus生成的元数据标签聚焦于服务的核心信息,如服务名、端口、选择器等,

  • 核心元数据标签如下:

    元数据标签名称 说明 示例
    __meta_kubernetes_service_name Service的名称 mysql-service
    __meta_kubernetes_service_namespace Service所属的命名空间 middleware
    __meta_kubernetes_service_label_<labelname> Service的自定义标签,替换为实际标签名 __meta_kubernetes_service_label_app=middleware
    __meta_kubernetes_service_port_name Service的端口名称 mysql-port
    __meta_kubernetes_service_port_number Service的端口号 3306
    __meta_kubernetes_service_port_protocol Service的端口协议(TCP/UDP) TCP
    __meta_kubernetes_service_cluster_ip Service的集群IP地址 10.96.123.45
    __meta_kubernetes_service_selector_<key> Service的选择器键值对,替换为选择器键 __meta_kubernetes_service_selector_app=mysql
  • yml示例

    bash 复制代码
    scrape_configs:
      - job_name: 'k8s-service-monitor'
        kubernetes_sd_configs:
          - role: service  # 资源角色为Service
        relabel_configs:
          # 1. 仅抓取标签为app=middleware的服务(如MySQL、Redis)
          - source_labels: [__meta_kubernetes_service_label_app]
            regex: middleware
            action: keep
          # 2. 提取服务端口名称作为标签
          - source_labels: [__meta_kubernetes_service_port_name]
            target_label: service_port_name
          # 3. 拼接服务访问地址(Service ClusterIP:端口)
          - source_labels: [__meta_kubernetes_service_cluster_ip, __meta_kubernetes_service_port_number]
            target_label: __address__
            replacement: "${1}:${2}"
        metrics_path: /metrics
        scheme: http

验证与运维关键事项

  • 配置验证方法
    • WebUI验证 :访问Prometheus WebUI(默认http://<Prometheus-IP>:9090),进入"Status → Targets"页面,对应Job下的目标状态为"UP"表示发现成功。
    • API验证 :通过Prometheus API查询发现的目标列表: curl http://<Prometheus-IP>:9090/api/v1/targets | jq .data.activeTargets
    • 动态测试:新建或删除符合过滤规则的Pod/Node,观察Prometheus Target列表是否在15秒内(与scrape_interval一致)同步更新。
  • 核心注意事项
    • 权限安全:严禁授予Prometheus集群管理员(cluster-admin)权限,避免权限泄露导致安全风险。
    • 目标过滤优化 :务必通过relabel_configs过滤无关目标(如kube-system命名空间的系统Pod),减少Prometheus抓取压力。
    • 注解规范 :业务Pod需统一注解格式(如prometheus.io/*前缀),避免因注解不规范导致发现失败。
    • 元标签活用__meta_kubernetes_*元标签包含丰富资源信息,可用于构建精细化监控视图(如按命名空间、节点分组)。
    • 高可用适配:Prometheus建议部署为StatefulSet,结合K8s API的Watch机制,确保服务发现的连续性,避免单点故障。
    • 性能调优 :大规模集群(千级以上Pod)建议调大kubernetes_sd_configsrefresh_interval(默认30秒),避免频繁API调用影响K8s APIServer性能。
常见问题排查常见问题排查
问题现象 排查方向
Target状态为"Down" 1. 检查目标Pod/Node是否正常运行;2. 验证指标端口是否能访问(如telnet <IP> <端口>);3. 确认metrics路径是否正确
无目标被发现 1. 检查RBAC权限是否配置正确(kubectl describe sa prometheus -n monitoring);2. 验证relabel_configs过滤规则是否过于严格;3. 查看Prometheus日志是否有API访问错误
目标更新延迟 1. 调整kubernetes_sd_configsrefresh_interval参数;2. 检查K8s APIServer是否存在性能瓶颈
相关推荐
人生苦短1284 小时前
Kubernetes(k8s)
云原生·容器·kubernetes
岚天start17 小时前
KubeSphere在线安装单节点K8S集群
docker·容器·kubernetes·k8s·kubesphere·kubekey
Yyyy48217 小时前
标签Labels、Scheduler:调度器、k8s污点与容忍度
开发语言·kubernetes
xyhshen17 小时前
记录一次K8S跨命名空间访问 xxx.xxx.svc.cluster.local 类似内部服务不通的问题
云原生·容器·kubernetes
栗子~~17 小时前
shell-基于k8s/docker管理容器、监控模型训练所消耗的最大CPU与最大内存脚本
docker·容器·kubernetes
海鸥8117 小时前
在k8s中部署seaweedfs,上传文件到seaweedfs方法
云原生·容器·kubernetes
半梦半醒*17 小时前
k8s——pod详解2
linux·运维·docker·容器·kubernetes·负载均衡
AAA小肥杨17 小时前
K8s从Docker到Containerd的迁移全流程实践
docker·容器·kubernetes
xx.ii20 小时前
k8s:pod-1
云原生·容器·kubernetes