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是否存在性能瓶颈
相关推荐
Connie14514 小时前
记一次K8s故障告警排查(Grafna告警排查)
云原生·容器·kubernetes·grafana
谷隐凡二12 小时前
Kubernetes主从架构简单解析:基于Python的模拟实现
python·架构·kubernetes
陈陈CHENCHEN12 小时前
SuperMap iManager for K8s 离线环境镜像仓库 Containerd 部署
kubernetes
会飞的小蛮猪15 小时前
Ubuntu24.04 基于Containerd部署K8s1.34(私服部署)
docker·云原生·kubernetes
间彧1 天前
Kubernetes滚动发布详解
kubernetes
间彧1 天前
在实际生产环境中,Kubernetes声明式API如何实现蓝绿部署、金丝雀发布等高级部署策略?
kubernetes
间彧1 天前
Kubernetes声明式API相比传统命令式API在故障恢复场景下的具体优势有哪些?
kubernetes·github
间彧1 天前
为什么说Kubernetes的API设计是其成功的关键因素之一?
kubernetes
间彧1 天前
Kubernetes Deployment 配置简化实战:从复杂到高效
kubernetes
可爱的小小小狼1 天前
k8s:服务网格Service Mesh(服务网格)istio和envoy
kubernetes·istio·service_mesh