Kubernetes Custom Resource and Custom Resource Definition (CRD)

Kubernetes Custom Resource and Custom Resource Definition (CRD)

Before knowing the custom resource definition, let's know what is resource definition

To start with, what is resource in the context of Kubernetes?

When we talk about Kubernetes, few of the resources Kubernetes provides us out of the box.

Core Resources:


  • Pods
  • Services
  • Deployments
  • ReplicaSets
  • StatefulSets
  • DaemonSets
  • Ingresses
  • ConfigMaps
  • Secrets
  • PersistentVolumes
  • PersistentVolumeClaims


Networking:


  • NetworkPolicies
  • Services


Storage:


  • PersistentVolumes
  • PersistentVolumeClaims
  • StorageClasses


Authorization and Access Control:


  • Roles
  • RoleBindings
  • ServiceAccounts


Cluster Management:


  • Namespaces
  • LimitRanges
  • ResourceQuotas


Custom Resources:


  • Any custom resource defined using a CRD



What is Custom resource definition (CRD) and why do we need that?

Since, we know that Kubernetes has already many resources, so its easy to relate its purpose of having a custom resource as well.

- Kubernetes has many resources like pod, service, deployments etc, these all resource gets created based on the objects that we write in a YAML file

#example of an object to create a resource ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: user_authentication
  namespace: devNameSpace
data:
  mapUsers:
    - userarn: <developer-user_arn>
      username: developer-user        

- It follows certain structure or fields ( ex: kind: deployment, metadata -name etc)

Each Kubernetes resources has some specific job, one creates deployments, one connects the pod with outside world using another resource like service and its mode of Load Balancer etc.

- Now, why do we need to be so careful while we write these yaml files and ensure it should maintain the proper structure

- For an example - in the above yaml file we cant write

kind: ConfigMap as kindas: Configmaps

But, why?

- because whatever we write in the YAML file and when we try to apply them through kubectl command, Kubernetes has a built-in mechanism(API Server -> Admission Controller) to validate and enforce the schema for each resource type.

- So, whatever we write in the YAML file, it gets compared against the corresponding Resource Definition.

- Which ensures the fields, types, and constraints for that resource matches with the schema.

- If the resource adheres to the schema, it's allowed to be created in the cluster.


Is there a way, we can see, how these resource definitions look like?

- Kubernetes doesn't have a specific UI or command-line tool to directly view the Resource definitions for built-in resources,

But, there are some ways to see the fields that each resources has which defines their definition.

1. From the API reference of each resources, we can get to know about each fields (Here is an example of Resource definition for Deployment resource)- https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#deployment-v1-apps

2. Through command-line

kubectl explain deployments         


Now, it's the time to get into Custom Resource and definitions.

So, Kubernetes has many existing resources


  • but to extend the capability of K8S which needs some customization which the existing resource does not provide, we need some custom resources to be created and to make sure these custom resource maintains a structure, we need to create custom resource definitions.
  • Now, as we understand how the resource objects are created and gets validated behind the scene.


- Some application deployed in K8S cluster may need some additional support or additional need which is not natively available with K8S resource like pods, deployment etc, in that case, we need to develop the custom resource.

- Every Kubernetes resource needs to follow some guidelines that is defined for that resource and that is defined by that resource definition,

- for native K8S resource, these definitions are already exist in the K8s cluster.

- But, when we develop a new resource, that also need to follow some guidelines and that is defined in custom definition.


Lets take a scenerio where there is a need to have a resource which monitors the databases


In this case, developers or infra team need to write their own custom resources

kind: databaseMonitor

- But, we cant allow anyone to write the YAML object of that custom resource databaseMonitor, for that we need to define its accaptable fields.

- ex: anyone who is writing the object(yaml file) for that resource need to follow these schema,

Note : it's just an example, there is no Resource Definition like this.


  • Create your own custom resource Definition (CRD):

#customresourcedefinition/databasemonitor-crd.yaml

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: databasemonitors.mygroup.example.com
spec:
  group: mygroup.example.com
  names:
    plural: databasemonitors
    singular: databasemonitor
  scope: Namespaced
  version: v1
  subresources:
    status: {}
  validation:
    openAPIV3Schema:
      type: object
      properties:
        spec:
          type: object
          properties:
            databaseType:
              type: string
            databaseName:
              type: string
            monitorInterval:
              type: integer
        status:
          type: object
          properties:
            status:
              type: string         


  • Once CRDs are Created, you need to apply that into the Kubernetes cluster


kubectl apply -f databasemonitor-crd.yaml

## Note: Ensuring the user has the proper role setup and a role binding is done with proper permissions and verbs        


  • Now, to create a resource, one can create an object like this


apiVersion: mygroup.example.com/v1
kind: DatabaseMonitor
metadata:
  name: my-database-monitor
spec:
  databaseType: mysql
  databaseName: my-database
  monitorInterval: 60        

- But, If someone creates the object and makes it different than what is mentioned in the schema of the resource, the resource creation would not be done.


- Here, the schema of the resource is called as custom resource definition for that resource databaseMonitor

Who validates the resources and its definition?

- K8s control plane has a service called API Server which examines the resource object and if it matches with its definition schema, it allows the API request made by client to be applied

Please note that the Custom resources often require custom controllers to handle their logic and reconcile the desired state with the actual state.

Custom Controller


  • Like K8S COntroller, which always keeps an eye(watch) on the resource thrugh K8S API server and takes any action to ensure the desired state matches with the current state,
  • the built in controller would not be able to monitor the custom resource, so a custom controller is needed to watch that.
  • responsibilities of a custom controller is to reconcile the desired state (from CRD) with the actual state (of the cluster).



Some example & steps of developing the custom controllers


  • To develop a custom controller, we can use Go lang or Python programming language
  • since K8S is natively developed using Go, so most of the DevOps eng prefer to use Go Lang.
  • To communicate with K8S API, we have to communicate with GoClient first,
  • To see any changes in the custom resources, we have to create our own custom watchers as well,
  • There are frameworks like “Kubernetes controller runtime” which is a set of libraries to build kubernetes controllers.
  • So, when the watcher finds any change like CRUD of resource, it communicates with GoClient(reflector - a component of GoClient)
  • Once we develop a custom controller, to install that controller into K8S and mannage its lifecycle, we can use K8S operators. https://operatorhub.io/



How to install Custom controller on k8s Cluster


  • To install the custom controller on K8S cluster - minikube for local laptop or EKS for AWS etc
  • First install the OLM on the cluster [`Operator lifecycle manager`]
  • Now install the operators : Example of installing ArgoCD operator into K8S cluster using operatorshub.io
  • Once the operator is installed, we have to do the installation of controller
  • Follow this for ArgoCD - https://argocd-operator.readthedocs.io/en/latest/usage/basics/

Ahmed Ayman

Senior Cloud DevOps Engineer | DevOps | RHCSA | RHCE | AWS | CKA | Terraform | Ansible | Docker | CI/CD

3 个月

A great insightful article simplyfying complex concepts, keep up the good work ????????????

Haytham Awadallah

Senior DevOps Engineer at _VOIS | CKA | AWS | RHCSA | RHCE | Terraform | Docker | Jenkins | ArgoCD | Ansible | Puppet | Prometheus | Python

3 个月

3ash ya Rana ????

要查看或添加评论,请登录

社区洞察

其他会员也浏览了