Friday, April 26, 2024
HomeKubernetesKubernetes Custom Resource Definition (CRDs)

Kubernetes Custom Resource Definition (CRDs)

In the IT world, we mayn’t get always what we are want, especially with opensource, as there will be some feature still missing. If it is enterprise application or in-house, we have some option to get the feature enabled by request. With opensource, we should customize what we are looking for (if the tool/software supports). Like that even in Kubernetes, though it gives wide range of solutions, still there will be some custom change required. For that Kubernetes has enabled Custom Resource Definition from version 1.7, this enables user to create their own/custom objects to the Kubernetes cluster and define the kind just like pod, deployment, etc.

In this post, lets discuss about custom resource definition (CRD), what CRDs are, how to use and create it.

What is a Custom Resource Definition (CRD)

As we mentioned above in the Kubernetes API, a resource is an endpoint that stores a collection of API objects of a certain kind. The standard Kubernetes distribution comes with lot of inbuilt API objects/resources. For example, the built-in pods’ resource contains a collection of Pod objects. CRD comes when we want to introduce our own object into the Kubernetes cluster to fulfil our custom requirements. Once we create a CRD in Kubernetes we can use it like any other native Kubernetes object thus leveraging all the features of Kubernetes like its CLI, security, API services, RBAC etc.

The custom resource created is also stored in the etcd cluster with proper replication and lifecycle management. This is a powerful way to extend Kubernetes capabilities beyond the default installation. Also, it allows us to extend Kubernetes capabilities by adding any kind of API object useful for our application. This is a powerful way to extend Kubernetes capabilities beyond the default installation.

How to create a CRD

The manifest below shows an example CRD crd.yaml, You can modify it based on your need or understanding.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: foxcrds.foxutech.com
spec:
  group: foxutech.com
  names:
    kind: foxcrds
    listKind: foxcrdslist
    plural: foxcrds
    singular: foxcrd
  scope: Namespaced
  versions:
  - name: v1
    schema:
      openAPIV3Schema:
        description: foxcrd is the foxutech custom resource definition
        type: object
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
              of an object. Servers should convert recognized schemas to the latest
              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
              object represents. Servers may infer this from the endpoint the client
              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: foxcrdsSpoc is the spec for a foxcrds resource
            type: object
            properties:
              title:
                type: string
              author:
                type: string
          status:
            description: foxcrdsStatus is the status for a foxcrds resource
            type: object
            properties:
              publishedAt:
                type: string
    served: true
    storage: true
    subresources:
      status: {}
status:
  acceptedNames:
    kind: ""
    plural: ""
  conditions: []
  storedVersions: []

Let’s explain what the CRD above will create:

  • The first two lines defines what the apiversion is and we are saying we want to create a custom resource definition.
  • The metadata field helps us define what the name of the resource is. In our case foxcrds (plural).
  • Spec group help us define what the group name will be.
  • Spec version helps us define the version. In our case we are versioning it as v1.
  • As you can see, we can define a version of our CRD and only one version can be a storage version at a time, so keep that in mind. We then made sure that this CRD is a namespaced and not cluster wide. This allows us to create the CRD for either just a specific namespace or for the whole cluster.
  • Next, we defined what the singular and plural name of our CRD will be.
  • Lastly, we defined the kind name and the short name. We can then create it with “kubectl create -f crd.yaml”. The new namespaced RESTful API endpoint for our CRD will be found at /apis/stable.example.com/v1/namespaces/*/foxcrds/

You can check the api-resources using following command,

# kubectl api-resources --api-group=foxutech.com
# kubectl explain foxcrd

Well, now the CRD is ready, to use, the CRD above, we need to create a manifest using the kind we created with the CRD.

# kubectl apply -f - <<EOF
apiVersion: foxutech.com/v1
kind: foxcrd
metadata:
  name: foxcheck
spec:
  title: Yet another post about kubernetes 
  author: Motoskia
EOF
foxcrd.foxutech.com/foxcheck created

As you can see, we are using the kind we defined in our CRD, then we defined the fields we want our kind object to have.

To see what is going on we can run “kubectl get foxcrds”, we can see detailed info on what we just created.

How to delete a CRD

To delete the CRD and resources we created, simply run kubectl delete just like with any other resources. It is important to know that the above CRD is just data which can be stored and retrieved therefore, it doesn’t give us a fully declarative API. The way to make this resource fully declarative is to add a custom controller, whose job is to make sure that the current state and the desired state are always in sync. An example is something like a replication controller.

Now that Kubernetes knows about the concept and structure of a foxcrd, it will let me create multiple foxcrd objects.

But, I’m a cluster-admin. I need to allow regular (non-admin) users to be able to create and delete foxcrd objects. Let’s see how we can do that.

Allowing regular users to create CRD

Once you’ve created a CRD, it’s generally available in the Kubernetes API, cluster-wide, although you can limit exactly who can create these objects.

You can create a new ClusterRole and grant the permissions to it:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: foxcrd-admin
rules:
  - apiGroups: ["foxutech.com"]
    resources: ["foxcrds"]
    verbs: ["get", "list", "watch", "create",
            "update", "patch", "delete", "deletecollection"]

And for the view permission:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: foxcrd-view
rules:
  - apiGroups: ["foxutech.com"]
    resources: ["foxcrds"]
    verbs: ["get", "list", "watch"]

Well, hope this give some idea about custom resource definition (CRD), you can expand this with multiple use cases. We will be seeing more about this in coming posts.

You can follow us on social media, to get some short knowledges regularly.

RELATED ARTICLES
- Advertisment -

Most Popular

Recent Comments