Working with Custom Resource Definitions
1. Understanding CRD Handling
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: '^[0-9/ *,-]+
| Property | Description | Values |
|---|---|---|
| apiVersion | API version of the CRD | apiextensions.k8s.io/v1 |
| kind | Kind of the CRD object | CustomResourceDefinition |
| metadata.name | Unique name for the CRD | crontabs.stable.example.com |
| spec.group | API group for the CRD | stable.example.com |
| spec.versions.name | Name of the version | v1 |
| spec.scope | Scope of the CRD (Namespaced or Cluster) | Namespaced, Cluster |
| spec.names.plural | Plural form of the resource name | crontabs |
| spec.names.singular | Singular form of the resource name | crontab |
| spec.names.kind | Kind of the CRD | CronTab |
Note: Helm charts can reference CRDs via
crd templates in the templates/ directory.CRD Handling in Helm Charts
- Helm charts can define CRDs using
crdtemplates in thetemplates/directory. - CRDs are installed before any chart resources that depend on them.
- CRDs can be defined in
crds/directory and referenced viacrdtemplates. - CRDs are not managed by Helm's release lifecycle, but can be updated via chart upgrades.
2. Installing CRDs with Charts
| Field | Description | Example |
|---|---|---|
| crds | Directory containing CRD definitions | crds/ |
| install | Whether to install CRDs during chart installation | true |
Example: CRD Installation in Chart
apiVersion: v2
name: my-app
version: 1.0.0
...
crds:
- crds/my-crd.yaml
Note: CRDs must be installed before resources using them.
Warning: Helm does not manage CRD updates after initial install.
3. Creating CRD Templates
| Property | Value | Description |
|---|---|---|
| apiVersion | apiextensions.k8s.io/v1 |
API version of the CRD resource |
| kind | CustomResourceDefinition |
Kind of the CRD resource |
| metadata.name | my-crd.example.com |
Name of the CRD, must follow DNS subdomain format |
| spec.versions.name | v1 |
Name of the version, used in API calls |
| spec.versions.schema.openAPIV3Schema.properties.spec | object |
Schema definition for the spec field of the custom resource |
Example: Basic CRD Template
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: my-crd.example.com
spec:
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
minimum: 0
Note: The
openAPIV3Schema is required for validation and must be a valid OpenAPI v3 schema.
Warning: CRDs must be installed before any custom resources using them can be created.
4. Managing CRD Versions
| Version | Schema Changes | Notes |
|---|---|---|
| v1 | spec.versions array with served and storage flags |
Latest stable version with full backward compatibility support |
| v1beta1 | Legacy version with spec.version field |
DEPRECATED in Kubernetes 1.16+, removed in 1.22+ |
Example: CRD v1 Schema 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
served: true
storage: true
Note: When migrating from
v1beta1 to v1, ensure all spec.version fields are updated to spec.versions array format.
Warning: CRDs using
v1beta1 will not be supported in Kubernetes 1.22+. Migrate to v1 schema before upgrading.
5. Handling CRD Upgrades
| Upgrade Type | Description | Notes |
|---|---|---|
| Major Version Upgrade | Changing from v1 to v2, or any non-backward-compatible change | Requires manual intervention and careful migration planning |
| Minor Version Upgrade | Adding new fields or updating existing ones with backward compatibility | Can be handled automatically by Helm if using proper schema validation |
| Patch Version Upgrade | Fixes or minor updates without changing structure | Generally safe to upgrade without additional steps |
Example: Upgrading CRD with New Field
# Before upgrade
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:
name:
type: string
# After upgrade
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:
name:
type: string
description:
type: string
Note: Helm does not automatically update CRDs in the cluster. You must manually apply updated CRD definitions or use
helm upgrade --set crds=true to ensure CRDs are updated.
CRD Upgrade Workflow
- Review the changes in the new CRD version
- Update your Helm chart's CRD template to match the new schema
- Run
helm upgrade --set crds=trueto apply the updated CRD - Verify that existing CRs still validate against the new schema
- Update any dependent resources or controllers to handle new fields if needed
CRD Upgrade Approaches
- Manual Update: Apply CRD YAML directly using
kubectl apply - Helm Managed: Include CRD in chart and use
--set crds=true - Operator-Based: Use an operator to manage CRD lifecycle and upgrades
6. Avoiding CRD Deletion on Uninstall
Example: Preventing CRD Deletion
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: mycrds.example.com
annotations:
helm.sh/resource-policy: keep
spec:
group: example.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
| Annotation | Value | Description |
|---|---|---|
| helm.sh/resource-policy | keep |
Prevents Helm from deleting the CRD during uninstall |
Note: The
helm.sh/resource-policy annotation must be set on the CRD's metadata to prevent deletion during helm uninstall.Warning: If a CRD is deleted while resources exist, those resources become orphaned and inaccessible.
7. Validating CRD Schemas
Example: Basic CRD Schema Validation
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: prometheuses.monitoring.coreos.com
spec:
group: monitoring.coreos.com
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
required:
- resources
properties:
resources:
type: array
items:
type: object
required:
- name
properties:
name:
type: string
pattern: "^[a-zA-Z][a-zA-Z0-9-]*$"
port:
type: integer
minimum: 1
maximum: 65535
additionalProperties: false
additionalProperties: false
| Field | Description | Validation Rules |
|---|---|---|
| spec.versions.schema.openAPIV3Schema | OpenAPI v3 schema for validating CR instances | Must be a valid OpenAPI v3 schema object |
| properties.name.pattern | Regex pattern for resource name validation | Must match ^[a-zA-Z][a-zA-Z0-9-]*$ |
| properties.port.minimum | Minimum allowed port value | Must be >= 1 |
| properties.port.maximum | Maximum allowed port value | Must be <= 65535 |
Note: The
openAPIV3Schema field uses the OpenAPI v3 schema format to define validation rules for Custom Resources. It supports all standard OpenAPI validation keywords like pattern, minimum, and maximum.Warning: Invalid schema definitions will cause CRD creation to fail. Always validate schemas before applying them to the cluster.
8. Using CRDs with Operators
Custom Resource Definitions (CRDs) are often used in conjunction with Kubernetes Operators to extend the Kubernetes API and automate operations for custom resources.
| Component | Description | Usage |
|---|---|---|
| CRD | Defines a new custom resource type in the Kubernetes API | Used to create custom resources that extend Kubernetes functionality |
| Operator | Controller that manages custom resources defined by CRDs | Automates deployment, scaling, and management of custom resources |
Example: Operator Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-operator
spec:
replicas: 1
selector:
matchLabels:
app: my-operator
template:
metadata:
labels:
app: my-operator
spec:
containers:
- name: operator
image: my-operator-image
Example: CRD Definition
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:
replicas:
type: integer
Note: Operators use CRDs to define custom resources and implement controllers that watch for changes to these resources.
Key Concepts
- CRDs define custom resource types that extend Kubernetes API
- Operators manage custom resources using controllers
- CRDs and Operators work together to automate complex operations
9. Testing CRD Installation
| Command | Description | Output |
|---|---|---|
| kubectl get crd | Lists all installed CRDs | Displays CRD names and versions |
| kubectl describe crd <name> | Shows detailed CRD information | Includes spec, status, and validation rules |
Note: Ensure the CRD is fully registered before deploying resources that use it.
Example: Validate CRD with Sample Resource
apiVersion: example.com/v1
kind: MyCustomResource
metadata:
name: test-resource
spec:
replicas: 2
Testing Workflow
- Create a test CRD using
kubectl apply - Verify CRD status with
kubectl get crd - Apply a sample custom resource using the CRD
- Check that the resource is created successfully
10. Troubleshooting CRD Issues
Example: Invalid CRD Schema
{
"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": {
"invalidField": {
"type": "string"
}
},
"required": ["invalidField"]
}
}
}
}
}
]
}
}
| Issue | Description | Solution |
|---|---|---|
| Invalid Schema | CRD schema does not conform to OpenAPI v3 spec | Validate using helm template or kubectl apply --dry-run=client |
| Missing Required Fields | CRD schema defines required fields that aren't present in instances | Add missing fields to CR instances or update CRD schema |
| Version Mismatch | CRD version used in chart doesn't match installed CRD | Ensure CRD versions align between chart and cluster |
Note: Use
kubectl get crd <crd-name> -o yaml to inspect CRD schema and status.Warning: Modifying CRDs after resources exist can lead to data loss or unexpected behavior.
Common CRD Troubleshooting Steps
- Check CRD status with
kubectl describe crd <name> - Validate CRD schema using
kubectl apply --dry-run=client - Ensure CR instances match the defined schema
- Verify Helm chart and installed CRD versions are compatible