With CRDs, your custom resource types behave like native Kubernetes objects. They can be managed with Kubernetes tools such as kubectl and follow the same declarative principles used for built-in resources.

Why Use CRDs?

CRDs are essential when the standard Kubernetes resources (like Pods, Deployments, or Services) don’t meet the requirements of your application. They enable you to:

  1. Customize the Kubernetes API: Add resource types specific to your workflows.
  2. Simplify Management: Encapsulate complex configurations and automate processes.
  3. Leverage Kubernetes Ecosystem: Use Kubernetes-native tools to interact with your custom resources.

For example, if you’re building an application that needs specialized workflows like creating blog posts or managing custom infrastructure resources, they allow you to define these concepts as Kubernetes resources.

How CRDs Work

They are part of Kubernetes’ API extension model. Here’s how they function:

  1. Define a CRD: Describe the schema, names, and scope of your new resource type.
  2. Register the CRD: Apply the CRD to your cluster, which adds a new API endpoint for your custom resource.
  3. Create Custom Resources (CRs): Use your custom resource type just like built-in Kubernetes objects, with YAML manifests or kubectl commands.

How to Create a CRD

Let’s create a practical example of a custom resource called Database, used to define configurations for managing database instances.

Step 1: Define the CRD

Here’s a YAML file for the Database resource definition:


  apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: databases.example.com
spec:
  group: example.com
  names:
    plural: databases
    singular: database
    kind: Database
    shortNames:
    - db
  scope: Namespaced
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              engine:
                type: string
                enum:
                - mysql
                - postgresql
              version:
                type: string
              storage:
                type: string




  • group: Defines the API group for your resource (e.g., example.com).
  • names: Specifies the naming conventions for your resource.
  • scope: Determines whether the resource is namespaced or cluster-wide.
  • schema: Describes the structure and validation rules for the resource.

Apply this CRD to your cluster:


  kubectl apply -f database-crd.yaml





Step 2: Create an Instance of the Custom Resource

Now, let’s create a Database instance:


  apiVersion: example.com/v1
kind: Database
metadata:
  name: my-database
spec:
  engine: postgresql
  version: "13"
  storage: "100Gi"




Apply the custom resource:


  kubectl apply -f database-instance.yaml





This will create a new resource named my-database, managed entirely within Kubernetes.

Integrating CRDs with Custom Controllers

CRDs define the resource, but they don’t include the logic to act on them. That’s where custom controllers come in. A custom controller watches for changes to your custom resources and performs specific actions in response.

For example, a controller for the Database resource could automate:

  • Provisioning database instances on cloud providers.
  • Backing up data when the resource is deleted.
  • Upgrading the database version when specified in the spec.

Controllers can be built using tools like Kubebuilder or Operator SDK.

Key Features

  1. Declarative Schema: Define custom resource structures using OpenAPI validation.
  2. Scalability: Manage custom resources across namespaces or the entire cluster.
  3. Versioning: Support multiple versions of your resource to handle API changes over time.
  4. Integration with Kubernetes Tools: Work seamlessly with kubectl, Helm, and Kubernetes RBAC.

Use Cases for CRDs

  1. Application-Specific Workflows:
    • Example: Define a BlogPost resource to manage blog publishing workflows.
  2. Infrastructure Management:
    • Example: Use a Database resource to automate database provisioning.
  3. Kubernetes Operators:
    • Example: Operators like Prometheus and Elasticsearch use CRDs to expose application-specific APIs.
  4. Custom Monitoring:
    • Example: A MonitoringRule CRD to define alert rules and thresholds.

Benefits of CRDs

  • Flexibility: Adapt Kubernetes to fit your unique needs.
  • Automation: Simplify complex workflows by pairing CRDs with custom controllers.
  • Reusability: Encapsulate logic and configurations into reusable resource types.

Limitations

  • Complexity: Designing effective CRDs and controllers requires a deep understanding of Kubernetes.
  • No Built-in Behavior: CRDs don’t inherently do anything without custom controllers.
  • API Evolution: Managing multiple versions of your custom resource can be challenging.

Resources for Further Reading

  1. Official Kubernetes Documentation
  2. Kubebuilder Documentation
  3. Operator SDK
  4. Practical Examples Github
  5. YouTube Tutorial
https://www.youtube.com/watch?v=Uwy0VUW5SOo