Prometheus服务发现机制之Kubernetes
概述
分析过云原生监控接入方案,下面开始看下云原生服务发现机制。Prometheus本身就是作为云原生监控出现的,所以对云原生服务发现支持具有天然优势。Kubernetes
服务发现协议允许使用Kubernetes Rest API
检索出Prometheus
需要监控的targets
,并且跟着集群状态进行同步变更。
(资料图片仅供参考)
kubernetes_sd_configs
表示基于Kubernetes
进行服务发现,服务发现目标类型使用role
表示,比如:role=service
,表示针对Kubernetes
中的service
资源对象,进行具体的服务发现操作。kubernetes_sd_configs
支持的role
包括:node、service、pod、endpoints、ingress
。
原理
基于Kubernetes
进行服务发现,主要针对Kubernetes
中的service、pod、node
等资源对象进行服务发现,Prometheus
使用client-go
对role
中指定的资源对象进行监听。一般Prometheus
部署在Kubernetes
集群中的话,Prometheus
可以直接利用指定的Service Account
对Kubernetes API
进行访问。若Prometheus
在Kubernetes
集群之外,则kubernetes_sd_configs
还需指定监控集群的API Server
的URL
以及相关的认证信息,从而能够创建对应集群的Client
。
“client-go是kubernetes官方提供的go语言的客户端库,go应用使用该库可以访问kubernetes的API Server,这样我们就能通过编程来对kubernetes资源进行增删改查操作。
配置示例:
- job_name: kubernetes-pod metrics_path: /metrics kubernetes_sd_configs: - role: pod namespaces: names: - "test01" api_server: https://apiserver.simon:6443 bearer_token_file: d:/token.k8s tls_config: insecure_skip_verify: true bearer_token_file: d:/token.k8s tls_config: insecure_skip_verify: true
协议分析
Kubernetes
服务发现大致原理如下图:
1、通过clientset
访问API Server
,根据role
配置获取不同的集群资源对象;
2、通过List & Watch
机制,注册监听事件:
p.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(o interface{}) { podAddCount.Inc() p.enqueue(o) }, DeleteFunc: func(o interface{}) { podDeleteCount.Inc() p.enqueue(o) }, UpdateFunc: func(_, o interface{}) { podUpdateCount.Inc() p.enqueue(o) },})
通过informer.AddEventHandler
函数可以为集群资源添加资源事件回调方法,支持3种资源事件回调方法:AddFunc、DeleteFunc、UpdateFunc
,分别对应新增资源、修改资源和删除资源时事件触发。
3、资源变更注册回调方法中,将目标资源对象转成key
放入到队列queue
中,如下pod
资源:
func (p *Pod) enqueue(obj interface{}) { //obj是pod资源对象,通过DeletionHandlingMetaNamespaceKeyFunc将其转换成key //比如key=test01/nginx-deployment-5ffc5bf56c-n2pl8,即namespace/pod_name格式 key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) if err != nil { return } p.queue.Add(key)}
4、后台goroutines
无限循环执行process
逻辑,process
逻辑中就是不停从queue
中提取数据进行处理,比如pod.go
对应逻辑如下:
func (p *Pod) process(ctx context.Context, ch chan<- []*targetgroup.Group) bool { keyObj, quit := p.queue.Get() if quit { return false } defer p.queue.Done(keyObj) key := keyObj.(string) //与 MetaNamespaceKeyFunc() 功能相反的是 SplitMetaNamespaceKey() 函数,它将传入的 Key 分解,返回对象所在的命名空间和对象名称。 namespace, name, err := cache.SplitMetaNamespaceKey(key) if err != nil { return true } //根据key获取资源对象obj o, exists, err := p.store.GetByKey(key) if err != nil { return true } if !exists { //pod被删除时,exists=false // 然后发送targets为空的tg,即移除 send(ctx, ch, &targetgroup.Group{Source: podSourceFromNamespaceAndName(namespace, name)}) return true } pod, err := convertToPod(o) if err != nil { level.Error(p.logger).Log("msg", "converting to Pod object failed", "err", err) return true } //p.buildPod(pod):将资源对象信息转成target groups send(ctx, ch, p.buildPod(pod)) return true}
大致逻辑:
a、根据从queue
中提取的key
,使用p.store.GetByKey(key)
获取对应的资源对象,比如pod、service
等对象;
b、如果对象不存在,则表示资源对象被删除,则创建一个targets
集合为空的target groups
,这样Scrape Manager
就会移除targets
;
c、使用buildXXX(obj)
将资源对象解析成target groups
,如buildNode()、buildPod()
等;
d、最后使用send()
方法将解析的target groups
通过通道channel
传递出去,最终传递给Scrape Manager
,这样target groups
中targets
将被Prometheus
抓取监控数据。
pod
资源的target groups
结构如下示例,每个pod对象都会被解析成target groups
,其中包含targets
集合、labels
标签集合:
Discovery创建
1、假如我们定义如下抓取作业:
- job_name: kubernetes-nodes-cadvisor metrics_path: /metrics scheme: https kubernetes_sd_configs: - role: node api_server: https://apiserver.simon:6443 bearer_token_file: d:/token.k8s tls_config: insecure_skip_verify: true bearer_token_file: d:/token.k8s tls_config: insecure_skip_verify: true relabel_configs: # 将标签(.*)作为新标签名,原有值不变 - action: labelmap regex: __meta_kubernetes_node_label_(.*) # 修改NodeIP:10250为APIServerIP:6443 - action: replace regex: (.*) source_labels: ["__address__"] target_label: __address__ replacement: 192.168.52.151:6443 - action: replace source_labels: [__meta_kubernetes_node_name] target_label: __metrics_path__ regex: (.*) replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
会被解析成kubernetes.SDConfig
如下:
kubernetes.SDConfig
定义如下:
type SDConfig struct { APIServer config.URL `yaml:"api_server,omitempty"` Role Role `yaml:"role"` HTTPClientConfig config.HTTPClientConfig `yaml:",inline"` NamespaceDiscovery NamespaceDiscovery `yaml:"namespaces,omitempty"` Selectors []SelectorConfig `yaml:"selectors,omitempty"`}
2、Discovery
创建
//创建Clientset,可看成操作Kubernetes API的客户端c, err := kubernetes.NewForConfig(kcfg) if err != nil { return nil, err }return &Discovery{ client: c, logger: l, role: conf.Role, namespaceDiscovery: &conf.NamespaceDiscovery, discoverers: make([]discovery.Discoverer, 0), selectors: mapSelector(conf.Selectors),}, nil
3、Discovery
创建完成,最后会调用Discovery.Run()
启动服务发现:
func (d *Discovery) Run(ctx context.Context, ch chan<- []*targetgroup.Group) { d.Lock() namespaces := d.getNamespaces() switch d.role { case RoleEndpointSlice: role=endpointslice逻辑 case RoleEndpoint: role=endpoints逻辑 case RolePod: role=pod逻辑 case RoleService: role=service逻辑 case RoleIngress: role=ingress逻辑 case RoleNode: role=node逻辑 default: level.Error(d.logger).Log("msg", "unknown Kubernetes discovery kind", "role", d.role) } var wg sync.WaitGroup for _, dd := range d.discoverers { wg.Add(1) go func(d discovery.Discoverer) { defer wg.Done() d.Run(ctx, ch) }(dd) } d.Unlock() wg.Wait() <-ctx.Done()}
4、注册集群资源对象监听事件回调逻辑:
for _, namespace := range namespaces { p := d.client.CoreV1().Pods(namespace) plw := &cache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { options.FieldSelector = d.selectors.pod.field options.LabelSelector = d.selectors.pod.label return p.List(ctx, options) }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { options.FieldSelector = d.selectors.pod.field options.LabelSelector = d.selectors.pod.label return p.Watch(ctx, options) }, } pod := NewPod( log.With(d.logger, "role", "pod"), cache.NewSharedInformer(plw, &apiv1.Pod{}, resyncPeriod), ) d.discoverers = append(d.discoverers, pod) go pod.informer.Run(ctx.Done())}
关键词:
分析过云原生监控接入方案,下面开始看下云原生服务发现机制。Prometheus本身就是作为云原生监控出现的,所以对云原生服务发现支持具有天然优2023-03-25
PDF(PortableDocumentFormat)意思是便携式文件格式,是一种由Adobe公司设计,用独立于应用程序、硬件、操作系统的方式呈现文档的文件格式2023-03-25
兰蔻菁纯眼霜是一款知名的护肤品,被广大消费者认可为对待眼部肌肤问题非常有效的产品之一。下面,我们将从成分、功效、使用方法等角度来为大2023-03-25
整治交通顽瘴痼疾丨一季度全市查处各类交通违法42 5万起2023-03-25
1、肝郁气滞选用中药汤剂,是因为中药汤剂是医生通过自己丰富的临床经验,综合评估患者的临床表现而确定的个性化用药。2、首先2023-03-25
3月24日,广发集丰债券A最新单位净值为1 129元,累计净值为1 373元,较前一交易日下跌0 09%。历史数据显示该基金近1个月上涨0 36%,近3个月上2023-03-25
从姚明的NBA表现看:姚明开创了许多个第一——他在2002年以状元秀身份加盟火箭,是亚洲首位状元秀,也是NBA历史上第一个海外状元秀。姚明一共2023-03-24
(资料图片)在福特汽车(F US)公布了电动汽车业务的盈利时间表后,华尔街多家投行初步反应基本上是积极的。福特预计,到2026年底,电动汽车部门2023-03-24
中原网讯3月24日下午,郑东新区第四届机关健步走活动在龙湖金融岛举行,30余家机关单位和4大国有企业1600余人相聚龙湖之滨,以“健步走”的形2023-03-24
德天空:图赫尔用比赛理念让拜仁高层信服,双方最终达成一致,拜仁,多特,德天空,德国足球,足球竞赛,足球教练,纳格尔斯曼,英格兰足球,托马斯·图2023-03-24
3月18日,市人民医院邀请全国名老中医王道坤教授及其团队来医院开展坐诊、教学、查房、疑难病例会诊、讲座等一系列学术活动。2023-03-24
截至2023年3月24日收盘,晶赛科技(871981)报收于12 85元,上涨4 73%,换手率0 91%,成交量3559 0手,成交额453 2万元。2023-03-24
最近成都疫情也引起了大家关注,很多小伙伴都有注意到,近日成都疫情的本土病例增长较快,有消息称,成都新增的17名确诊病例与同一酒吧有关联2023-03-24
沈阳会见绿色江河环保促进会会长杨欣2023-03-24
3月24日下午,寒武纪午后再度大涨10%,股价创近2年半新高,本周累涨近50%,年内涨幅接近250%,仅次于中航电测暂居2023-03-24
据“中国钢铁工业协会”微信号消息,中国钢铁工业协会在安徽马鞍山召开“基石计划”国内铁矿资源开发工作座谈会。中钢协副会长骆铁军强调,下2023-03-24
3月24日上午,在花都区气象局发布冰雹橙色预警信号不久后,花都区部分地区就下起了大雨加冰雹,密集的冰雹打在铁皮屋顶上、车玻璃上噼啪作响。2023-03-24
2022年,昌平区技术市场认定登记技术合同2390项,成交额362 6亿元,位列全市第六;成交额同比增长101 2%,增速位列全市第四。”北京品驰医疗设2023-03-24
河南广电·大象新闻记者龚雪通讯员张远“您好,您通过电子税务局申请的退税业务符合退税要求,但资料不齐全,建议您先在线2023-03-24
1、《庆余年》范闲娶了五个妻子,分别是正室晨郡主林婉儿,侧室大丫鬟柳思思、北齐圣女海棠朵朵、北齐贵妃司理理和北齐女帝战豆豆。2、正室林2023-03-24
搞汽车的朋友如果熟悉汽车产品周期,会知道汽车产品生命周期一般是7年左右。一般汽车上市后的第2年左右上市小改款,第4年左右上市大改款,之后2023-03-24
北京时间3月24日03:45,欧洲杯预选赛小组赛C组第1轮,意大利坐镇马拉多纳球场迎战英格兰,本场主裁判为约万诺维奇,赛前双方首发出炉。意大利2023-03-24
3月23日电,联合国秘书长古特雷斯与欧洲理事会举行工作会议。会议重申对《联合国宪章》及其原则的充分承诺,强调了对以联合国为核心的多边主义2023-03-23
《关于加强新市民金融服务工作的通知》印发已一年有余,兴业银行通过成立由行领导为组长的新市民金融服务工作领导小组,建立健全新市民金融服2023-03-23
名侦探柯南中好看的集数:001集,云霄飞车杀人事件;002集,董事长千金绑架事件;011集,钢琴奏鸣曲月光杀人事件;043集,江户川柯南诱拐事件2023-03-23
