Managing Custom Resource Definitions
1. Creating CRD
Example: Basic CRD Definition
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
schedule:
type: string
pattern: '^\S+
| Field | Description | Required |
|---|---|---|
| apiVersion | API version of the CRD, must be apiextensions.k8s.io/v1 |
Yes |
| kind | Kind of the CRD, must be CustomResourceDefinition |
Yes |
| metadata.name | Name of the CRD, e.g., crontabs.stable.example.com |
Yes |
| spec.group | API group for the CRD, e.g., stable.example.com |
Yes |
| spec.versions | List of versions supported by this CRD | Yes |
| spec.scope | Scope of the CRD, either Namespaced or Cluster |
Yes |
Note: The
spec.versions field must contain at least one version definition.Warning: CRDs must be created before any custom resources using them.
2. Listing CRDs
| Field | Description | Example |
|---|---|---|
| metadata.name | Name of the CRD | myapp.example.com |
| spec.versions | List of versions supported by this CRD | [{name: "v1", served: true, storage: true}] |
| spec.group | API group this CRD belongs to | example.com |
| spec.names.kind | Kind of the custom resource | MyApp |
3. Describing CRD Details
| Field | Description | Example |
|---|---|---|
| apiVersion | API version of the CRD | apiextensions.k8s.io/v1 |
| kind | Kind of the CRD object | CustomResourceDefinition |
| metadata.name | Name of the CRD, must follow DNS subdomain format | myapp.example.com |
| spec.versions | List of versions supported by this CRD | [{name: "v1", served: true, storage: true}] |
| spec.group | API group for the CRD | example.com |
| spec.names.kind | Kind of the custom resource | MyApp |
| spec.names.plural | Plural form of the custom resource name | myapps |
| spec.scope | Scope of the CRD - Cluster or Namespaced | Namespaced |
Example: CRD Definition
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myapps.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
scope: Namespaced
names:
plural: myapps
singular: myapp
kind: MyApp
4. Defining CRD Versions
| Version | Schema | Notes |
|---|---|---|
| apiVersion | apiextensions.k8s.io/v1 |
Latest stable version for CRD schema |
| kind | CustomResourceDefinition |
Kind of the CRD object |
| spec.versions | [] |
List of versions supported by this CRD |
| spec.versions[].name | v1 |
Version name (e.g., v1, v1beta1) |
| spec.versions[].served | true |
Indicates if this version is served by the API server |
| spec.versions[].storage | true |
Indicates if this version is the storage version |
| spec.versions[].schema.openAPIV3Schema | {} |
OpenAPI v3 schema definition for this version |
Example: Defining a CRD with multiple versions
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: mycrds.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
- name: v1beta1
served: true
storage: false
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
Note: The
storage version is used for persistence. Only one version can be the storage version.
5. Setting CRD Scope
| Scope | Description | Use Case | Notes |
|---|---|---|---|
| namespaced | CRD is scoped to a specific namespace | Isolated resources within a namespace | Default scope. Resources are deleted when namespace is deleted. |
| cluster | CRD is available across all namespaces | Global resources shared across the cluster | Cluster-wide resources. Requires cluster-admin permissions. |
Example: Namespaced CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
scope: Namespaced
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
name:
type: string
Example: Cluster-scoped CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myclusterresources.example.com
spec:
scope: Cluster
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
name:
type: string
6. Configuring Validation Schema
| Field | Type | Description | Example |
|---|---|---|---|
| openAPIV3Schema.properties | object | Defines the schema for the custom resource's spec | |
| openAPIV3Schema.required | array of strings | List of required fields in the spec | ["name"] |
| openAPIV3Schema.patternProperties | object | Allows defining patterns for property names | |
Example: Validating Custom Resource Fields
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
name:
type: string
minLength: 1
replicas:
type: integer
minimum: 0
required:
- name
Note: Validation schemas are enforced at the API server level and prevent invalid custom resource creation.
7. Using CRD Subresources
| Subresource | Description | Usage | Notes |
|---|---|---|---|
| /status | Reads and writes to the status subresource | |
Used to report the current state of a custom resource |
| /scale | Enables scaling of a custom resource | |
Requires scale in the CRD's subresources definition |
Example: Status Subresource
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
properties:
spec:
type: object
properties:
replicas:
type: integer
status:
type: object
properties:
phase:
type: string
subresources:
status: {}
Example: Scale Subresource
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
properties:
spec:
type: object
properties:
replicas:
type: integer
subresources:
scale:
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas
8. Setting Printer Columns
| Field | Description | Example |
|---|---|---|
| name | The name of the column | status |
| type | JSON type of the field (string, integer, number) | string |
| JSONPath | JSONPath expression to extract the value | .status.phase |
| description | Optional description of the column | Current phase of the pod |
Example: Printer Column Definition
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: mycrds.example.com
spec:
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
properties:
spec:
type: object
properties:
replicas:
type: integer
status:
type: string
printerColumns:
- name: Status
type: string
JSONPath: .status.phase
description: Current phase of the pod
9. Creating Custom Resources
| Field | Description | Required | Example |
|---|---|---|---|
| apiVersion | API version of the CRD | Yes | example.com/v1 |
| kind | Kind of the CRD | Yes | MyResource |
| metadata.name | Name of the CRD | Yes | myresources.example.com |
| spec.versions | List of versions supported by this CRD | Yes | [{name: "v1", served: true, storage: true}] |
| spec.names.plural | Plural form of the resource name | Yes | myresources |
| spec.names.singular | Singular form of the resource name | Yes | myresource |
| spec.names.kind | Kind of the CRD | Yes | MyResource |
| spec.scope | Scope of the CRD (Namespaced or Cluster) | Yes | Namespaced |
Example: Define a Custom Resource Definition (CRD)
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
name:
type: string
replicas:
type: integer
scope: Namespaced
names:
plural: myresources
singular: myresource
kind: MyResource
Example: Create a Custom Resource using the CRD
apiVersion: example.com/v1
kind: MyResource
metadata:
name: my-instance
spec:
name: example-app
replicas: 3
10. Understanding CRD Finalizers
| Property | Description | Values | Notes |
|---|---|---|---|
| finalizers | List of finalizers to be handled by the CRD | ["example.com/finalizer"] |
Used to ensure cleanup logic runs before deletion |
Example: CRD with Finalizer
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
name:
type: string
status:
acceptedNames:
plural: myresources
scope: Namespaced
finalizers:
- example.com/finalizer
Note: Finalizers prevent deletion of a CR instance until all finalizer logic completes.
Warning: If a finalizer is not properly removed, the CR instance will remain in
Terminating state.
11. Deleting CRDs
| Field | Description | Value |
|---|---|---|
| apiVersion | API version of the CRD | apiextensions.k8s.io/v1 |
| kind | Kind of the CRD object | CustomResourceDefinition |
| metadata.name | Name of the CRD to delete | my-crd.example.com |
Note: Deleting a CRD will also delete all instances of that CRD type in the cluster.
Warning: Ensure that all resources using this CRD are deleted before deletion to avoid data loss.
required:
- schedule
scope: Namespaced