- Why built-in resources are insufficient for platform-level abstractions.
- How the API extension model works.
- How to author CRDs with correct group, names, scope, and schema.
- How to validate resources using OpenAPI v3.
- How CRDs, Custom Resources (CRs), and controllers interact.

kubectl get databases— and get a meaningful list of domain objects.
/apis/apps/v1/namespaces/default/deployments). That means CRDs integrate seamlessly with kubectl, RBAC, controllers, GitOps tools, and policy engines.

Using CRDs gives you a native API experience: the new resource is reachable through the same endpoints and tooling as built-in types. This ensures compatibility with
kubectl, clients, RBAC policies, admission controllers, and GitOps workflows.CRD structure and important fields
A CustomResourceDefinition declares a new resource type to the API server. Key spec fields you should always consider:
Minimal CRD example (top-level structure and where schema belongs):
Versions and conversion
You can serve multiple versions for the same custom resource (for example:v1alpha1, v1beta1, v1). Each version can define its own schema and conversion strategy. Design your versioning and conversion plan to support safe schema evolution and backward compatibility—this avoids breaking consumers or controllers.
OpenAPI v3 schema validation
The CRD’s OpenAPI v3 schema is validated by the API server on create and update. Proper schema design prevents invalid objects from being persisted to etcd and saves controller cycles. Validation capabilities:- Type checking:
string,integer,object,array, etc. - Enum constraints: restrict a field to a set of allowed values.
- Required fields: ensure essential properties exist.
- Numeric constraints:
minimum,maximum, etc. - Nested object validation and arrays.
- The API server rejects requests that omit
specorspec.size. sizeaccepts onlysmall,medium, orlarge.replicasmust be an integer between 1 and 10.
CRD validation is powerful but not all-expressive. Some rules (like cross-field dependencies or complex business logic) may require admission webhooks or controller-side checks. Always combine schema validation with controller-level safeguards when needed.
CRD → CR → Controller: lifecycle and responsibilities
Typical workflow:- Create a CRD to register a new API type and its schema.
- Developers create Custom Resources (CRs) using that kind and version.
- A controller watches CRs and reconciles desired state to actual infrastructure (creating StatefulSets, Secrets, cloud resources, etc.), and updates the CR’s
status.

Best practices and mental model
- CRD = class definition: schema, validation, API surface.
- CR = instance of the class: desired state specified by users.
- Controller = implementation logic: reconcile desired to actual state and update
status.
- Use a DNS-style API group (e.g.,
platform.acme.io) to avoid collisions. - Provide shortNames for ergonomics (e.g.,
db). - Design robust OpenAPI v3 schemas to catch invalid input early.
- Plan versioning and conversion strategies before wide adoption.
- Expose only the fields users need; avoid leaking internal implementation details.
- Use subresources (
status,scale) to cleanly separate desired vs observed state.
Takeaways
- CRDs let you extend Kubernetes without modifying its core.
- Custom resources are first-class Kubernetes API objects that integrate with existing tooling and patterns.
- OpenAPI v3 schema in CRDs validates objects at the API layer and prevents invalid inputs from reaching controllers.
- The lifecycle flows from CRD → CR → Controller, enabling platforms to expose higher-level abstractions (for example, Database) and provide a native, consistent developer experience.
Links and References
- Kubernetes Custom Resources and CRDs (official)
- apiextensions.k8s.io API reference
- OpenAPI v3 specification