Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To create a Kubernetes custom resource, define and apply a CustomResourceDefinition (CRD), then create an instance of the new type. The CRD registers the type and schema; it does not automate anything by itself. Add a controller only when the resource should trigger ongoing reconciliation or application-specific actions.
How do I create my first Kubernetes custom resource?
Start by deciding whether the object belongs in the Kubernetes API. A custom resource is most useful for declarative configuration or desired state that benefits from Kubernetes conventions, kubectl, API clients, watches, or automation. A CRD tells the API server what the new type looks like and lets it serve and store instances. Once registered, those instances can be managed with Kubernetes clients just like other API resources.
If you only need to provide an existing configuration file to a workload, a ConfigMap may be simpler. For imperative request/response operations, nonstandard REST paths, sustained high-volume traffic, or large end-user data, consider a standalone API instead. Custom resources use API-server storage and are a poor fit for large application data. Kubernetes documents these trade-offs.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsChoose what the object represents
Model a relatively small, declarative configuration object—not a general-purpose database or an action request. For example, an object might describe the desired configuration of an application component. If you need Kubernetes to react to that declaration, plan for a controller as well as the CRD.
#1 Best Overall
What belongs in a CRD?
A CRD defines the API identity, scope, versions, and schema for a new resource type. Plan these elements before writing the manifest:
- API group: Namespaces your API, such as
example.com. - Plural and singular names: The plural is used as the resource name; the CRD’s full name is derived from that plural name and the group.
- Kind: The type name users see in objects, such as
Widget. - Scope: Choose whether instances are namespaced or cluster-scoped.
- Version: Declare which API version clients can use and which version stores the data.
- Schema: Specify the fields, types, and validation rules with the CRD’s OpenAPI v3 schema.
Keep the schema purposeful: define the fields users need and avoid a catch-all arbitrary object unless preserving arbitrary data is an explicit requirement. Kubernetes also supports status subresources and admission webhooks for CRDs. Consult the CRD task documentation for the manifest format and version-specific capabilities.
Choose scope deliberately
A namespaced custom object belongs to a namespace; deleting that namespace deletes its objects. A cluster-scoped object is not tied to a namespace. The CRD definition itself is non-namespaced, regardless of the scope selected for instances. Choose scope based on ownership, lifecycle, and access patterns—not convenience alone.
Apply the CRD, then create an instance
The essential sequence is to install the type before submitting objects that use it. The manifest below is a minimal illustrative pattern, not a complete production API; replace the example names and schema with your design, and check the CRD documentation for the Kubernetes release you target.
Rank #3
- Save a CRD manifest. Define the group, names, scope, served and storage version, and schema. For example, a namespaced type could use group
example.com, kindWidget, and plural namewidgets. - Register the type: run
kubectl apply -f widget-crd.yaml. - Wait for establishment: run
kubectl wait --for condition=Established --timeout=60s crd/widgets.example.com. - Check API discovery: run
kubectl api-resources --api-group=example.com. Confirm that the resource appears before creating an instance. - Create an instance manifest: set
apiVersion: example.com/v1,kind: Widget, a name undermetadata, and values underspecthat match your schema. For a namespaced type, provide a namespace or use the namespace selected by your kubectl context. - Apply and inspect the instance: run
kubectl apply -f widget.yaml, thenkubectl get widgetsandkubectl describe widget <name>. The API server can store and return the object even if no controller exists.
For exact syntax, including schema details and version declarations, follow the official CRD task guide. Commands and available capabilities can vary by Kubernetes version.
Do I need a controller for a CRD?
No—not just to register a type or store and retrieve its objects. As the Kubernetes documentation puts it, “On their own, custom resources let you store and retrieve structured data.” The custom resources guide distinguishes that basic API role from automation.
Add a controller when users expect the cluster to act on the declared state. A controller watches custom resources and repeatedly reconciles related Kubernetes objects or external effects so the observed system moves toward the desired state. A CRD paired with a controller is commonly associated with the operator pattern; an operator encodes application-specific operating knowledge in that controller-based extension.
Recommended Free Tools
CRD only or CRD plus controller?
| Approach | What it provides | When it fits |
|---|---|---|
| CRD only | A registered API type whose instances the API server serves and stores | When clients need structured data in Kubernetes but no ongoing action is required |
| CRD plus controller | The API type plus a process that watches instances and reconciles desired state | When a declaration should create, update, or manage related resources or external effects |
A controller is an additional operational component, not a feature switched on by adding fields to a CRD. Some packages install both a CRD and a controller, so account for the code and lifecycle of each.
Best Value
Choosing a controller approach
If reconciliation is required, the Kubernetes operator guide lists frameworks and approaches including Kubebuilder, Operator Framework, Kopf, and Java Operator SDK. They are options, not a universal recommendation. Choose based on your language, project needs, and the maintenance model you can support. The Kubernetes operator guide explains the pattern.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Plan API versions and permissions
Served and storage versions
Decide which CRD version clients may use (served) and which version Kubernetes uses to store objects (storage). As the schema evolves, plan how existing objects and clients move between versions. If versions have schema differences that require custom conversion logic, Kubernetes supports conversion webhooks. See the CRD versioning guide before changing a version plan.
RBAC access
Custom resources use Kubernetes authentication, authorization, and audit logging, but existing roles do not automatically grant access to a newly introduced resource type. Add explicit RBAC rules for the custom resource and any subresources users or controllers need. The Kubernetes RBAC reference describes how permissions are granted.
Quick Recap
Common first-CRD mistakes
- Expecting behavior from the CRD: It registers a type and schema; automation requires a controller.
- Choosing scope casually: Namespace deletion removes namespaced instances, while cluster-scoped objects have different lifecycle and access semantics.
- Leaving the schema vague: Define meaningful fields and validation so invalid desired state can be rejected.
- Ignoring version evolution: Set served and storage versions intentionally, and plan conversion if schemas diverge.
- Assuming permissions carry over: Grant RBAC access to the new type explicitly.
- Using a custom resource as a data store: Keep it focused on configuration or desired state, not large application or end-user data.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

