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:
- Customize the Kubernetes API: Add resource types specific to your workflows.
- Simplify Management: Encapsulate complex configurations and automate processes.
- 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:
- Define a CRD: Describe the schema, names, and scope of your new resource type.
- Register the CRD: Apply the CRD to your cluster, which adds a new API endpoint for your custom resource.
- 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
- Declarative Schema: Define custom resource structures using OpenAPI validation.
- Scalability: Manage custom resources across namespaces or the entire cluster.
- Versioning: Support multiple versions of your resource to handle API changes over time.
- Integration with Kubernetes Tools: Work seamlessly with
kubectl
, Helm, and Kubernetes RBAC.
Use Cases for CRDs
- Application-Specific Workflows:
- Example: Define a
BlogPost
resource to manage blog publishing workflows.
- Example: Define a
- Infrastructure Management:
- Example: Use a
Database
resource to automate database provisioning.
- Example: Use a
- Kubernetes Operators:
- Example: Operators like Prometheus and Elasticsearch use CRDs to expose application-specific APIs.
- Custom Monitoring:
- Example: A
MonitoringRule
CRD to define alert rules and thresholds.
- Example: A
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.