# Kubernetes CRDs (Custom Resource Definitions)

A Custom Resource Definition (CRD) in Kubernetes is a powerful API extension tool that allows users to create custom resources. These resources extend Kubernetes' capabilities by enabling you to define your own resource types that fit specific application or infrastructure needs. CRDs essentially transform Kubernetes into a more flexible platform that can manage not just containers but any kind of resource relevant to your environment.

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](/content/finops-glossary/kubernetes-pods/index.html), 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](/content/finops-glossary/kubectl-kubernetes/index.html).

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

```yaml
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](/content/finops-glossary/kubernetes-cluster/index.html):

```yaml
kubectl apply -f database-crd.yaml
```

### Step 2: Create an Instance of the Custom Resource

Now, let’s create a `Database` instance:

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

Apply the custom resource:

```yaml
kubectl apply -f database-instance.yaml
```

This will create a new resource named `my-database`, managed entirely within [Kubernetes](/content/finops-glossary/kubernetes/index.html).

### 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](https://github.com/kubernetes-sigs/kubebuilder) or [Operator SDK](https://operatorframework.io/).

## 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](/content/finops-glossary/prometheus/index.html) 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](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)**
2. **[Kubebuilder Documentation](https://book.kubebuilder.io/reference/markers/crd)**
3. **[Operator SDK](https://operatorframework.io/)**
4. **[Practical Examples Github](https://github.com/kubernetes/sample-controller)**
5. **YouTube Tutorial**

https://www.youtube.com/watch?v=Uwy0VUW5SOo
