使用controller-runtime开发简单的controller

7 篇文章 0 订阅
5 篇文章 1 订阅

      kubebuilder和operator-sdk都是在controller-runtime基础上做了一层封装,如果不需要自定义crd资源,只是使用k8s现有的resource做一些自定义的开发,可以直接使用controller-runtime快速开发。这里我们实现一个对namespace打上label就创建对应的service功能。

      首先先初始化一个manager,manager的作用是用来管理controller

    var namespace string
	var metricsAddr string
	var syncPeriod int64
	var enableLeaderElection bool
	//
	flag.StringVar(&namespace, "namespace", "", "Namespace within which CRD controller is running.")
	flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
	flag.Int64Var(&syncPeriod, "sync-period", 0, "Sync every sync-period seconds.")
	flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
		"Enable leader election for controller lk-ns-controller. Enabling this will ensure there is only one active controller lk-ns-controller.")
	flag.Parse()

	ctrl.SetLogger(zap.New(func(o *zap.Options) {
		o.Development = true
	}))

	syncPeriodD := time.Duration(int64(time.Second) * syncPeriod)
	manager,err := ctrl.NewManager(ctrl.GetConfigOrDie(),ctrl.Options{
		Scheme:             scheme,
		MetricsBindAddress: metricsAddr,
		LeaderElection:     enableLeaderElection,
		LeaderElectionID:	"service-controller",
		SyncPeriod:         &syncPeriodD,
		LeaderElectionNamespace: namespace,
		Namespace:          namespace,
	})
	if err != nil {
		log.Error(err, "unable to start service-controller")
		os.Exit(1)
	}

然后创建controller并添加到manager中

err = ctrl.NewControllerManagedBy(manager).For(&v1.Namespace{}).WithEventFilter(&controller.ResourceChangePredicate{}).
		Complete(&controller.NamespaceReconciler{
		Client:manager.GetClient(),
		Log: ctrl.Log.WithName("controllers").WithName("service-controller"),
		Scheme: manager.GetScheme(),
	})
	if err !=nil{
		log.Error(err,"unable to create service-controller")
		os.Exit(1)
	}

注意这里的NamespaceReconciler是自定义的结构体,用来继承Reconciler接口,并实现自定义的业务逻辑。

type NamespaceReconciler struct {
	client.Client
	Log    logr.Logger
	Scheme *runtime.Scheme

}


func (r *NamespaceReconciler) Reconcile(ctx context.Context,req ctrl.Request) (ctrl.Result, error) {
	namespace :=&v1.Namespace{}
	err :=r.Get(ctx,req.NamespacedName,namespace)
	if err!=nil{
		return err
	}

	label :=make(map[string]string)
	label["jvm"]="prometheus"
	jvmService := &v1.Service{
		ObjectMeta: metaV1.ObjectMeta{
			Name:"jvm-prometheus",
			Labels: label,
			Namespace:req.Name,
		},
		Spec:       v1.ServiceSpec{
			Ports: []v1.ServicePort{
				v1.ServicePort{
					Name:        "jvm",
					Protocol:    "TCP",
					Port:        65533,
					TargetPort:  intstr.IntOrString{IntVal:65533},
				},
			},
			Selector: label,
			Type: v1.ServiceTypeClusterIP,
		},
	}
	
    jvmLabel :=make(map[string]string)
	jvmLabel["jvm-enabled"]="true"
    if enabled,exist :=namespace.Labels["jvm-enabled"];exist && enabled=="true"{
        err :=r.Create(ctx,jvmService)
		if err!=nil{
			return err
		}
        fmt.Printf("create service in namespace: %v\n",req.Name)
    }
	
	return ctrl.Result{},nil
}

我们在Reconcile方法中实现自己的业务逻辑,如果namespace存在jvm-enabled=true这个label,就创建对应的service。是不是用法和kubebuilder一模一样。

最后我们启动controller所在的manager

log.Info("starting service-controller")
if err :=manager.Start(ctrl.SetupSignalHandler());err!=nil{
	log.Error(err,"cloud not start manager")
	os.Exit(1)
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值