No history yet

Introduction to Kubernetes CRDs

Extending the Kubernetes Language

Kubernetes comes with a built-in vocabulary of resources. You've likely worked with some of them already: Pods, Deployments, Services, and ConfigMaps are all standard Kubernetes objects. Think of these as the native nouns in the Kubernetes language. They give you powerful ways to describe and manage containerized applications.

But what if you need to manage something that doesn't fit neatly into these predefined categories? What if your application relies on a specific type of database cluster, a custom pipeline, or a unique piece of infrastructure that Kubernetes doesn't know about by default?

This is where Custom Resource Definitions, or CRDs, come in. A CRD is a way to teach Kubernetes a new noun. It allows you to define your very own resource type, extending the Kubernetes API to understand concepts specific to your needs.

Custom Resource Definitions (CRDs) enable you to extend Kubernetes' functionality by defining your own custom resources.

Once you've defined a new resource with a CRD, you can create instances of it, just like you would with a built-in resource like a Pod. These instances are called Custom Resources (CRs). The CRD is the blueprint, and the CR is the object you build from that blueprint.

Why Bother with Custom Resources?

Creating new resource types might sound complicated, but it unlocks powerful benefits for managing your applications and infrastructure.

First, CRDs make Kubernetes extensible. Instead of forcing your application's logic into existing resource types, you can create abstractions that perfectly match your domain. For example, the Prometheus Operator, a popular monitoring tool, uses CRDs to define resources like ServiceMonitor and PrometheusRule. This allows users to manage monitoring configurations using familiar Kubernetes tools like kubectl.

Second, they promote reusability and clarity. By creating a custom resource like DatabaseCluster, you create a high-level abstraction. Anyone on your team can now create a new database cluster with a simple YAML file without needing to understand the complex collection of Deployments, Services, and PersistentVolumes that make it work. It captures operational knowledge in a reusable, declarative format.

CRDs turn complex operational procedures into simple, declarative Kubernetes objects.

Finally, this leads to better automation. While we won't dive into the implementation here, CRDs are the foundation for the Operator pattern. A custom controller (the logic behind an Operator) can watch for your custom resources and perform complex actions to bring them to life. This is how you can ask Kubernetes for a DatabaseCluster and have it automatically provision storage, set up replication, and configure backups, all based on the specifications in your custom resource.

Creating an Abstraction

Let's look at a simple example. Imagine you regularly deploy static websites. Each deployment involves creating a Deployment to run an NGINX server and a Service to expose it to traffic. This is a repetitive two-step process.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-website
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:latest
---
apiVersion: v1
kind: Service
metadata:
  name: my-website-service
spec:
  selector:
    app: my-website
  ports:
    - protocol: TCP
      port: 80

With a CRD, you could create a new resource type called Website. The CRD would define that a Website object must have a spec field containing a Git repository URL.

# Custom Resource Definition (CRD)
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: websites.example.com
spec:
  group: example.com
  names:
    kind: Website
    plural: websites
  scope: Namespaced
  versions:
  - name: v1
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              gitRepo:
                type: string

After applying this CRD to your cluster, you could deploy a new website with a much simpler manifest. You would create a Website custom resource, and a custom controller (which you'd also build) would see this new resource and automatically create the required Deployment and Service in the background.

This is the power of abstraction. You've hidden the implementation details behind a simple, intuitive interface that speaks the language of your application.

# Custom Resource (CR)
apiVersion: example.com/v1
kind: Website
metadata:
  name: my-new-site
spec:
  gitRepo: "https://github.com/user/my-site.git"

By defining your own resources, you make your Kubernetes manifests more declarative and meaningful. Instead of describing how to run a website (a Deployment and a Service), you can simply declare that you want a website, and let automation handle the rest.

Quiz Questions 1/5

What is the primary purpose of a Custom Resource Definition (CRD) in Kubernetes?

Quiz Questions 2/5

What is the correct relationship between a Custom Resource Definition (CRD) and a Custom Resource (CR)?

CRDs are a cornerstone of Kubernetes' flexibility, allowing you to tailor the platform to your specific needs and build powerful, automated workflows.