What are Kubernetes Custom Resource Definitions (CRDs)?

What are Kubernetes Custom Resource Definitions (CRDs)?

In this article, we will explore Custom Resource Definitions (CRDs) in Kubernetes (K8S), explain what they are, possible use cases, and how to get started creating your own CRDs.

What are CRD in Kubernetes?

kubectl get MyRouter

I get an error:

error: the server doesn't have a resource type "MyRouter"

Viewing and Creating a CRD

Many tools that you install on your K8S cluster will include the creation of some CRD objects. This is to enable them to provide functionality that is not provided in vanilla K8S.

For example, if you have the monitoring tool Prometheus installed on your cluster, it will include the installation of prometheusrules.monitoring.coreos.com CRDs. CRDs are listed in the format <object>.<group>. With these installed, I can run the command kubectl get prometheusrules -n prometheus — before the installation of Prometheus on my cluster, these commands would return an error:

error: the server doesn't have a resource type "prometheusrules"

With it installed, the command shows me a list of Prometheus rules.

list of prometheus rules

Because CRDs are created with most tool installations, you will likely have some CRDs already installed on your cluster.

You can view a list using the command:

kubectl get crd
kubectl get crd

To create a CRD, we need to create a new YAML file. The example below defines a resource definition for switches that I have in my datacenter that I will manage using K8S. Before you jump in, be aware that most scenarios do not need a new CRD created from scratch, they already have a solution out there on the internet.


apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
  name: switches.datacenter.com  # name must match the spec fields below, and be in the form: <plural>.<group>
  group: datacenter.com  # group name to use for REST API: /apis/<group>/<version>
    - name: v1 
      served: true # Each version can be enabled/disabled by Served flag.
      storage: true # One and only one version must be marked as the storage version.
          type: object
              type: object
                  type: string
                  type: integer
                  type: string
  scope: Cluster # either Namespaced or Cluster
    plural: switches # plural name to be used in the URL: /apis/<group>/<version>/<plural>
    singular: switch # singular name to be used as an alias on the CLI and for display
    kind: Switch # kind is normally the CamelCased singular type. Your resource manifests use this.
    shortNames: # shortNames allow shorter string to match your resource on the CLI
    - sw

I can apply it using:

kubectl apply -f switchcrd.yaml
kubectl apply -f switchcrd.yaml

I can see it added to the list of my CRDs by using the command:

kubectl get crd
added to the list kubectl get crd

Now I can run the command:

kubectl get switches
kubectl get switches
apiVersion: datacenter.com/v1
kind: Switch 
  name: switch1
  dataCenter: uksouth
  rack: 280
  type: physical

Apply it using the command:

kubectl apply -f .\switch1.yaml

Now we can list our switches:

kubectl get switches
kubectl get switches list

Key Points

Custom resource definitions (CRDs) enables Kubernetes to be hugely flexible when it comes to deciding what you want it to manage. CRDs are considered a fairly advanced K8S topic. You should understand the basics before diving in!

Additionally, Spacelift can help you manage the complexities and compliance challenges of using Kubernetes. Anything that can be run via kubectl can be run within a Spacelift stack. Read more about how Spacelift works with Kubernetes.

The Most Flexible CI/CD Automation Tool

Spacelift is an alternative to using homegrown solutions on top of a generic CI. It helps overcome common state management issues and adds several must-have capabilities for infrastructure management.

Start free trial