栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

自定义生成operator框架

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

自定义生成operator框架

在实现的开发过程中,开发人员需要借助 Operator 开发框架来扩展 Kubernetes API。operator framework 可以提供 webhook 和 controller 的框架,它的主要意义在于帮助开发者屏蔽了一些通用的底层细节,不需要开发者再去实现消息通知触发、失败重新入队等,只需关注被管理应用的运维逻辑实现即可。主流的 operator framework 主要有两个:kubebuilder 和 operator-sdk。

主要步骤是首先定义好 Group、version 以及 kind,然后使用 operator framework 命令即可生成所需的 operator 框架,CRD结构等,具体用法这里不详细叙述。

自定义controller实现
// Define some nested types to simplify the codebase
type Controller interface {
    Run(int, <-chan struct{})
}
type InformerFactory interface {
    Start(stopCh <-chan struct{})
    WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
}

// 初始化两种 CRD 的 controller
// Initialize all controllers
controllers := []Controller{
    // add example1 controller
    example.NewController(deps),
}

informer初始化

// Start informer factories after all controllers are initialized.
informerFactories := []InformerFactory{
    informerFactory,
}
for _, f := range informerFactories {
    f.Start(ctx.Done())
    for v, synced := range f.WaitForCacheSync(wait.NeverStop) {
        if !synced {
            klog.Fatalf("error syncing informer for %v", v)
        }
    }
}
klog.Info("cache of informer factories sync successfully")

// Start syncLoop for all controllers
for _, controller := range controllers {
    c := controller
    go wait.Forever(func() { c.Run(cliCfg.Workers, ctx.Done()) }, cliCfg.WaitDuration)
}

只需要实现 Run 方法

// Controller controls backup.
type Controller struct {
	// control returns an interface capable of syncing a backup.
	// Abstracted out for testing.
	control ControlInterface
	// backups that need to be synced.
	queue workqueue.RateLimitingInterface
}

// NewController creates a backup controller.
func NewController(control ControlInterface) *Controller {
	c := &Controller{
		control: control,
		queue:   workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "backup"),
	}

	informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: c.update,
		UpdateFunc: func(old, cur interface{}) {
			c.update(cur)
		},
		DeleteFunc: c.update,
	})

	return c
}

// Run runs the controller.
func (c *Controller) Run(workers int, stopCh <-chan struct{}) {
	defer utilruntime.HandleCrash()
	defer c.queue.ShutDown()

	klog.Info("Starting controller")
	defer klog.Info("Shutting down controller")

	for i := 0; i < workers; i++ {
		go wait.Until(c.worker, time.Second, stopCh)
	}

	<-stopCh
}

// worker runs a worker goroutine that invokes processNextWorkItem until the the controller's queue is closed
func (c *Controller) worker() {
	for c.processNextWorkItem() {
	}
}

// processNextWorkItem dequeues items, processes them, and marks them done. It enforces that the syncHandler is never
// invoked concurrently with the same key.
func (c *Controller) processNextWorkItem() bool {
	key, quit := c.queue.Get()
	if quit {
		return false
	}
	defer c.queue.Done(key)
	if err := c.sync(key.(string)); err != nil {
		if perrors.Find(err, util.IsRequeueError) != nil {		
			c.queue.AddRateLimited(key)
		} else if perrors.Find(err, util.IsIgnoreError) != nil {
			klog.V(4).Infof("CR: %v, ignore err: %v", key.(string), err)
		} else {
			utilruntime.HandleError(fmt.Errorf("CR: %v, sync failed, err: %v, requeuing", key.(string), err))
			c.queue.AddRateLimited(key)
		}
	} else {
		c.queue.Forget(key)
	}
	return true
}


// enqueueBackup enqueues the given backup in the work queue.
func (c *Controller) update(obj interface{}) {
// TODO: Determine whether to enter the queue
}
client 生成工具

生成完 operator 框架之后,目录结构一般如下(不同工具生成的文件目录可能有细微区别):

pis/
`-- bcrds
    |-- group.go
    `-- v1alpha1
        |-- doc.go
        |-- register.go
        |-- example_types.go
        `-- zz_generated.deepcopy.go

其中 types.go 为具体的 CRD struct 结构。

对 CRD 的增删改查需要通过 client 方式来实现,这里用 github.com/openshift-evangelists/crd-code-generation/vendor/k8s.io/code-generator 工具生成 client。

# `--output-base $SCRIPT_ROOT` will output generated code to current dir
bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" 
    operator/pkg/client 
    operator/pkg/apis 
    bcrds:v1alpha1 
    --output-base $SCRIPT_ROOT 
    --go-header-file ./hack/boilerplate/boilerplate.generatego.txt

boilerplate.generatego.txt 为 client 模板文件,生成的文件均会在 go 文件前加上 TXT 中的模板内容。

 目录结构

pkg
  |--pis
    `-- bcrds
        |-- group.go
        `-- v1alpha1  
            |-- doc.go
            |-- register.go
            |-- example_types.go
            `-- zz_generated.deepcopy.go
  |--client
        |--clientset
        |--informers
        |--listers

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/990481.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号