> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Extending Kubernetes Custom Resources and API Extensions

> Guide to extending the Kubernetes API with CustomResourceDefinitions, designing CRD schemas, versioning and validation with OpenAPI v3, and how controllers reconcile custom resources.

Platforms need higher-level, domain-aware APIs.

Kubernetes exposes a powerful, consistent API for core primitives (Pods, Services, Deployments), but those primitives are low-level. Developers think in domain terms: “I need a database,” not “I need a StatefulSet, a Secret, and a ServiceAccount.” Without a higher-level resource, one logical service maps to many scattered native objects—StatefulSets, ConfigMaps, Secrets, NetworkPolicies—making it hard to reason about platform state.

This guide explains how to extend the Kubernetes API using CustomResourceDefinitions (CRDs). You’ll learn:

* 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.

![A presentation slide titled "Kubernetes Built-In Resources – Limits" that outlines "The Gap" with four limitations: no domain-specific abstractions, no custom validation, no business logic integration, and no platform-specific concepts. Each point has a short explanation (e.g., can't create a single "Database" resource, can't enforce production backup rules, can't trigger workflows on resource changes, and teams/environments aren't native).](https://mintcdn.com/kodekloud-c4ac6d9a/seqLTE3JlSrVAtw9/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Platform-APIs-and-Self-Service-Capabilities/Extending-Kubernetes-Custom-Resources-and-API-Extensions/kubernetes-resources-limits-gap.jpg?fit=max\&auto=format\&n=seqLTE3JlSrVAtw9\&q=85\&s=6d2dcd5846a4fe24818c14ece07109af)

When teams rely solely on primitives, queries like “which databases exist?” require scripts that correlate many resources by labels and annotations. With CRDs you can run a single command:

* `kubectl get databases` — and get a meaningful list of domain objects.

Kubernetes is designed to be extended. Every API resource follows the same URL pattern: group, version, (optional) namespace, resource. Built-in types and custom types share this pattern (for example, deployments appear at `/apis/apps/v1/namespaces/default/deployments`). That means CRDs integrate seamlessly with kubectl, RBAC, controllers, GitOps tools, and policy engines.

![A presentation slide titled "The Kubernetes API – Extensible by Design" that lists four reasons why this matters: same tools work everywhere, native API experience, consistent patterns, and ecosystem integration. Each reason is shown in a colored, numbered box across the slide.](https://mintcdn.com/kodekloud-c4ac6d9a/seqLTE3JlSrVAtw9/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Platform-APIs-and-Self-Service-Capabilities/Extending-Kubernetes-Custom-Resources-and-API-Extensions/kubernetes-api-extensible-design-reasons.jpg?fit=max\&auto=format\&n=seqLTE3JlSrVAtw9\&q=85\&s=14961252ed460ef990e7c29f32a2aa67)

From the moment you create a CRD, the API server registers the new type and it becomes a first-class API resource. You extend Kubernetes’ API surface without changing Kubernetes core code.

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:

| Field | Purpose | Example |
| - | - | - |
| `group` | API group to avoid naming collisions; usually a DNS-style domain | `platform.acme.io` |
| `names` | How the resource is addressed: `plural` (URLs / kubectl), `singular`, `kind`, `shortNames` | `plural: databases`, `kind: Database`, `shortNames: ["db"]` |
| `scope` | Resource scope: `Namespaced` or `Cluster` | `Namespaced` |
| `versions` | One or more API versions; each can have its own schema and conversion strategy | `v1`, `v1beta1` |
| `schema` | OpenAPI v3 validation schema enforced by the API server | see examples below |
| `status` / subresources | Whether to enable status and scale subresources | `subresources: { status: {} }` |

Minimal CRD example (top-level structure and where schema belongs):

```yaml theme={null}
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: databases.platform.acme.io
spec:
  group: platform.acme.io
  scope: Namespaced
  names:
    plural: databases
    singular: database
    kind: Database
    shortNames:
      - db
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          # full validation schema goes here
          type: object
          properties:
            spec:
              type: object
              properties:
                size:
                  type: string
```

### 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.

Example: required fields and an enum constraint

```yaml theme={null}
# inside spec.versions[].schema:
openAPIV3Schema:
  type: object
  required: ["spec"]
  properties:
    spec:
      type: object
      required: ["size"]
      properties:
        size:
          type: string
          enum:
            - small
            - medium
            - large
        replicas:
          type: integer
          minimum: 1
          maximum: 10
```

With the schema above:

* The API server rejects requests that omit `spec` or `spec.size`.
* `size` accepts only `small`, `medium`, or `large`.
* `replicas` must 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.

Validation occurs at the API layer — controllers do not need to duplicate basic input validation, but they must handle valid states and reconcile external resources.

## CRD → CR → Controller: lifecycle and responsibilities

Typical workflow:

1. Create a CRD to register a new API type and its schema.
2. Developers create Custom Resources (CRs) using that kind and version.
3. A controller watches CRs and reconciles desired state to actual infrastructure (creating StatefulSets, Secrets, cloud resources, etc.), and updates the CR’s `status`.

In short: CRD (schema) → CR (instance) → Controller (implementation logic).

![A slide titled "From CRD to Custom Resource" showing a three-box flow: CRD (Schema) → CR (Instance) → Controller (Logic). Below the diagram are short definitions: CRD = class definition, CR = instance of that class, Controller = the logic that makes it real.](https://mintcdn.com/kodekloud-c4ac6d9a/seqLTE3JlSrVAtw9/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Platform-APIs-and-Self-Service-Capabilities/Extending-Kubernetes-Custom-Resources-and-API-Extensions/crd-to-cr-controller-diagram.jpg?fit=max\&auto=format\&n=seqLTE3JlSrVAtw9\&q=85\&s=917d7bf7bf7c56813a5762e1522e80d9)

Example custom resource that conforms to the CRD shown above:

```yaml theme={null}
apiVersion: platform.acme.io/v1
kind: Database
metadata:
  name: orders-db
spec:
  size: medium
  engine: postgresql
  replicas: 3
```

Apply the CR:

```bash theme={null}
kubectl apply -f database.yaml
```

Once applied, Custom Resources behave like native Kubernetes types. Example interactions:

```bash theme={null}
# List all databases
kubectl get databases

# Using the short name:
kubectl get db

# Describe a specific database:
kubectl describe db orders-db

# Delete the custom resource:
kubectl delete db orders-db
```

## 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`.

Recommended practices:

* 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)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)
* [apiextensions.k8s.io API reference](https://kubernetes.io/docs/reference/using-api/api-concepts/#customresourcedefinitions)
* [OpenAPI v3 specification](https://spec.openapis.org/oas/v3.1.0)

> **[Watch Video](https://learn.kodekloud.com/user/courses/prep-course-certified-cloud-native-platform-engineer-cnpe/module/756ffaae-767b-4743-9724-c05d3fbf9a18/lesson/aae4d782-46cf-4e49-acd3-faf8d0fe71bd)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.