日期:2023-03-25 22:05:56 来源:腾讯云
分析过云原生监控接入方案,下面开始看下云原生服务发现机制。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
标签集合:
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】-08 图解云原生服务发现机制 天天观速讯
乳源瑶族自治县气象台发布暴雨黄色预警【III级/较重】【2023-03-25】 环球快播
中国驻日大使吴江浩到任拜会日本自民党前干事长二阶俊博 世界新消息
why是啥意思
外交部发言人:中方反对美国“有罪推定”和无理打压有关企业 全球关注
环球微动态丨三体搬运长评
观世音菩萨歌曲大全100首_观世音菩萨歌曲
每日快报!什么是陈皮
中农立华与拜耳签署新业务的合作协议书 今日关注
搭3.0T,售118.98万,玛莎拉蒂Levante特别版,致敬F1首位女车手 环球报资讯
环球微动态丨股票行情快报:光线传媒(300251)3月24日主力资金净卖出1847.20万元
60余名在豫台胞集中办理医保:拿到属于自己的医保卡太开心了! 世界热门
中国最大的渔具批发市场在哪
举杯消愁愁更愁上一句
七8九歌曲慕容晓晓_七8九
CBA三大黑马现状:山西被打回原形 一队从榜首跌至第12名? 世界关注
天天消息!作字组词语_汉字作字组词语
美否认与“北溪”爆炸有关 俄:对调查透明度不抱期望-天天实时
珠海高新区探索盘活存量土地 “国企+村集体”共建5.0产业新空间 环球观点
鼓励自己的个性签名
今亮点!华福证券:给予分众传媒买入评级,目标价位10.6元
今日播报!法拉第未来宣布启动FF 91 Futurist开始生产倒计时
首批主板注册制 IPO 定价结果揭晓!23 倍发行市盈率终成历史,这些“打新要点”你需要知道!-天天时快讯
安徽2023年省考笔试分数线公布 同步晒出达线人员成绩-环球新动态
单眼皮眼妆怎么画自然又好看_单眼皮眼妆-今日精选