Author: Shen Yajun

I am a member of the R&D team of Ekoson, responsible for the back-end development of the company’s DMP products. My hobbies are so wide that I can’t finish them for three days and three nights. I keep a low profile…

Source of this article: original contribution

* Produced by the open source community of ecoson, the original content is not allowed to be used without authorization, please contact the small edition and indicate the source.


K8s operator is introduced

The K8S Operator is an application-specific controller that extends the functions of the Kubernetes API to create, configure, and manage instances of complex applications on behalf of K8S users. It is built on basic K8S resource and controller concepts, but covers knowledge of a specific domain or application. The most common ones used to automate the application lifecycle they manage are etcd-operator, Prometheus -operator, etc. Here is a list of some of the most common functions performed by k8s operator:

  • Deployment specifies the configuration and number of applications
  • Scaling the volume of the application
  • Initiate upgrade, automatic backup, and failover
  • Perform any other tasks for managing the application that can be rendered as code

How Operators Work

The K8S Operator is a custom K8S controller that manages applications and their components using a custom resource (CR), which is an API extension mechanism in K8S. A custom resource definition (CRD) declares CR and lists all the configurations available to the Operator user

When an operator is deployed to a K8S cluster, it listens for events of a particular resource type via the API Server connected to the master node and takes action based on the configuration provided by the user in the CR and embedded in the operator processing logic. Perform a loop to ensure that the current state of the resource matches the ideal state

Write a simple operator

The operator SDK is a tool developed and maintained by CoreOS for quickly creating operator applications. We can use this tool to help us quickly build operator applications.

  • Kudo (Kubernetes Universal Declative Operator)
  • KubeBuilder, a project that Kubernetes SIG is maintaining
  • Metacontroller, which can be used in conjunction with Webhooks to achieve its own functionality

The next step is to build a simple operator project using the operator-SDK

Development Environment:

Docker 20.10.5 Operator-SDK 1.9.0 Golang 1.16.3 Kubernetes 1.19 MacOS 11.4

1. Create nginx-operator project using operator-SDK CLI

mkdir -p $HOME/nginx-operator && cd $HOME/nginx-operator
operator-sdk init --domain example.com --repo github.com/example/nginx-operator

2. Create a new CRD API that specifies the group as Proxy and the NGINX version as V1alpha1

operator-sdk create api --group proxy --version v1alpha1 --kind Nginx --resource --controller

The API /v1alpha1/nginx_types.go and the Controllers /nginx_controller.go files generated by this command are required to implement the CR configuration and controller processing logic respectively

3. Define NGINX resource type CR and generate CRD

Modify the NginxSpec and NginxStatus in the file API /v1alpha1/nginx_types.go as follows

// NginxSpec defines the desired state of Nginx
type NginxSpec struct {
    Count int32 `json:"count"`
}

// NginxStatus defines the observed state of Nginx
type NginxStatus struct {
    // Nodes are the names of the nginx pods
    Nodes []string `json:"nodes"`
}

Execute the following command to generate the code associated with the CR resource each time you modify the definition of CR

make generate

Execute the following command generates the CRD definition file nginx-operator/config/crd/bases/proxy.example.com _nginxes. Yaml

make manifests

4. Implementation of controller processing logic

You need to implement the following logic in Controllers/NGINX_CONTROLLER.GO, see NGINX_CONTROLLER.GO

Implement the setupWithManager method to set the resource object to listen on. The following code specifies that the primary listener is NGINX and the secondary listener is Deployment:

func (r *NginxReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&proxyv1alpha1.Nginx{}).
        Owns(&appsv1.Deployment{}).
        Complete(r)
}

The Reconcile method is used to maintain the desired state of the listening object in the former K8S environment. The Reconcile method is called whenever a new event is triggered by the listening resource object

func (r *NginxReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    log := ctrllog.FromContext(ctx)

    return ctrl.Result{}, nil
}

5. The deployment of the operator

1. Compile and deploy the operator image to modify the Makefile

-IMG ? = controller:latest +IMG ? = $(IMAGE_TAG_BASE):$(VERSION)

Compile and deploy Operators to the K8S cluster

make docker-build
make deploy

2. View the deployment

$ kubectl get deployment -n nginx-operator-system
NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
nginx-operator-controller-manager   1/1     1            1           5m14s

Config /samples/proxy_v1alpha1_nginx.yaml

apiVersion: proxy.example.com/v1alpha1
kind: Nginx
metadata:
  name: nginx-sample
spec:
  count: 3

Run the command kubectl apply-f config/samples/proxy_v1alpha1_nginx.yaml to create CR

Gets the created POD

$ kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
nginx-sample-66b6c48dd5-bcqc8   1/1     Running   0          15m
nginx-sample-66b6c48dd5-thnx6   1/1     Running   0          15m
nginx-sample-66b6c48dd5-xrd9l   1/1     Running   0          15m

4. Check the status of CR

$ kubectl get nginx/nginx-sample -o yaml
apiVersion: proxy.example.com/v1alpha1
kind: Nginx
metadata:
  name: nginx-sample
  namespace: default
  ...
spec:
  count: 3
status:
  nodes:
  - nginx-sample-66b6c48dd5-bcqc8
  - nginx-sample-66b6c48dd5-thnx6
  - nginx-sample-66b6c48dd5-xrd9l

To clean up, execute the following command

kubectl delete -f config/samples/proxy_v1alpha1_nginx.yaml
make undeploy