Skip to main content

Command Palette

Search for a command to run...

Kubernetes Custom Resources Explained: CRD, CR, and Custom Controllers

Updated
6 min read

Kubernetes comes with many powerful built-in resources like:

  • Pods

  • Deployments

  • Services

  • ConfigMaps

  • Secrets

These resources allow us to deploy and manage applications effectively.

But Kubernetes is used in thousands of organizations, each with different requirements. Many advanced tools such as service meshes, GitOps platforms, monitoring systems, and security tools need capabilities that are not available in the default Kubernetes API.

So how does Kubernetes support these additional features without making the core system extremely complex?

The answer is Custom Resources.

In this article, we will understand:

  • Why Kubernetes needs Custom Resources

  • What CRD, CR, and Custom Controllers are

  • How they work together

  • A simple real-world example using tools like Istio and Argo CD


Why Kubernetes Needs Custom Resources

Kubernetes cannot include every possible feature inside its core system.

For example, organizations often use tools like:

  • Istio → Service mesh and traffic management

  • Argo CD → GitOps continuous deployment

  • Prometheus → Monitoring and metrics

  • Cert Manager → TLS certificate automation

If Kubernetes tried to include logic for all these tools, the platform would become extremely large and difficult to maintain.

Instead, Kubernetes provides a mechanism to extend its API.

This allows developers and organizations to introduce new resource types inside Kubernetes that behave just like built-in resources.

This extension is achieved using Custom Resource Definitions (CRDs).


Native Kubernetes Resources vs Custom Resources

Before understanding custom resources, let's first look at how native resources work.

Example Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3

When this YAML is applied:

kubectl apply -f deployment.yaml

Kubernetes performs three main steps:

  1. The API Server validates the YAML

  2. The resource is stored in etcd

  3. The Deployment Controller creates pods

This process involves three components:

Component Description
Resource Definition Built-in schema for Deployments
Resource The Deployment YAML created by the user
Controller Kubernetes component that creates and manages pods

Custom resources follow exactly the same architecture.


The Three Core Components

To extend Kubernetes functionality, three components are involved.

1. Custom Resource Definition (CRD)

A Custom Resource Definition (CRD) defines a new type of resource in Kubernetes.

It acts as a blueprint or schema that tells Kubernetes:

  • What the resource is called

  • What fields it supports

  • How the YAML should look

Example:

kind: CustomResourceDefinition

After installing a CRD, Kubernetes understands a new resource type.

For example:

VirtualService
Application
ServiceMonitor
Certificate

These resources are not native to Kubernetes but are added by external tools.


2. Custom Resource (CR)

A Custom Resource (CR) is an instance of the CRD.

It is the actual object created by a user to use the new functionality.

Example:

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
  - myapp.example.com

Here:

  • VirtualService is the custom resource

  • It follows the schema defined in the CRD

  • Kubernetes validates it using the CRD

However, creating a custom resource alone does nothing.

Something must observe and act on it.

That component is the Custom Controller.


3. Custom Controller

A Custom Controller is a program that watches custom resources and performs actions when they change.

It works exactly like Kubernetes built-in controllers.

For example:

Controller Watches Action
Deployment Controller Deployments Creates ReplicaSets
ReplicaSet Controller ReplicaSets Creates Pods

Similarly:

Custom Controller Watches Action
Istio Controller VirtualService Configures traffic routing
Argo CD Controller Application Syncs Git repositories
Prometheus Controller ServiceMonitor Configures monitoring

Controllers constantly compare:

Desired State vs Actual State

and make changes to keep the cluster in the desired state.

This process is called the Reconciliation Loop.


How These Components Work Together

The workflow typically looks like this:

CRD is installed in the cluster
        ↓
Kubernetes API server registers the new resource type
        ↓
A Custom Resource is created
        ↓
The Custom Controller watches the resource
        ↓
The controller performs the required actions

Or visually:

CRD
 ↓ defines
Custom Resource
 ↓ watched by
Controller
 ↓ performs actions
Pods / Services / Configurations

Roles and Responsibilities

Two main actors interact with custom resources.

Platform Engineers / Cluster Operators

Responsible for:

  • Installing CRDs

  • Deploying custom controllers

  • Debugging issues by checking logs and resource status

Usually these are installed using tools like:

Helm
Operators
Kubernetes manifests

Developers / Users

Responsible for:

  • Creating Custom Resources

  • Defining configurations required by the application

Example:

Traffic rules
Monitoring configuration
Deployment automation

Example: Istio Service Mesh

Istio is a great real-world example of Kubernetes extensions.

When installing Istio using Helm:

helm repo add istio https://istio-release.storage.googleapis.com/charts
kubectl create namespace istio-system
helm install istio-base istio/base -n istio-system

Two major things happen:

Istio Custom Resource Definitions (CRDs) are installed
• Kubernetes learns new resource types related to Istio

You can verify this by running:

kubectl get crd

You will see resources like:

virtualservices.networking.istio.io
destinationrules.networking.istio.io
gateways.networking.istio.io

These CRDs extend the Kubernetes API and allow users to create new resources such as:

kind: VirtualService

Once the Istio control plane (controllers) is installed, these controllers watch the custom resources and configure traffic routing between services.


How Custom Controllers Work Internally

Most custom controllers are written in Golang because Kubernetes itself is written in Go.

Developers typically use:

  • client-go

  • controller-runtime

  • Operator SDK

The controller workflow usually follows this pattern:

  1. Watch resource changes (create/update/delete)

  2. Add events to a worker queue

  3. Process each event

  4. Update the cluster state

This ensures the system remains consistent and self-healing.


Real World Kubernetes Extensions

Many popular Kubernetes tools rely on CRDs and custom controllers.

Tool Custom Resource
Istio VirtualService
Argo CD Application
Prometheus Operator ServiceMonitor
Cert Manager Certificate
Crossplane CompositeResource

These tools extend Kubernetes without modifying Kubernetes core code.


Key Takeaways

  • Kubernetes allows extending its API using Custom Resource Definitions (CRDs).

  • A Custom Resource (CR) is an instance created by users based on the CRD schema.

  • A Custom Controller watches custom resources and performs the actual logic.

  • This architecture allows Kubernetes to remain modular, extensible, and scalable.

In simple terms:

CRD → Defines the new resource type
CR → User configuration
Controller → Executes the logic

Kubernetes Deep Dive – From Basics to Production

Part 8 of 8

A hands-on Kubernetes series covering core concepts like Pods, ReplicaSets, and Deployments, progressing toward real-world application deployments with kubectl commands, YAML examples, and practical DevOps insights.

Start from the beginning

Introduction to Kubernetes (K8s): What It Is and Why It Matters

As software systems evolve toward microservices and cloud-native architectures, the way applications are deployed and managed has fundamentally changed. Modern applications must be scalable, highly av