CKAD — Creating CRDs
Custom Resource Definitions (CRDs)
A CRD tells the Kubernetes API server about a new resource type. Once you create a CRD, you can create instances of that resource using kubectl.
Creating a Basic CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: backups.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
database:
type: string
schedule:
type: string
retentionDays:
type: integer
required:
- database
- schedule
scope: Namespaced
names:
plural: backups
singular: backup
kind: Backup
shortNames:
- bk
kubectl apply -f backup-crd.yaml
# Expected: customresourcedefinition.apiextensions.k8s.io/backups.stable.example.com created
# Verify the CRD exists
kubectl get crd backups.stable.example.com
CRD Field Reference
| Field | Description |
|---|---|
spec.group |
API group (e.g., stable.example.com) |
spec.versions |
List of versions with schemas |
spec.versions[].served |
Whether this version is served by the API |
spec.versions[].storage |
Which version is used for storage (only one) |
spec.scope |
Namespaced or Cluster |
spec.names.plural |
Plural name for the URL (e.g., /apis/group/v1/backups) |
spec.names.singular |
Singular name for display |
spec.names.kind |
Resource kind in YAML |
spec.names.shortNames |
Short aliases for kubectl |
Schema Validation
The openAPIV3Schema section validates custom resources. If someone creates a resource that does not match the schema, the API server rejects it.
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
minimum: 1
maximum: 10
image:
type: string
pattern: '^[\w.-]+/[\w.-]+:[\w.-]+$'
environment:
type: string
enum:
- development
- staging
- production
required:
- replicas
- image
Supported validations:
type— string, integer, boolean, array, objectrequired— list of required fieldsminimum/maximum— numeric rangesminLength/maxLength— string lengthsenum— allowed valuespattern— regex pattern
Adding Printer Columns
By default kubectl get only shows name and age. Add columns using additionalPrinterColumns:
versions:
- name: v1
served: true
storage: true
additionalPrinterColumns:
- name: Database
type: string
jsonPath: .spec.database
- name: Schedule
type: string
jsonPath: .spec.schedule
- name: Retention
type: integer
jsonPath: .spec.retentionDays
- name: Age
type: date
jsonPath: .metadata.creationTimestamp
schema:
openAPIV3Schema:
# ... schema here
kubectl get backups
# Expected:
# NAME DATABASE SCHEDULE RETENTION AGE
# daily-db-backup postgres-main 0 2 * * * 30 1m
Next: Custom Resources →