Skip to main content
This guide explains CustomResourceDefinitions (CRDs) in Kubernetes — how they extend the Kubernetes API, how objects are persisted, and how controllers act on those objects. It preserves the sequence of concepts and diagrams so you can follow the flow from built-in resources to custom resources and controllers.

How built-in Kubernetes resources work

When you create a built-in resource such as a Deployment, Kubernetes persists the object in etcd and a controller reconciles the cluster to match the desired state recorded in that object. You can manage these objects with kubectl. Example: a simple Deployment YAML and typical kubectl commands
Controllers are control-plane processes that watch objects and reconcile actual cluster state to the desired state. For example, the Deployment controller creates a ReplicaSet for the Deployment, and the ReplicaSet creates Pods. Small excerpt of what a controller looks like in Go (for illustration only):
We have many built-in resource types (ReplicaSets, Deployments, Jobs, CronJobs, StatefulSets, Namespaces, etc.), and each normally has a controller responsible for ensuring the cluster matches the desired state.
A simple diagram showing Kubernetes resources (ReplicaSet, Deployment, Job, CronJob, StatefulSet, Namespace) on the left and corresponding controllers on the right with ETCD depicted between them. It illustrates the relationship between resources, controllers, and the ETCD datastore.

Extending the Kubernetes API: custom resource example

You can extend the Kubernetes API to include your own resource types using a CustomResourceDefinition (CRD). For example, suppose you want to model flight bookings inside Kubernetes with a custom resource called FlightTicket. Desired FlightTicket manifest:
Once a CRD is registered, kubectl should be able to create, list, and delete FlightTicket objects:
Important: creating the FlightTicket object only persists it in etcd via the API server. To perform side effects (for example, call an external booking service like bookflight.com/API when a FlightTicket is created), you must run a controller that watches FlightTicket objects and takes action. Illustrative snippet of a custom controller in Go:
If the cluster does not know about the FlightTicket resource type, kubectl will fail with the following error:
This error occurs because the API server has not been told about the new resource type. You register a new resource type with the API server using a CustomResourceDefinition.

What is a CustomResourceDefinition (CRD)?

A CRD is itself an API object (apiVersion: apiextensions.k8s.io/v1, kind: CustomResourceDefinition) that instructs the API server to accept a new resource type. The CRD defines:
  • API group and versions (for example, flights.com/v1)
  • resource names (kind, singular, plural, shortNames)
  • scope (Namespaced or Cluster)
  • OpenAPI v3 validation schema (openAPIV3Schema) for server-side validation
  • which version is served and which is storage
Example CRD (key parts):
The openAPIV3Schema field lets the API server validate incoming objects. In this example, from and to are strings and number must be an integer between 1 and 10. If a user submits invalid data, the API server will reject the object according to this schema. Create the CRD and then the custom resource:
Creating a CRD registers a new resource type with the Kubernetes API and enables persisted objects of that type. A CRD provides validation and API wiring but does not implement business logic — to make the resource trigger actions (for example, call an external booking API), you must deploy a controller that watches those custom objects and reconciles desired state to actual state.

Quick reference: CRD spec fields

Summary

  • CRDs extend the Kubernetes API by registering new resource types (for example, FlightTicket).
  • After a CRD is created, you can create, list, and delete custom resources using kubectl.
  • CRDs support OpenAPI v3 schemas for server-side validation of resource fields.
  • To make custom resources trigger real-world actions, implement and run a controller that watches the custom resources and reconciles them (e.g., call external APIs).

Watch Video

Practice Lab