Certified Kubernetes Application Developer - CKAD
Security
Custom Resource Definition
In this lesson, we explore how Custom Resource Definitions (CRDs) work in Kubernetes. You will learn how standard Kubernetes resources, such as Deployments, are created, stored in etcd, and managed by built-in controllers. Then, we’ll demonstrate how to extend Kubernetes by defining and using a custom resource—illustrated here as a "FlightTicket"—and explain why a dedicated custom controller is necessary to act upon these new resources.
Standard Kubernetes Resource: Deployment
When you create a Deployment in Kubernetes, the API server stores its state in etcd. A built-in controller, known as the deployment controller, continuously monitors the Deployment to ensure that the desired state (for example, maintaining three replicas) is met by creating or deleting pods as needed.
Below is an example Deployment definition file:
# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
type: front-end
template:
metadata:
name: myapp-pod
labels:
type: front-end
spec:
containers:
- image: nginx
Using the file above, you can create, query, and delete the deployment with the following commands:
kubectl create -f deployment.yml
# Output:
kubectl get deployments
# Output:
# NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kubectl delete -f deployment.yml
# Output:
# deployment "myapp-deployment" deleted
The deployment controller automatically creates a ReplicaSet, which manages the specified number of pods. This automation lies at the heart of Kubernetes resource management.
Custom Resource: FlightTicket
Imagine you want to manage something entirely new on your cluster—such as booking a flight ticket. In this example, we define a custom resource called FlightTicket that represents a flight ticket booking. The resource encapsulates details such as the departure and destination airports and the number of tickets required.
Below is an example of a FlightTicket resource file:
# flightticket.yml
apiVersion: flights.com/v1
kind: FlightTicket
metadata:
name: my-flight-ticket
spec:
from: Mumbai
to: London
number: 2
When you create this custom resource, you expect that:
- It is stored in etcd.
- A custom controller (which you will build) watches for create, update, or delete events.
- The controller automatically makes the necessary API calls (for example, to an external flight booking API) to either book or cancel the ticket.
Important
Attempting to create the FlightTicket resource without first informing Kubernetes of its existence will result in an error:
kubectl create -f flightticket.yml
# Output:
# no matches for kind "FlightTicket" in version "flights.com/v1"
This error means that Kubernetes does not yet recognize the FlightTicket type.
Defining a Custom Resource Definition (CRD)
To allow the Kubernetes API to accept FlightTicket objects, you must create a CRD that informs the API server about this new resource type. The CRD includes details such as API version, kind, metadata, spec, and schema information (including supported fields, types, and validation rules).
Here’s an example of a CRD for the FlightTicket resource:
# flightticket-custom-definition.yml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: flighttickets.flights.com
spec:
group: flights.com
scope: Namespaced
names:
plural: flighttickets
singular: flightticket
kind: FlightTicket
shortNames:
- ft
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
from:
type: string
to:
type: string
number:
type: integer
minimum: 1
Key points in the CRD:
- The API group is
flights.com
. - The resource scope is namespace-scoped.
- Both singular and plural names are defined along with a short name (
ft
). - Only one version (
v1
) is served and defined as the storage version. - An OpenAPI v3 schema enforces that the
spec
includesfrom
andto
as strings, andnumber
as an integer with a minimum value of 1.
After creating the CRD, you can create, retrieve, and delete FlightTicket resources using these commands:
kubectl create -f flightticket-custom-definition.yml
# Output:
kubectl create -f flightticket.yml
# Output:
kubectl get flightticket
# Output:
# NAME STATUS
kubectl delete -f flightticket.yml
# Output:
# flightticket "my-flight-ticket" deleted
To verify that your new resource is recognized by Kubernetes, run:
kubectl api-resources
# Output snippet:
# NAME SHORTNAMES APIGROUP NAMESPACED KIND
# flighttickets ft flights.com true FlightTicket
The Role of a Custom Controller
While defining a CRD enables Kubernetes to store and retrieve FlightTicket objects in etcd, these objects remain inactive without a controller. A custom controller, often implemented in Go, observes events related to FlightTicket resources and executes business logic (such as calling external APIs to book or cancel flights).
Below is a simplified snippet of what such a controller might look like:
package flightticket
var controllerKind = apps.SchemeGroupVersion.WithKind("FlightTicket")
// Run begins watching and syncing FlightTicket resources.
func (dc *FlightTicketController) Run(workers int, stopCh <-chan struct{}) {
// Controller logic goes here
}
// callBookFlightAPI handles the API call to book a flight ticket.
func (dc *FlightTicketController) callBookFlightAPI(obj interface{}) {
// API call implementation goes here
}
Note
Without a custom controller, any FlightTicket resource you create remains a passive data record in etcd without triggering any external actions.
Conclusion
In this lesson, we learned how:
- Kubernetes resources like Deployments are managed by built-in controllers.
- A custom resource (FlightTicket) can be defined to represent a new domain object.
- A CRD must be created so that Kubernetes recognizes your custom resource.
- A custom controller is essential to actively process and respond to events related to these resources.
In upcoming lessons, we’ll dive deeper into developing custom controllers that monitor CRD events and execute automated tasks based on resource changes.
Watch Video
Watch video content
Practice Lab
Practice lab