CKAD — CRDs & Operators Lab
Lab 1: Create a CRD and Custom Resources
# Create a CRD for a "Website" resource
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: websites.apps.example.com
spec:
group: apps.example.com
versions:
- name: v1
served: true
storage: true
additionalPrinterColumns:
- name: URL
type: string
jsonPath: .spec.url
- name: Replicas
type: integer
jsonPath: .spec.replicas
- name: Age
type: date
jsonPath: .metadata.creationTimestamp
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
url:
type: string
replicas:
type: integer
minimum: 1
maximum: 5
image:
type: string
required:
- url
- replicas
scope: Namespaced
names:
plural: websites
singular: website
kind: Website
shortNames:
- ws
EOF
# Verify the CRD
kubectl get crd websites.apps.example.com
# Expected: CRD exists
# Create a Website resource
cat <<EOF | kubectl apply -f -
apiVersion: apps.example.com/v1
kind: Website
metadata:
name: my-blog
spec:
url: https://example.com
replicas: 3
image: nginx:1.27
EOF
# List websites
kubectl get websites
# Expected:
# NAME URL REPLICAS AGE
# my-blog https://example.com 3 5s
# Use the short name
kubectl get ws
# Try creating an invalid resource (replicas > 5)
cat <<EOF | kubectl apply -f -
apiVersion: apps.example.com/v1
kind: Website
metadata:
name: invalid-site
spec:
url: https://bad.com
replicas: 100
EOF
# Expected: Error — spec.replicas must be <= 5
Lab 2: Explore Existing CRDs
# List all CRDs in the cluster
kubectl get crd
# Pick a CRD and explore it
kubectl describe crd <crd-name>
# List instances of that custom resource
kubectl get <resource-plural-name>
# Check the schema
kubectl explain <resource-kind>
Practice Questions
Q1: What is a CRD and how does it differ from a built-in resource?
Show Answer
A Custom Resource Definition (CRD) extends the Kubernetes API with a new resource type. After creating a CRD, you can use kubectl to create, get, update, and delete instances of that resource just like built-in resources. The difference is that built-in resources (Pods, Deployments, Services) come with Kubernetes and have built-in controllers. CRDs define only the data structure — they need a separate controller (Operator) to act on the resources.Q2: Create a CRD for a resource called “Database” in the group db.example.com with fields: engine (string, required), version (string), and replicas (integer, minimum 1).
Show Answer
```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: databases.db.example.com spec: group: db.example.com versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: engine: type: string version: type: string replicas: type: integer minimum: 1 required: - engine scope: Namespaced names: plural: databases singular: database kind: Database shortNames: - db ```Q3: What happens when you delete a CRD?
Show Answer
When you delete a CRD, **all custom resources of that type are also deleted**. This is a cascading delete. For example, if you delete the `backups.stable.example.com` CRD, all Backup resources are permanently removed from the cluster. Always be careful when deleting CRDs in production.Q4: What is the difference between an Operator and a CRD?
Show Answer
A **CRD** defines a new resource type — it is just the data schema. It tells the API server "this kind of object exists and its fields look like this." An **Operator** is a controller that watches CRDs and takes action. It contains the business logic — creating Pods, Services, or other resources based on the custom resource spec. Together: CRD = the "what" (desired state), Operator = the "how" (reconciliation logic).Q5: How do you check if a custom resource type exists in the cluster and list its instances?