0


Prometheus 云原生kubernetes服务发现原理图解

云原生kubernetes服务发现原理图解

概述

上节分析了

Prometheus

服务发现核心流程(如下图),

Discoverer

基于不同协议发现采集点,通过

channel

通知到

updater

协程,然后更新到

discoveryManager

结构体

trargets

字段中,最终由

sender

协程将

discoveryManager

targets

字段数据发送给

scrape

采集模块。
e6928605c1de049a69f5529cb52fd0e3.png

Discoverer

定义的接口类型,不同的服务发现协议基于该接口进行实现:

type Discoverer interface {
 // Run hands a channel to the discovery provider (Consul, DNS, etc.) through which
 // it can send updated target groups. It must return when the context is canceled.
 // It should not close the update channel on returning.
 Run(ctx context.Context, up chan<- []*targetgroup.Group)
}

k8s协议配置

Prometheus

本身就是作为云原生监控出现的,所以对云原生服务发现支持具有天然优势。

kubernetes_sd_configs

服务发现协议核心原理就是利用

API Server

提供的

Rest接口

获取到云原生集群中的

POD

Service

Node

Endpoints

Endpointslice

Ingress

等对象的元数据,并基于这些信息生成

Prometheus

采集点,并且可以随着云原生集群状态变更进行动态实时刷新。
1b7cae25cee41c3bcb70eae399f733a7.png

kubernetes

云原生集群的

POD

Service

Node

Ingress

等对象元数据信息都被存储到

etcd

数据库中,并通过

API Server

组件暴露的

Rest

接口方式提供访问或操作这些对象数据信息。

**「

kubernetes_sd_configs

配置示例:」**

- job_name: kubernetes-pod
    kubernetes_sd_configs:
    - role: pod
      namespaces:
        names:
        - 'test01'
      api_server: https://apiserver.simon:6443
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

配置说明:

  • api_server指定API Server地址,出于安全考虑,这些接口是带有安全认证的,bearer_token_fileca_file则指定访问API Server使用到的认证信息;
  • role指定基于云原生集群中哪种对象类型做服务发现,支持PODServiceNodeEndpointsEndpointsliceIngress六种类型;
  • namespaces指定作用于哪个云原生命名空间下的对象,不配置则对所有的云原生命名空间生效;

「为什么没有配置api server信息也可以正常进行服务发现?」

很多时候我们并不需要配置

api server

相关信息也可以进行服务发现,如我们将上面示例简化如下写法:

- job_name: kubernetes-pod
    kubernetes_sd_configs:
    - role: pod
      namespaces:
        names:
        - 'test01'

一般

Prometheus

部署在监控云原生集群上,从

Pod

使用

Kubernetes API

官方客户端库(

client-go

)提供了更为简便的方法:

rest.InClusterConfig()

API Server

地址是从

POD

的环境变量

KUBERNETES_SERVICE_HOST

KUBERNETES_SERVICE_PORT

构建出来,

token

以及

ca

信息从

POD

固定的文件中获取,因此这种场景下

kubernetes_sd_configs

api_server

ca_file

是不需要配置的。
a5b9bf7f2b9224a094d12c3233ffc8dd.png

client-go

kubernetes

官方提供的

go

语言的客户端库,

go

应用使用该库可以访问

kubernetes

API Server

,这样我们就能通过编程来对

kubernetes

资源进行增删改查操作。

Informer机制

从之前分析的服务发现协议接口设计得知,了解

k8s

服务发现协议入口在

discovery/kubernetes.go

Run

方法:
ffaa2d87e24f68f272b4d2c04ce50300.png

Run

方法中

switch

罗列出不同

role

的处理逻辑,刚好和配置示例中

role

支持的六种云原生对象类型对应,只是基于不同的对象进行服务发现,基本原理都是一致的。

云原生服务发现基本原理是访问

API Server

获取到云原生集群资源对象,

Prometheus

API Server

进行交互这里使用到的是

client-go

官方客户端里的

Informer

核心工具包。

Informer

底层使用

ListWatch

机制,在

Informer

首次启动时,会调用

List API

获取所有最新版本的资源对象,缓存在内存中,然后再通过

Watch API

来监听这些对象的变化,去维护这份缓存,降低

API Server

的负载。除了

ListWatch

Informer

还可以注册自定义事件处理逻辑,之后如果监听到事件变化就会调用对应的用户自定义事件处理逻辑,这样就实现了用户业务逻辑扩展。

Informer

机制工作流程如下图:
3844b889feafd00db05f8252a64c4739.png

Informer

机制本身比较复杂,这里先暂时不太具体说明,只需要理解

Prometheus

使用

Informer

机制获取和监听云原生资源对象,即上图中只有「绿色框部分是自定义业务逻辑」,其它都是

client-go

框架

informer

工具包提供的功能。

这其中的关键就是注册自定义

AddFunc

DeleteFunc

UpdateFunc

三种事件处理器,分别对应增、删、改操作,当触发对应操作后,事件处理器就会被回调感知到。比如云原生集群新增一个

POD

资源对象,则会触发

AddFunc

处理器,该处理器并不做复杂的业务处理,只是将该对象的

key

放入到

Workqueue

队列中,然后

Process Item

组件作为消费端,不停从

Workqueue

中提取数据获取到新增

POD

key

,然后交由

Handle Object

组件,该组件通过

Indexer

组件提供的

GetByKey()

查询到该新增

POD

的所有元数据信息,然后基于该

POD

元数据就可以构建采集点信息,这样就实现

kubernetes

服务发现。

「为什么需要Workqueue队列?」

Resource Event Handlers

组件注册自定义事件处理器,获取到事件时只是把对象

key

放入到

Workerqueue

中这种简单操作,而没有直接调用

Handle Object

进行事件处理,这里主要是避免阻塞影响整个

informer

框架运行。如果

Handle Object

比较耗时放到

Resource Event Handlers

组件中直接处理,可能就会影响到④⑤功能,所以这里引入

Workqueue

类似于

MQ

功能实现解耦。

源码分析

熟悉了上面

Informer机制

,下面以

role=POD

为例结合

Prometheus

源码梳理下上面流程。

1、创建和

API Server

交互底层使用的

ListWatch

工具;
106df7f30fe30fbaf884bc6e69a89c24.png
2、基于

ListWatch

创建

Informer


e9ccd4b00abc7b8c95c14bd84b76e982.png
3、注册资源事件,分别对应资源创建、资源删除和资源更新事件处理;
4185c0deeb1f95044305405cec454b55.png

这里的

podAddCount

podDeleteCount

podUpdateCount

分别对应下面三个指标序列,指标含义也比较明显:

prometheus_sd_kubernetes_events_total(role="pod", event="add")
prometheus_sd_kubernetes_events_total(role="pod", event="delete")
prometheus_sd_kubernetes_events_total(role="pod", event="update")
role

标识资源类型,包括:

"endpointslice", "endpoints", "node", "pod", "service", "ingress"

五种类型;

event

标识事件类型,包括:

"add", "delete", "update"

三种类型。

4、事件处理,

AddFunc

DeleteFunc

UpdateFunc

注册的事件处理逻辑一样,处理逻辑也比较简单:就是获取资源对象

key

,并将其写入到

Workqueue

中;
77998e9a80ff289c3f7a24997cf92ed0.png

对于

POD

资源,这里的

key

就是:

namespace/pod_name

格式,比如

key=test01/nginx-deployment-5ffc5bf56c-n2pl8

5、给

Workqueue

注册一个无限循环处理逻辑,就能持续从

Workqueue

中取出

key

进行处理;
42825715be44b2548a2b3a7332cab5f2.png

针对

Pod

里的每个

Container

上的每个

port

,都会生成一个对应采集点

target

,其中

__address__

就是

PodIP
  • port
    

    组合。

6、最后启动

Informer

,让整个流程运转起来;
653098546eee905e15331f674ff41f13.pngc231106b62994cf1958b314e5f82aa82.gif
「更多云原生监控运维知识,请关注公众号:Reactor2020」


本文转载自: https://blog.csdn.net/god_86/article/details/129512438
版权归原作者 Reactor2020 所有, 如有侵权,请联系我们删除。

“Prometheus 云原生kubernetes服务发现原理图解”的评论:

还没有评论