Kubernetes has cemented itself as the de-facto container orchestration tool. It helps you manage your applications across a cluster of varied infrastructure and machines. With Kubernetes, you can define how your application should work and interact with other applications or the real world. Kubernetes allows you to scale up and down your application based on your needs. You can also roll out updates more efficiently while redirecting some of your traffic to the new version to check if it’s ready to be released. Kubernetes is pluggable, configurable, and extensible. Kubernetes users can extend the K8s feature using their vendor APIs. Kubernetes provides a plethora of features to the users, but what if developers need a custom object or resource based on their specific requirements? This is where CRD (custom resource definition) comes into the conversation. CRD is the latest feature introduced as a part of Kubernetes 1.7 and helps users add their own custom objects to the Kubernetes cluster and use them like any other native K8s object like Deployment and Pod.
What is CRD and why do you need it?
A resource in the Kubernetes API server stores a collection of API objects of a certain type. A custom resource allows users to create their own API objects. Custom resources are defined using the custom resource definition. This way users can extend Kubernetes capabilities beyond their default limits. Once CRD is created, the Kubernetes API server creates a RESTful path to each version specified in the CRD. The path can be accessed by the entire cluster or a specific project based on the scope defined in the CRD file. A custom resource, once defined by CRD, is then stored in the etcd cluster. Kubernetes API server takes care of the resource lifecycle and replication. The custom resources act similar to the native resources and when a project is deleted, all the custom resources and native resources get deleted.
Although custom resources are incredibly useful, they shouldn’t be used everywhere. You should go for config files if you already have a well-documented configuration file or if you prefer the Pod consumes configurations through a file rather than Kubernetes APIs. Config files should also be used when you need to perform rolling updates each time the file is updated. You should rely on custom resources if you need to use Kubernetes client libraries, or CLIs to create and update resources. Custom resources are also ideal if you want to abstract a collection of resources. Other than that, use custom resources if you want to use Kubernetes API fields such as .spec and .metadata or if you want fully declarative APIs.
Let’s take a look at how to create a CRD and consequently creating custom resources.
Creating a custom resource definition
To create a CRD, you need to have Kubernetes 1.7 or above and a kubectl tool installed. The CRD is created using a YAML file that contains all the specs of the CRD object that you need. The YAML file consists of several fields. Some important fields are as follows:
- metadata.name: This is the name of CRD that you’re creating.
- spec.group: The name of the group the CRD object belongs to.
- spec.versions: This field holds the different versions of custom resources that will be created using the CRD in context. Versions can be enabled and disabled using the “served” flag.
- spec.names: This field is used to define how you can describe the custom resources. You can define plural, singular, and short name form that can be used to manage the custom resources through kubectl.
- spec.names.kind: This field defines the “kind” of custom resources that can be created using the CRD. Deployment, CronJob, and CronTab are some of the kinds you can define in the CRD.
- spec.scope: The field defines what the scope of the custom resources will be. It can either be set to “clustered” or “namespaced.” It is, however, set to “namespaced” by default.
After creating the CRD through kubectl, the endpoint URL is generated that can be used to create and manage custom objects. This endpoint might take a couple of seconds to get created. To check if the resource has been created, you can either check the discovery information of your API server or check for “Established” condition to become “true.”
Creating a custom resource
After the custom resource definition is created, you can start creating custom resources based on it. Custom resources can have any number of custom fields. The fields can also contain arbitrary data depending on if it gets validated by the validations you set in the CRD. The custom objects are of the kind defined in the CRD. After saving the custom object YAML, you can create is using a kubectl command. Kubectl can also be used to manage all the objects of a particular “kind.” When you use kubectl, the resource names aren’t case-sensitive. Also, you can access the custom resources using singular, plural, and short name forms depending on what you defined in the CRD.
Deleting a custom resource definition
To delete a CRD in Kubernetes, you can use kubectl delete just like you’ll use it for a native resource. When you delete the CRD, the server uninstalls the RESTful endpoint that was created with the CRD. With the deletion of a CRD, all the custom resources created using it are also deleted and cannot be retrieved. If you start from scratch and make a CRD with the same name as the one you deleted earlier, you won’t be able to retrieve all the custom resources you previously created.
How to get a fully declarative API
A simple custom resource only helps with the storage and retrieval of structured data. Custom resources should ideally be used where you want to use declarative APIs. The controller contains the knowledge on how to manage a particular resource. Using custom resources and custom controllers together provides fully declarative APIs. The controller assumes the structured data in the custom resources is the users’ desired state and runs in a loop to maintain this state by keeping both, desired and actual states, in sync. You can deploy custom controllers and update them on a running cluster without affecting the cluster’s lifecycle. Custom controllers can be used with any resource, but they work better with custom resources.
CRD: Making Kubernetes even more powerful
A custom resource definition adds to the incredible features Kubernetes already offers to its users. CRD helps extend Kubernetes’ features helps make it an even more universal tool for container orchestration. You can use custom resources to add your own resources that help with your specific requirements. And, you can use these resources like any native Kubernetes service and leverage all the features Kubernetes has to offer like security, RBAC, API services, and CLI. You can also use dynamic registration to have the custom resources appear and disappear while the cluster is running. To sum it up, custom resources provide even more extensibility than Kubernetes already offers. With newer versions, custom resources are bound to get even better. With increasing feature parity, this could be the next level for the already soaring container orchestration platform.
Featured image: Shutterstock