Kubernetes was built to manage your fleet of clusters for you. It comes built-in with standard objects like Services, Deployments, and Ingresses to name a few. The typical flow of operations is the administrator defining key objects they need on the cluster, and Kubernetes making sure they always exist and are operational.
This constant loop allows administrators to manage the desired states of their clusters in versioning systems like Git, and it gave birth to operational flows like GitOps, building on DevOps best practices.
Now, when administrators want Kubernetes to manage more objects than what is already available, they can define their own. These are called CRDs: Custom Resource Definitions.
What are Kubernetes Custom Resource Definitions (CRDs)
Kubernetes Custom Resource Definitions (CRDs) are definition files—structured data that describe objects (Custom Resources) and their desired state—that extend the scope of Kubernetes and leverage the existing K8s ecosystem.
Administrators manipulate these Custom Resources through the same available tools (e.g., kubectl) and secure them with the same role based access control. Once defined and added to the state of the cluster, these objects are available through the standard K8s API.
How are Kubernetes Custom Resources handled?
Since CRDs are definitions only, administrators need to add specific skills to Kubernetes so it can handle these new resources—the same way they install Ingress Controllers to manage the standard Ingress Objects.
Operators or controllers are the components responsible for managing custom resources in Kubernetes.
For example, Traefik extends the capabilities of the standard Ingress objects with the help of the IngressRoute CRD. Traefik, as the IngressRoute Controller, is responsible for managing these IngressRoute objects and allows requests to be dispatched leveraging fine-grained routing rules.
Kubernetes Administrators who add CRDs to their cluster will also add operators to manage these new resources.
Creating and Applying CRDs (With an Example)
Let's consider an example to illustrate the use of CRDs. Suppose you are managing a backup pipeline using Kubernetes.
In this system, each backup pipeline is a resource that needs to be managed. However, Kubernetes' built-in resources don't quite fit the concept of a backup pipeline. This is where CRDs can be very helpful.
Creating such a CRD in Kubernetes starts with defining the schema, using JSON Schema. This schema outlines the structure of your custom resource, and allows you to define acceptable values and structure.
Let’s then define a backup pipeline and its attributes. We’ll consider a pipeline to have 4 attributes:
- appId—a unique identifier
- Periodicity—a frequency of daily, weekly, or monthly
- Copies—a number between 1 and 10 indicating how many copies of the backup the system should keep over time
- Mode—either incremental or full
Only appId, periodicity, and mode are required fields.
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: bupipelines.traefik.io spec: group: traefik.io names: plural: bupipelines singular: bupipeline kind: BUPipeLine shortNames: - bupl scope: Namespaced versions: - name: v1alpha1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: appId: type: string periodicity: type: string enum: - daily - weekly - monthly copies: type: integer minimum: 1 maximum: 10 mode: type: string enum: - incremental - full required: ["appId", "periodicity", "mode"] required: ["spec"]
To allow Kubernetes to handle this new CRD, use the command
kubectl apply. In the following example, we saved the CRD in a file named
kubectl apply -f backuppipeline.yaml customresourcedefinition.apiextensions.k8s.io/bupipelines.traefik.io created
Using CRDs to Create and Manage Custom Resources
Once a CRD has been created, users can create custom resources of that type. These resources can be managed using the Kubernetes API, just like any other resource. They can be created, updated, deleted, and retrieved using the kubectl command-line tool or any other tool that interacts with the Kubernetes API.
Use the example given above, and define a BUPipeline:
apiVersion: traefik.io/v1alpha1 kind: BUPipeLine metadata: name: test-pipeline spec: appId: daily-backup periodicity: daily mode: incremental copies: 5
Assuming the above content was saved to a file named
bupipeline-std.yaml, you can apply it with
kubectl apply -f bupipeline-std.yaml.
kubectl apply -f bupipeline-std.yaml bupipeline.traefik.io/test-pipeline created
And if you tried with an incorrect value, K8s would refuse to apply the change. For example, if we tried to define 15 copies, we’d get the following error:
kubectl apply -f bupipeline-std.yaml The BUPipeLine "test-pipeline" is invalid: spec.copies: Invalid value: 15: spec.copies in body should be less than or equal to 10
Benefits of Using CRDs
Custom Resource Definitions provide important benefits for anyone running their applications in Kubernetes at scale. The two most important benefits are:
- Extended Functionality—CRDs extend the functionality of the Kubernetes API, enabling it to manage more than its standard objects. This flexibility is one of the key reasons behind the popularity of Kubernetes.
- Adaptability—CRDs, when used in conjunction with Kubernetes operators, open up almost unlimited possibilities for adapting Kubernetes to manage every part of your infrastructure.
CRDs provide a way to extend the Kubernetes API beyond standard out-of-the-box functionality, allowing users to create custom resources that adapt to every unique environment. This makes Kubernetes more flexible, and a perfect fit in a wide range of scenarios.
If you’re managing company microservices and APIs in Kubernetes, know that Traefik Hub, the industry’s first Kubernets-native API management solution, takes full advantage of CRDs and introduces Custom Resources for the whole lifecycle of APIs. Request your free trial of Traefik Hub today.