Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >kubernetes 中 informer 的使用

kubernetes 中 informer 的使用

原创
作者头像
田飞雨
修改于 2019-12-13 10:40:48
修改于 2019-12-13 10:40:48
4.4K0
举报
文章被收录于专栏:田飞雨的专栏田飞雨的专栏
一、kubernetes 集群的几种访问方式

在实际开发过程中,若想要获取 kubernetes 中某个资源(比如 pod)的所有对象,可以使用 kubectl、k8s REST API、client-go(ClientSet、Dynamic Client、RESTClient 三种方式) 等多种方式访问 k8s 集群获取资源。在笔者的开发过程中,最初都是直接调用 k8s 的 REST API 来获取的,使用 kubectl get pod -v=9 可以直接看到调用 k8s 的接口,然后在程序中直接访问还是比较方便的。但是随着集群规模的增长或者从国内获取海外 k8s 集群的数据,直接调用 k8s 接口获取所有 pod 还是比较耗时,这个问题有多种解决方法,最初是直接使用 k8s 原生的 watch 接口来获取的,下面是一个伪代码:

代码语言:txt
AI代码解释
复制
const (

    ADDED    string = "ADDED"

    MODIFIED string = "MODIFIED"

    DELETED  string = "DELETED"

    ERROR    string = "ERROR"

)



type Event struct {

    Type   string          `json:"type"`

    Object json.RawMessage `json:"object"`

}



func main() {

    resp, err := http.Get("http://apiserver:8080/api/v1/watch/pods?watch=yes")

    if err != nil {

        // ...

    }

    decoder := json.NewDecoder(resp.Body)

    for {

        var event Event

        err = decoder.Decode(&event)

        if err != nil {

            // ...

        }

        switch event.Type {

        case ADDED, MODIFIED:

            // ...

        case DELETED:

            // ...

        case ERROR:

            // ...

        }

    }

}

调用 watch 接口后会先将所有的对象 list 一次,然后 apiserver 会将变化的数据推送到 client 端,可以看到每次对于 watch 到的事件都需要判断后进行处理,然后将处理后的结果写入到本地的缓存中,原生的 watch 操作还是非常麻烦的。后来了解到官方推出一个客户端工具 client-go ,client-go 中的 Informer 对 watch 操作做了封装,使用起来非常方便,下面会主要介绍一下 client-go 的使用。

二、Informer 的机制

cient-go 是从 k8s 代码中抽出来的一个客户端工具,Informer 是 client-go 中的核心工具包,已经被 kubernetes 中众多组件所使用。所谓 Informer,其实就是一个带有本地缓存和索引机制的、可以注册 EventHandler 的 client,本地缓存被称为 Store,索引被称为 Index。使用 informer 的目的是为了减轻 apiserver 数据交互的压力而抽象出来的一个 cache 层, 客户端对 apiserver 数据的 "读取" 和 "监听" 操作都通过本地 informer 进行。Informer 实例的Lister()方法可以直接查找缓存在本地内存中的数据。

Informer 的主要功能:

  • 同步数据到本地缓存
  • 根据对应的事件类型,触发事先注册好的 ResourceEventHandle
1、Informer 中几个组件的作用

Informer 中主要有 Reflector、Delta FIFO Queue、Local Store、WorkQueue 几个组件。以下是 Informer 的工作流程图。

Informer 组件
Informer 组件

根据流程图来解释一下 Informer 中几个组件的作用:

  • Reflector:称之为反射器,实现对 apiserver 指定类型对象的监控(ListAndWatch),其中反射实现的就是把监控的结果实例化成具体的对象,最终也是调用 Kubernetes 的 List/Watch API;
  • DeltaIFIFO Queue:一个增量队列,将 Reflector 监控变化的对象形成一个 FIFO 队列,此处的 Delta 就是变化;
  • LocalStore:就是 informer 的 cache,这里面缓存的是 apiserver 中的对象(其中有一部分可能还在DeltaFIFO 中),此时使用者再查询对象的时候就直接从 cache 中查找,减少了 apiserver 的压力,LocalStore 只会被 Lister 的 List/Get 方法访问。
  • WorkQueue:DeltaIFIFO 收到时间后会先将时间存储在自己的数据结构中,然后直接操作 Store 中存储的数据,更新完 store 后 DeltaIFIFO 会将该事件 pop 到 WorkQueue 中,Controller 收到 WorkQueue 中的事件会根据对应的类型触发对应的回调函数。
2、Informer 的工作流程
  • Informer 首先会 list/watch apiserver,Informer 所使用的 Reflector 包负责与 apiserver 建立连接,Reflector 使用 ListAndWatch 的方法,会先从 apiserver 中 list 该资源的所有实例,list 会拿到该对象最新的 resourceVersion,然后使用 watch 方法监听该 resourceVersion 之后的所有变化,若中途出现异常,reflector 则会从断开的 resourceVersion 处重现尝试监听所有变化,一旦该对象的实例有创建、删除、更新动作,Reflector 都会收到"事件通知",这时,该事件及它对应的 API 对象这个组合,被称为增量(Delta),它会被放进 DeltaFIFO 中。
  • Informer 会不断地从这个 DeltaFIFO 中读取增量,每拿出一个对象,Informer 就会判断这个增量的时间类型,然后创建或更新本地的缓存,也就是 store。
  • 如果事件类型是 Added(添加对象),那么 Informer 会通过 Indexer 的库把这个增量里的 API 对象保存到本地的缓存中,并为它创建索引,若为删除操作,则在本地缓存中删除该对象。
  • DeltaFIFO 再 pop 这个事件到 controller 中,controller 会调用事先注册的 ResourceEventHandler 回调函数进行处理。
  • 在 ResourceEventHandler 回调函数中,其实只是做了一些很简单的过滤,然后将关心变更的 Object 放到 workqueue 里面。
  • Controller 从 workqueue 里面取出 Object,启动一个 worker 来执行自己的业务逻辑,业务逻辑通常是计算目前集群的状态和用户希望达到的状态有多大的区别,然后孜孜不倦地让 apiserver 将状态演化到用户希望达到的状态,比如为 deployment 创建新的 pods,或者是扩容/缩容 deployment。
  • 在worker中就可以使用 lister 来获取 resource,而不用频繁的访问 apiserver,因为 apiserver 中 resource 的变更都会反映到本地的 cache 中。

Informer 在使用时需要先初始化一个 InformerFactory,目前主要推荐使用的是 SharedInformerFactory,Shared 指的是在多个 Informer 中共享一个本地 cache。

Informer 中的 ResourceEventHandler 函数有三种:

代码语言:txt
AI代码解释
复制
// ResourceEventHandlerFuncs is an adaptor to let you easily specify as many o

// as few of the notification functions as you want while still implementing

// ResourceEventHandler.

type ResourceEventHandlerFuncs struct {

    AddFunc    func(obj interface{})

    UpdateFunc func(oldObj, newObj interface{})

    DeleteFunc func(obj interface{})

}

这三种函数的处理逻辑是用户自定义的,在初始化 controller 时注册完 ResourceEventHandler 后,一旦该对象的实例有创建、删除、更新三中操作后就会触发对应的 ResourceEventHandler。

三、Informer 使用示例

在实际的开发工作中,Informer 主要用在两处:

  • 在访问 k8s apiserver 的客户端作为一个 client 缓存对象使用;
  • 在一些自定义 controller 中使用,比如 operator 的开发;
1、下面是一个作为 client 的使用示例:
代码语言:txt
AI代码解释
复制
package main



import (

    "flag"

    "fmt"

    "log"

    "path/filepath"



    corev1 "k8s.io/api/core/v1"

    "k8s.io/apimachinery/pkg/labels"

    "k8s.io/apimachinery/pkg/util/runtime"



    "k8s.io/client-go/informers"

    "k8s.io/client-go/kubernetes"

    "k8s.io/client-go/tools/cache"

    "k8s.io/client-go/tools/clientcmd"

    "k8s.io/client-go/util/homedir"

)



func main() {

    var kubeconfig \*string

    if home := homedir.HomeDir(); home != "" {

        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")

    } else {

        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")

    }

    flag.Parse()



    config, err := clientcmd.BuildConfigFromFlags("", \*kubeconfig)

    if err != nil {

        panic(err)

    }



    // 初始化 client

    clientset, err := kubernetes.NewForConfig(config)

    if err != nil {

        log.Panic(err.Error())

    }



    stopper := make(chan struct{})

    defer close(stopper)



    // 初始化 informe

    factory := informers.NewSharedInformerFactory(clientset, 0)

    nodeInformer := factory.Core().V1().Nodes()

    informer := nodeInformer.Informer()

    defer runtime.HandleCrash()



    // 启动 informer,list & watch

    go factory.Start(stopper)



    // 从 apiserver 同步资源,即 list

    if !cache.WaitForCacheSync(stopper, informer.HasSynced) {

        runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))

        return

    }



    // 使用自定义 handle

    informer.AddEventHandler(cache.ResourceEventHandlerFuncs{

        AddFunc:    onAdd,

        UpdateFunc: func(interface{}, interface{}) { fmt.Println("update not implemented") }, // 此处省略 workqueue 的使用

        DeleteFunc: func(interface{}) { fmt.Println("delete not implemented") },

    })



    // 创建 liste

    nodeLister := nodeInformer.Lister()

    // 从 lister 中获取所有 items

    nodeList, err := nodeLister.List(labels.Everything())

    if err != nil {

        fmt.Println(err)

    }

    fmt.Println("nodelist:", nodeList)

    <-stoppe

}



func onAdd(obj interface{}) {

    node := obj.(\*corev1.Node)

    fmt.Println("add a node:", node.Name)

}

Shared指的是多个 lister 共享同一个cache,而且资源的变化会同时通知到cache和 listers。这个解释和上面图所展示的内容的是一致的,cache我们在Indexer的介绍中已经分析过了,lister 指的就是OnAdd、OnUpdate、OnDelete 这些回调函数背后的对象。

2、以下是作为 controller 使用的一个整体工作流程

(1) 创建一个控制器

  • 为控制器创建 workqueue
  • 创建 informer, 为 informer 添加 callback 函数,创建 liste

(2) 启动控制器

  • 启动 informe
  • 等待本地 cache sync 完成后, 启动 workers

(3) 当收到变更事件后,执行 callback

  • 等待事件触发
  • 从事件中获取变更的 Object
  • 做一些必要的检查
  • 生成 object key,一般是 namespace/name 的形式
  • 将 key 放入 workqueue 中

(4) worker loop

  • 等待从 workqueue 中获取到 item,一般为 object key
  • 用 object key 通过 lister 从本地 cache 中获取到真正的 object 对象
  • 做一些检查
  • 执行真正的业务逻辑
  • 处理下一个 item

下面是自定义 controller 使用的一个参考:

代码语言:txt
AI代码解释
复制
var (

    masterURL  string

    kubeconfig string

)



func init() {

    flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")

    flag.StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")

}



func main() {

    flag.Parse()



    stopCh := signals.SetupSignalHandler()



    cfg, err := clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)

    if err != nil {

        glog.Fatalf("Error building kubeconfig: %s", err.Error())

    }



    kubeClient, err := kubernetes.NewForConfig(cfg)

    if err != nil {

        glog.Fatalf("Error building kubernetes clientset: %s", err.Error())

    }



    // 所谓 Informer,其实就是一个带有本地缓存和索引机制的、可以注册 EventHandler 的 client

    // informer watch apiserver,每隔 30 秒 resync 一次(list)

    kubeInformerFactory := informers.NewSharedInformerFactory(kubeClient, time.Second\*30)



    controller := controller.NewController(kubeClient, kubeInformerFactory.Core().V1().Nodes())



    //  启动 informe

    go kubeInformerFactory.Start(stopCh)



     // start controlle

    if err = controller.Run(2, stopCh); err != nil {

        glog.Fatalf("Error running controller: %s", err.Error())

    }

}





// NewController returns a new network controlle

func NewController(

    kubeclientset kubernetes.Interface,

    networkclientset clientset.Interface,

    networkInformer informers.NetworkInformer) \*Controller {



    // Create event broadcaste

    // Add sample-controller types to the default Kubernetes Scheme so Events can be

    // logged for sample-controller types.

    utilruntime.Must(networkscheme.AddToScheme(scheme.Scheme))

    glog.V(4).Info("Creating event broadcaster")

    eventBroadcaster := record.NewBroadcaster()

    eventBroadcaster.StartLogging(glog.Infof)

    eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")})

    recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName})



    controller := &Controller{

        kubeclientset:    kubeclientset,

        networkclientset: networkclientset,

        networksLister:   networkInformer.Lister(),

        networksSynced:   networkInformer.Informer().HasSynced,

        workqueue:        workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Networks"),

        recorder:         recorder,

    }



    glog.Info("Setting up event handlers")

    // Set up an event handler for when Network resources change

    networkInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{

        AddFunc: controller.enqueueNetwork,

        UpdateFunc: func(old, new interface{}) {

            oldNetwork := old.(\*samplecrdv1.Network)

            newNetwork := new.(\*samplecrdv1.Network)

            if oldNetwork.ResourceVersion == newNetwork.ResourceVersion {

                // Periodic resync will send update events for all known Networks.

                // Two different versions of the same Network will always have different RVs.

                return

            }

            controller.enqueueNetwork(new)

        },

        DeleteFunc: controller.enqueueNetworkForDelete,

    })



    return controlle

}

自定义 controller 的详细使用方法可以参考:k8s-controller-custom-resource

四、使用中的一些问题
1、Informer 二级缓存中的同步问题

虽然 Informer 和 Kubernetes 之间没有 resync 机制,但 Informer 内部的这两级缓存 DeltaIFIFO 和 LocalStore 之间会存在 resync 机制,k8s 中 kube-controller-manager 的 StatefulSetController 中使用了两级缓存的 resync 机制(如下图所示),我们在生产环境中发现 sts 创建后过了很久 pod 才会创建,主要是由于 StatefulSetController 的两级缓存之间 30s 会同步一次,由于 StatefulSetController watch 到变化后就会把对应的 sts 放入 DeltaIFIFO 中,且每隔30s会把 LocalStore 中全部的 sts 重新入一遍 DeltaIFIFO,入队时会做一些处理,过滤掉一些不需要重复入队列的 sts,若间隔的 30s 内没有处理完队列中所有的 sts,则待处理队列中始终存在未处理完的 sts,并且在同步过程中产生的 sts 会加的队列的尾部,新加入队尾的 sts 只能等到前面的 sts 处理完成(也就是 resync 完成)才会被处理,所以导致的现象就是 sts 创建后过了很久 pod 才会创建。

优化的方法就是去掉二级缓存的同步策略(将 setInformer.Informer().AddEventHandlerWithResyncPeriod() 改为 informer.AddEventHandler())或者调大同步周期,但是在研究 kube-controller-manager 其他 controller 时发现并不是所有的 controller 都有同步策略,社区也有相关的 issue 反馈了这一问题,Remove resync period for sset controller,社区也会在以后的版本中去掉两级缓存之间的 resync 策略。

k8s.io/kubernetes/pkg/controller/statefulset/stateful\_set.go

kube-controller-manager sts controller
kube-controller-manager sts controller
2、使用 Informer 如何监听所有资源对象?

一个 Informer 实例只能监听一种 resource,每个 resource 需要创建对应的 Informer 实例。

3、为什么不是使用 workqueue?

建议使用 RateLimitingQueue,它相比普通的 workqueue 多了以下的功能:

  • 限流:可以限制一个 item 被 reenqueued 的次数。
  • 防止 hot loop:它保证了一个 item 被 reenqueued 后,不会马上被处理。
五、总结

本文介绍了 client-go 包中核心组件 Informer 的原理以及使用方法,Informer 主要功能是缓存对象到本地以及根据对应的事件类型触发已注册好的 ResourceEventHandler,其主要用在访问 k8s apiserver 的客户端和 operator 中。

参考:

如何用 client-go 拓展 Kubernetes 的 API

https://www.kubernetes.org.cn/2693.html

Kubernetes 大咖秀徐超《使用 client-go 控制原生及拓展的 Kubernetes API》

Use prometheus conventions for workqueue metrics

深入浅出kubernetes之client-go的workqueue

https://gianarb.it/blog/kubernetes-shared-informer

理解 K8S 的设计精髓之 List-Watch机制和Informer模块

https://ranler.org/notes/file/528

Kubernetes Client-go Informer 源码分析

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
《一起读 kubernetes 源码》揭秘 k8s 关键机制 informer
在第二章我们会去看 k8s 中常用对象的源码,不过在看这些对象之前,我们需要聊一聊 informer 机制。这个机制可以说是 k8s 设计之中的一个重点了。这个机制的设计不仅仅让代码本身变得清晰,更让整个系统的结构更容易扩展。所以这个机制需要放到第二章的第一节来说。
LinkinStar
2024/05/01
3290
《一起读 kubernetes 源码》揭秘 k8s 关键机制 informer
Operator示例:通过Operator+CRD实现部署自动化
在上一篇通过Operator自动暴露集群内部服务中,遗留了一个问题:开发人员or业务上游是需要关注k8s内建资源,例如deployment如何定义,这和K8S自动化的目标背道而驰。 本篇文章将采用CRD(CustomResourceDefinition)来屏蔽底层K8S资源,让开发人员只需要按照我们制定的规则来定义CR即可。至于创建deployment,service,ingress等操作就可以交给Operator来完成,从而实现部署自动化。 而自动化就可以对接业务系统,使其实现业务价值。例如根据授权信息,创建租户购买的产品服务,当授权到期时,自动删除对应资源。
Yuyy
2024/01/22
8030
Operator示例:通过Operator+CRD实现部署自动化
k8s informer 是如何保证事件不丢失的?
我们知道 k8s 里重要概念之一就是 声明式 API,比如 kubectl apply 就是声明式 API的实现。
没有故事的陈师傅
2024/01/10
6120
k8s informer 是如何保证事件不丢失的?
Kubernetes 中 Informer 的使用
前面我们在使用 Clientset 的时候了解到我们可以使用 Clientset 来获取所有的原生资源对象,那么如果我们想要去一直获取集群的资源对象数据呢?岂不是需要用一个轮询去不断执行 List() 操作?这显然是不合理的,实际上除了常用的 CRUD 操作之外,我们还可以进行 Watch 操作,可以监听资源对象的增、删、改、查操作,这样我们就可以根据自己的业务逻辑去处理这些数据了。
我是阳明
2020/08/04
2.1K0
Kubernetes 中 Informer 的使用
Kubernetes Informer基本原理
不论是 k8s 自身组件,还是自己编写 controller,都需要通过 apiserver 监听 etcd 事件来完成自己的控制循环逻辑。
政采云前端团队
2024/01/30
5930
Kubernetes Informer基本原理
client-go实战之九:手写一个kubernetes的controller
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 系列文章链接 client-go实战之一:准备工作 client-go实战之二:RESTClient client-go实战之三:Clientset client-go实战之四:dynamicClient client-go实战之五:DiscoveryClient client-go实战之六:时隔两年,刷新版本继续实战 client-go实战之七:准备一个工
程序员欣宸
2023/02/13
1.7K0
client-go实战之九:手写一个kubernetes的controller
kubernetes client-go解析
Indexer保存了来自apiServer的资源。使用listWatch方式来维护资源的增量变化。通过这种方式可以减小对apiServer的访问,减轻apiServer端的压力
charlieroro
2020/03/24
1.3K1
kubernetes client-go解析
理解 K8S 的设计精髓之 List-Watch机制和Informer模块
最近想深入了解一下K8S的内部通信机制,因此读了几遍K8S的源码,感慨很深。至今清楚的记得,当了解到K8S 组件之间仅采用HTTP 协议通信,没有依赖中间件时,我非常好奇它是如何做到的。
云爬虫技术研究笔记
2019/11/05
3.6K0
Kubernetes之Informer机制详解
本文尝试从Informer中的Lister、Watcher、Indexer、Store及Controller 5个组件展开对其进行详细阐述。希望对您有所帮助!
锅总
2024/06/28
1.6K0
Kubernetes之Informer机制详解
浅谈 K8s Informer
进入 K8s 的世界,会发现有很多的 Controller,它们都是为了完成某类资源(如 pod 是通过 DeploymentController, ReplicaSetController 进行管理)的调谐,目标是保持用户期望的状态。
astraw99
2021/09/14
1.5K2
浅谈 K8s Informer
k8s源码分析- Informer机制
由于Informer这部分的源码比较复杂,调用链路也很长,后面的源码分析,都会围绕这一张图展开。
kinnylee
2020/10/15
5.5K0
k8s源码分析- Informer机制
16.深入k8s:Informer使用及其源码分析
这次讲解我用了很一些图,尽可能的把这个模块给描述清楚,如果感觉对你有所帮助不妨发一封邮件激励一下我~
luozhiyun
2020/10/28
2.6K0
16.深入k8s:Informer使用及其源码分析
如何高效掌控K8s资源变化?K8s Informer实现机制浅析
作者:腾讯云云巢团队研发工程师 王成 导语:本文通过分析 K8s 中 Reflector(反射器)、DeletaFIFO(增量队列)、Indexer(索引器)、Controller(控制器)、SharedInformer(共享资源通知器)、processorListener(事件监听处理器)、workqueue(事件处理工作队列) 等组件,对 Informer 实现机制进行了解析。 PART ONE 概述 进入 K8s 的世界,会发现有很多的 Controller,它们都是为了完成某类资源(如 pod
腾源会
2021/09/15
5340
你真的搞懂 Informer 了吗?
Informer 作为 client-go 的核心,网上有众多的源码分析,原理解析相关文章,可以教给大家如何"正确"的使用 Informer。当然其前提是在 Informer 本身逻辑没问题的前提下,本篇旨在为大家指出几个 Informer 里面长期存在甚至现在仍然存在的问题。
李鹤
2023/10/16
5310
你真的搞懂 Informer 了吗?
编写一个operator扩展kubernetes能力
Operator 是 CoreOS 推出的旨在简化复杂有状态应用管理,它是一个感知应用状态的控制器,通过扩展 Kubernetes API 来自动创建、管理和配置应用实例。 Operator 基于 CRD 扩展资源对象,并通过控制器来保证应用处于预期状态。
我的小碗汤
2019/04/25
2.6K0
编写一个operator扩展kubernetes能力
Kubernetes CRD 自定义控制器
上文我们学习了如何使用 code-generator 来进行代码自动生成,通过代码自动生成可以帮我们自动生成 CRD 资源对象客户端访问的 ClientSet、Informer、Lister 等工具包,接下来我们来了解下如何编写一个自定义的控制器。
我是阳明
2020/10/26
2.3K0
Kubernetes CRD 自定义控制器
k8s自定义controller三部曲之三:编写controller代码
本文是《k8s自定义controller三部曲》的终篇,前面的章节中,我们创建了CRD,再通过自动生成代码的工具将controller所需的informer、client等依赖全部准备好,到了本章,就该编写controller的代码了,也就是说,现在已经能监听到Student对象的增删改等事件,接下来就是根据这些事件来做不同的事情,满足个性化的业务需求;
程序员欣宸
2019/05/31
1.6K0
mac 上学习k8s系列(21)CRD (part III)
今天继续从https://github.com/kubernetes/sample-controller入手,分析crd的源码:
golangLeetcode
2022/08/02
3770
图解K8s源码 - kube-controller-manager篇
在kubernetes master节点中最重要的三个组件是:kube-apiserver、kube-controller-manager、kube-scheduler 分别负责k8s集群的资源访问入口、集群状态管理、集群调度。我们在之前的文章介绍了集群资源访问入口kube-apiserver “图解K8s源码 - kube-apiserver篇”,本篇尝试梳理清楚 kube-controller-manager 是如何“Manage Controller”的。
才浅Coding攻略
2022/12/12
9800
图解K8s源码 - kube-controller-manager篇
Kubernetes的client-go库介绍
Kubernetes官方从2016年8月份开始,将Kubernetes资源操作相关的核心源码抽取出来,独立出来一个项目Client-go,作为官方提供的Go client。Kubernetes的部分代码也是基于这个client实现的,所以对这个client的质量、性能等方面还是非常有信心的。
Allen.Wu
2019/12/12
4.3K0
相关推荐
《一起读 kubernetes 源码》揭秘 k8s 关键机制 informer
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档