Custom Resource Definitions (CRDs)

Custom Resource Definitions (CRDs) allow you to extend the Kubernetes API with your own custom resource types. They enable you to define application-specific objects that can be managed using standard Kubernetes tools like kubectl, stored in etcd alongside built-in resources, and integrated with Kubernetes’ declarative management patterns.

What are Custom Resources?

A Custom Resource is an extension of the Kubernetes API that represents a customization of a particular Kubernetes installation. Custom Resources can appear and disappear in a running cluster through dynamic registration, and cluster admins can update Custom Resources independently of the cluster itself.

Why Use Custom Resources?

Custom Resources provide several key benefits:

BenefitDescription
API ConsistencyUse the same API patterns and tools (kubectl, RBAC, etc.) for custom objects
Declarative ManagementLeverage Kubernetes’ declarative approach for your custom resources
IntegrationSeamlessly integrate with existing Kubernetes tooling and workflows
VersioningSupport multiple API versions with automatic conversion
ValidationDefine schemas to validate custom resource specifications

Creating a Custom Resource Definition

A CRD defines the schema and behavior of a custom resource. Here’s a basic example of a Website CRD:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: websites.example.com
spec:
  group: example.com
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              domain:
                type: string
                pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'
              replicas:
                type: integer
                minimum: 1
                maximum: 100
              image:
                type: string
            required:
            - domain
            - image
          status:
            type: object
            properties:
              phase:
                type: string
                enum: ["Pending", "Running", "Failed"]
              message:
                type: string
  scope: Namespaced
  names:
    plural: websites
    singular: website
    kind: Website

Key Components of a CRD

ComponentDescriptionPurpose
GroupAPI group for the custom resourceOrganizes related resources (e.g., example.com)
VersionAPI version for the resourceEnables API evolution and compatibility
KindThe type name of the custom resourceUsed in YAML manifests (e.g., Website)
ScopeWhether the resource is namespaced or cluster-wideDetermines resource visibility and isolation
SchemaOpenAPI v3 schema for validationDefines the structure and constraints of the resource

Working with Custom Resources

Once you’ve created a CRD, you can work with custom resources just like built-in Kubernetes resources.

Creating a Custom Resource Instance

apiVersion: example.com/v1
kind: Website
metadata:
  name: my-website
  namespace: default
spec:
  domain: myapp.example.com
  replicas: 3
  image: nginx:1.20

Managing Custom Resources with kubectl

# Create the CRD
kubectl apply -f website-crd.yaml

# Create a custom resource instance
kubectl apply -f my-website.yaml

# List all websites
kubectl get websites

# Describe a specific website
kubectl describe website my-website

# Delete a website
kubectl delete website my-website

Advanced CRD Features

Schema Validation

CRDs support comprehensive OpenAPI v3 schema validation. In the example below, we are inspecting the resources object to make sure that it contains cpu and memory fields as strings that match specific patterns:

  • cpu must be a string representing either an integer, an integer followed by “m” (for millicores), or a decimal number,
  • memory must be a string starting with an integer and optionally followed by valid memory units like “Ki”, “Mi”, or “Gi”.
schema:
  openAPIV3Schema:
    type: object
    properties:
      spec:
        type: object
        properties:
          resources:
            type: object
            properties:
              requests:
                type: object
                properties:
                  cpu:
                    type: string
                    pattern: '^(\d+m?|\d+\.\d+)$'
                  memory:
                    type: string
                    pattern: '^(\d+)(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$'
        required:
        - resources

Multiple Versions and Conversion

CRDs support multiple API versions with automatic conversion between versions:

spec:
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      # v1 schema
  - name: v1beta1
    served: true
    storage: false
    schema:
      # v1beta1 schema
  conversion:
    strategy: Webhook
    webhook:
      clientConfig:
        service:
          name: example-conversion-webhook
          namespace: default

Subresources

CRDs can define subresources like /status and /scale:

spec:
  versions:
  - name: v1
    served: true
    storage: true
    subresources:
      status: {}
      scale:
        specReplicasPath: .spec.replicas
        statusReplicasPath: .status.replicas
        labelSelectorPath: .status.selector

Custom Resource Categories and Short Names

Make your custom resources easier to work with by defining categories and short names:

spec:
  names:
    plural: websites
    singular: website
    kind: Website
    shortNames:
    - ws
    categories:
    - all
    - mycompany

This allows users to run commands like:

kubectl get ws              # Using short name
kubectl get all             # Includes websites in "all" category
kubectl get mycompany       # Custom category

Best Practices for CRDs

Design Principles

When designing Custom Resource Definitions, follow these principles:

PrincipleImplementationBenefits
Single ResponsibilityEach CRD should represent one conceptEasier to understand and maintain
Immutable SpecAvoid changing spec fields after creationPrevents configuration drift
Rich StatusProvide detailed status informationEnables better observability and debugging
Semantic VersioningUse semantic versioning for API versionsClear compatibility expectations
Comprehensive ValidationDefine thorough schema validationPrevents invalid configurations

Common Use Cases for CRDs

Custom Resource Definitions are particularly useful for:

Use CaseExampleBenefits
Application ConfigurationDatabase schemas, API configurationsDeclarative application management
Infrastructure as CodeCloud resources, network policiesKubernetes-native infrastructure management
Workflow ManagementCI/CD pipelines, batch jobsIntegrated workflow orchestration
Policy DefinitionSecurity policies, compliance rulesCentralized policy management
Integration PointsExternal service configurationsUnified configuration management

Further Reading and Resources