带你读《云原生应用开发 Operator原理与实践》第一章引言1.2Operator 介绍(五)

(4)  修改 Controller逻辑

在 Controller中需要通过Reconcile方法完成 Deployment和 Service 部署,并最终达到期望的状态。

Controller中的代码见代码清单 1-11,我们需要在其中加入业务逻辑。

// +kubebuilder:rbac:groups=webapp.demo.welcome.domain,resources=welcomes,ver-bs=get;list;watch;create;update;patch;delete

//+kubebuilder:rbac:groups=webapp.demo.welcome.domain,resources=welcomes/status,verbs=get;update;patch

 

//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=list;watch;get;patch;create;update

//+kubebuilder:rbac:groups=core,resources=services,verbs=list;watch;get;patch;create;update

func(r*WelcomeReconciler)Reconcile(reqctrl.Request)(ctrl.Result,error){

ctx:=context.Background()

log:=r.Log.WithValues("welcome",req.NamespacedName)log.Info("reconcilingwelcome")

 

此处有两组+”标识,第一组用于Operator更新Welcome资源对象,第二组用于创Deployment和 Service。接下来完成 Welcome类型控制器的部分代码的实现(见代码清单1-12)。


deployment,err:=r.createWelcomeDeployment(welcome)iferr!=nil{

returnctrl.Result{},err

}

log.Info("createdeploymentsuccess!")

 

svc,err:=r.createService(welcome)iferr!=nil{

returnctrl.Result{},err

}

log.Info("createservicesuccess!")

applyOpts:=[]client.PatchOption{client.ForceOwnership,client.

FieldOwner("welcome_controller")}

err=r.Patch(ctx,&deployment,client.Apply,applyOpts...)


iferr!=nil{

returnctrl.Result{},err

}

 

err=r.Patch(ctx,&svc,client.Apply,applyOpts...)iferr!=nil{

returnctrl.Result{},err

}

在控制器部分需要完成 Deployment和 Service 的创建,并完成两者的关联,在上述代码中,我们分别通过调用createWelcomeDeployment和 createService方法完成对象的创建,接下来我们完成上述方法的具体实现(见代码清单1-13)。

func(r*WelcomeReconciler)createWelcomeDeployment(welcomewebappv1.Welcome)(appsv1.Deployment,error){

defOne:=int32(1)

name:=welcome.Spec.Nameifname==""{

name="world"

}

depl:=appsv1.Deployment{

TypeMeta:metav1.TypeMeta{APIVersion:appsv1.SchemeGroupVersion.

String(),Kind:"Deployment"},

ObjectMeta:metav1.ObjectMeta{Name:welcome.Name,Namespace:welcome.Namespace,

},

Spec:appsv1.DeploymentSpec{Replicas:&defOne,

Selector:&metav1.LabelSelector{

MatchLabels:map[string]string{"welcome":welcome.Name},

},

Template:corev1.PodTemplateSpec{ObjectMeta:metav1.ObjectMeta{

Labels:map[string]string{"welcome":welcome.Name},

},

Spec:corev1.PodSpec{

Containers:[]corev1.Container{

{

Name:"welcome",

Env:[]corev1.EnvVar{

 

{Name:"NAME",Value:name},

},

 

Protocol:"TCP"},


Ports:[]corev1.ContainerPort{

{ContainerPort:8080,Name:"http",


},

Image:"sdfcdwefe/operatordemo:v1",Resources:corev1.ResourceRequirements{

Requests:corev1.ResourceList{corev1.ResourceCPU:   *resource.


NewMilliQuantity(100, resource.DecimalSI),NewMilliQuantity(100000,resource.BinarySI),


corev1.ResourceMemory:*resource.


在上述代码中,我们在 Deployment使用了之前制作的 Docker镜像,将 Types中获得的 NAME字段作为环境变量传入镜像中,在镜像执行 main函数时,即可获得 NAME字段并修改 index文件,在文件中插入 NAME,并默认开启 8080监听端口,用户通过Web访问时即可获得最终的期望值。

接下来,我们完成Service部分代码的实现(见代码清单1-14


func(r*WelcomeReconciler)createService(welcomewebappv1.Welcome)(corev1.Service,error){

svc:=corev1.Service{

TypeMeta:metav1.TypeMeta{APIVersion:corev1.SchemeGroupVersion.

String(),Kind:"Service"},

ObjectMeta:metav1.ObjectMeta{Name:welcome.Name,Namespace:welcome.Namespace,

},

Spec:corev1.ServiceSpec{

Ports:[]corev1.ServicePort{

{Name:"http",Port:8080,Protocol:"TCP",TargetPort:

intstr.FromString("http")},

},

Selector:map[string]string{"welcome":welcome.Name},Type:        corev1.ServiceTypeLoadBalancer,

},

}

 

在本例中,我们创建了 LoadBalancer类型的 Service。通过kubectlgetsvc命令可以获取 URL地址,也可以访问 Web应用。

上一篇:带你读《云原生应用开发 Operator原理与实践》第一章引言1.2Operator 介绍(二)


下一篇:带你读《云原生应用开发 Operator原理与实践》第一章引言1.1云原生介绍(五)