Kubernetes Custom Resources Explained: CRD, CR, and Custom Controllers
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:
The API Server validates the YAML
The resource is stored in etcd
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:
VirtualServiceis the custom resourceIt 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:
Watch resource changes (create/update/delete)
Add events to a worker queue
Process each event
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