Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the kuberenetes CRD development method?

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

Today, the editor will share with you the relevant knowledge of what the kuberenetes CRD development method is. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.

Extending the two most common things you need to master in kubernetes: custom resources CRD and adminsion webhook.

Kubernetes allows users to customize their own resource objects, just like deployment statefulset, which is widely used. For example, prometheus opterator customizes Prometheus objects, and when a custom controller listens to kubectl create Prometheus, it creates a Pod to form a pormetheus cluster. Rook and so on.

I need to schedule virtual machines with kubernetes, so here I customize a VirtualMachine type

Kubebuilder

Kubebuilder can save us a lot of work and make it extremely easy to develop CRD and adminsion webhook.

Installation

Install through source code:

Git clone https://github.com/kubernetes-sigs/kubebuildercd kubebuildermake buildcp bin/kubebuilder $GOPATH/bin

Or download binary:

Os=$ (go env GOOS) arch=$ (go env GOARCH) # download kubebuilder and extract it to tmpcurl-sL https://go.kubebuilder.io/dl/2.0.0-beta.0/${os}/${arch} | tar-xz-C / tmp/# move to a long-term location and put it on your path# (you'll need to set the KUBEBUILDER_ASSETS env var if you put it somewhere else) sudo mv / tmp/kubebuilder_2.0.0-beta.0_$ {os} _ ${arch} / usr/local/kubebuilderexport PATH=$PATH:/usr/local/kubebuilder/bin

You also need to install the kustomize, which is an artifact that renders yaml and makes helm tremble.

Go install sigs.k8s.io/kustomize/v3/cmd/kustomize usage

Note that you need to have a kubernetes cluster first, and install you in one step

Create CRD

Kubebuilder init-domain sealyun.com-license apache2-owner "fanux" kubebuilder create api-group infra-version v1-kind VirtulMachine

Install CRD and start controller

Make install # install CRDmake run # start controller

Then we can see the CRD we created.

# kubectl get crdNAME AGEvirtulmachines.infra.sealyun.com 52m

To create a virtual machine:

# kubectl apply-f config/samples/# kubectl get virtulmachines.infra.sealyun.com NAME AGEvirtulmachine-sample 49m

Take a look at the yaml file:

# cat config/samples/infra_v1_virtulmachine.yaml apiVersion: infra.sealyun.com/v1kind: VirtulMachinemetadata: name: virtulmachine-samplespec: # Add fields here foo: bar

Here we just put the yaml in the etcd, and we didn't do anything when we heard about the creation event.

Deploy controller to the cluster

Make docker-build docker-push IMG=fanux/infra-controllermake deploy

I am connected to the remote kubenetes, make docker-build when the test can not get through, there is no etcd bin file, so turn off test first.

Modify Makefile:

# docker-build: testdocker-build:

You may not be able to pull down the image of gcr.io/distroless/static:latest in Dockerfile. Just change it at will. I changed it to golang:1.12.7.

It is also possible that some code can not be pulled down when building. Enable go mod vendor to package the dependencies.

Go mod vendor if you can't pull down some local code, you can use proxy:

Export GOPROXY= https://goproxy.io

Change the Dockerfile and comment out the download:

After modification:

# Build the manager binaryFROM golang:1.12.7 as builderWORKDIR / go/src/github.com/fanux/sealvm# Copy the Go Modules manifestsCOPY. . # BuildRUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build-o manager main.go# Use distroless as minimal base image to package the manager binary# Refer to https://github.com/GoogleContainerTools/distroless for more details# FROM gcr.io/distroless/static:latestFROM golang:1.12.7WORKDIR / COPY-- from=builder / go/src/github.com/fanux/sealvm/manager .EntRYPoint ["/ manager"]

Make deploy Times error: Error: json: cannot unmarshal string into Go struct field Kustomization.patches of type types.Patch

Change the patches: in config/default/kustomization.yaml to patchesStrategicMerge:

The command kustomize build config/default renders the yaml file of controller. You can try it.

Look at your controller already running:

Kubectl get deploy-n sealvm-systemNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEsealvm-controller-manager 1 1 10 3mkubectl get svc-n sealvm-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT (S) AGEsealvm-controller-manager-metrics-service ClusterIP 10.98 .71.199 8443/TCP 4m development adds object data parameters

Take a look at the yaml file under config/samples:

ApiVersion: infra.sealyun.com/v1kind: VirtulMachinemetadata: name: virtulmachine-samplespec: # Add fields here foo: bar

There is foo:bar in the parameters here, so let's add a virtual CPU, memory information:

Just api/v1/virtulmachine_types.go directly.

/ / VirtulMachineSpec defines the desired state of VirtulMachine// add information type VirtulMachineSpec struct {/ / INSERT ADDITIONAL SPEC FIELDS-desired state of cluster / / Important: Run "make" to regenerate code after modifying this file CPU string `json: "cpu" `/ / this is my added Memory string `json: "memory"`} / / VirtulMachineStatus defines the observed state of VirtulMachine// add status information here, such as virtual machine startup status Type VirtulMachineStatus struct {/ / INSERT ADDITIONAL STATUS FIELD-define observed state of cluster / / Important: Run "make" to regenerate code after modifying this file}

Then make:

Make & & make install & & make run

If you render the yaml of controller at this time, you will find that CPU and memory information are already in the CRD:

Kustomize build config/default

Properties: cpu: description: 'INSERT ADDITIONAL SPEC FIELDS-desired state of cluster Important: Run "make" to regenerate code after modifying this file' type: string memory: type: string

Modify the yaml:

ApiVersion: infra.sealyun.com/v1kind: VirtulMachinemetadata: name: virtulmachine-samplespec: cpu: "1" memory: "2G" # kubectl apply-f config/samples virtulmachine.infra.sealyun.com "virtulmachine-sample" configured# kubectl get virtulmachines.infra.sealyun.com virtulmachine-sample-o yaml apiVersion: infra.sealyun.com/v1kind: VirtulMachinemetadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion": "infra.sealyun.com/v1", "kind": "VirtulMachine" "metadata": {"annotations": {}, "name": "virtulmachine-sample", "namespace": "default"}, "spec": {"cpu": "1" "memory": "2G"} creationTimestamp: 2019-07-26T08:47:34Z generation: 2 name: virtulmachine-sample namespace: default resourceVersion: "14811698" selfLink: / apis/infra.sealyun.com/v1/namespaces/default/virtulmachines/virtulmachine-sample uid: 030e2b9a-af82-11e9-b63e-5254bc16e436spec: # the new CRD has taken effect cpu: "1" memory: 2G

Status is the same, so I won't repeat it. For example, I add a Create to the status to indicate that controller is going to create a virtual machine (mainly some control-level logic), and change the state to Running after the creation.

The only interface that Reconcile needs to implement

Controller encapsulates rotation training and event monitoring in this interface. You don't need to care about how the incident is monitored.

Get virtual machine information func (r * VirtulMachineReconciler) Reconcile (req ctrl.Request) (ctrl.Result, error) {ctx = context.Background () _ = r.Log.WithValues ("virtulmachine", req.NamespacedName) vm: = & v1.VirtulMachine {} if err: = r.Get (ctx, req.NamespacedName, vm) Err! = nil {# get VM information log.Error (err, "unable to fetch vm")} else {fmt.Println (vm.Spec.CPU, vm.Spec.Memory) # print CPU memory information} return ctrl.Result {}, nil}

Make & & make install & & make run this time to create a virtual machine kubectl apply-f config/samples, the log will output CPU memory. The List interface is the same, so I won't repeat it.

R.List (ctx, & vms, client.InNamespace (req.Namespace), client.MatchingField (vmkey, req.Name)) update status

Add a status field to the status structure:

Type VirtulMachineStatus struct {Status string `json: "status" `}

Update the status in controller:

Vm.Status.Status = "Running" if err: = r.Status (). Update (ctx, vm); err! = nil {log.Error (err, "unable to update vm status")}

If the error: the server could not find the requested resource occurs, you need to add a comment / / + kubebuilder:subresource:status to the CRD structure:

/ / + kubebuilder:subresource:status// + kubebuilder:object:root=truetype VirtulMachine struct {metav1.TypeMeta `json: ", inline" `metav1.ObjectMeta `json: "metadata,omitempty" `Spec VirtulMachineSpec `json: "spec,omitempty" `Status VirtulMachineStatus `json: "status,omitempty" `}

That's good.

After the compilation starts, go to apply and find that the status has changed to running:

# kubectl get virtulmachines.infra.sealyun.com virtulmachine-sample-o yaml...status: status: Running Delete time.Sleep (time.Second * 10) if err: = r.Delete (ctx, vm); err! = nil {log.Error (err, "unable to delete vm", "vm", vm)}

After 10 seconds, we will be less than GET.

Delete Collector Finalizers

If you delete etcd data directly when you don't use Finalizers,kubectl delete, controller won't get it when you want to get CRD again:

ERRO [0029] VirtulMachine.infra.sealyun.com "virtulmachine-sample" not foundunable to fetch vm source= "virtulmachine_controller.go:48"

So we need to add Finalizer to CRD when we create it:

Vm.ObjectMeta.Finalizers = append (vm.ObjectMeta.Finalizers, "virtulmachine.infra.sealyun.com")

Then, when deleting, CRD will only be stamped with a deletion timestamp for subsequent processing. After that, we will delete the Finalizers:

If DeleteionTimestamp does not exist, if there is no Finalizers, add Finalizers, and update CRD, otherwise, it will be deleted. If Finalizers exists, delete Finalizers and update CRD.

Look at a complete code example:

If cronJob.ObjectMeta.DeletionTimestamp.IsZero () {if! containsString (cronJob.ObjectMeta.Finalizers, myFinalizerName) {cronJob.ObjectMeta.Finalizers = append (cronJob.ObjectMeta.Finalizers, myFinalizerName) if err: = r.Update (context.Background (), cronJob) Err! = nil {return ctrl.Result {}, err} else {if containsString (cronJob.ObjectMeta.Finalizers, myFinalizerName) {if err: = r.deleteExternalResources (cronJob) Err! = nil {return ctrl.Result {}, err} cronJob.ObjectMeta.Finalizers = removeString (cronJob.ObjectMeta.Finalizers, myFinalizerName) if err: = r.Update (context.Background (), cronJob); err! = nil {return ctrl.Result {}, err}} webhook

There are three kinds of webhook,admission webhook in kuberentes, authorization webhook and CRD conversion webhook.

Here, for example, we want to set some default values for CRD, or if the user creates it with less parameters, then we have to disable creation and so on.

Using webhook is also very simple, as long as you implement Defaulter and Validator interfaces for the defined structures.

Other interfaces

The Reconcile structure aggregates the Client interface, so all the methods of client can be called directly, most of which are related to CRD object.

Type Client interface {Reader Writer StatusClient} / / Reader knows how to read and list Kubernetes objects.type Reader interface {/ / Get retrieves an obj for the given object key from the Kubernetes Cluster. / / obj must be a struct pointer so that obj can be updated with the response / / returned by the Server. Get (ctx context.Context, key ObjectKey, obj runtime.Object) error / / List retrieves list of objects for a given namespace and list options. On a / / successful call, Items field in the list will be populated with the / / result returned from the server. List (ctx context.Context, list runtime.Object, opts... ListOptionFunc) error} / / Writer knows how to create, delete, and update Kubernetes objects.type Writer interface {/ / Create saves the object obj in the Kubernetes cluster. Create (ctx context.Context, obj runtime.Object, opts... CreateOptionFunc) error / / Delete deletes the given obj from Kubernetes cluster. Delete (ctx context.Context, obj runtime.Object, opts... DeleteOptionFunc) error / / Update updates the given obj in the Kubernetes cluster. Obj must be a / / struct pointer so that obj can be updated with the content returned by the Server. Update (ctx context.Context, obj runtime.Object, opts... UpdateOptionFunc) error / / Patch patches the given obj in the Kubernetes cluster. Obj must be a / / struct pointer so that obj can be updated with the content returned by the Server. Patch (ctx context.Context, obj runtime.Object, patch Patch, opts... PatchOptionFunc) error} / / StatusClient knows how to create a client which can update status subresource// for kubernetes objects.type StatusClient interface {Status () StatusWriter} above is all the content of this article "what is the kuberenetes CRD Development method?" Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report