Working with Custom Resource Definitions
1. Understanding CRD Handling
| Method | Behavior |
|---|---|
crds/ directory | Installed once before templates; not templated, not upgraded, not deleted |
templates/ with hooks | Use pre-install/pre-upgrade + helm.sh/resource-policy: keep for upgrade support |
2. Installing CRDs with Charts
| Flag | Effect |
|---|---|
| Default | CRDs in crds/ installed automatically |
--skip-crds | Skip CRD installation (assumes pre-installed) |
3. Creating CRD Templates
Example: crds/myresource.yaml (NOT templated)
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myresources.example.com
spec:
group: example.com
scope: Namespaced
names:
plural: myresources
singular: myresource
kind: MyResource
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
4. Managing CRD Versions
| Strategy | Detail |
|---|---|
| Separate chart | Manage CRDs in a chart consumed by app charts |
| Multiple versions | storage: true on exactly one version; others served: true for compatibility |
| Conversion webhooks | Required when promoting storage version |
5. Handling CRD Upgrades
Warning: CRDs in
crds/ are NEVER upgraded by Helm. For evolving CRDs, place them in templates/ with helm.sh/resource-policy: keep and pre-upgrade hooks.| Method | Workflow |
|---|---|
| Templated CRDs | Allow updates; risk of breaking running CRs |
| Hook-managed | pre-install,pre-upgrade hook applies CRDs first |
| Manual | Apply CRDs via kubectl outside chart, install with --skip-crds |
6. Avoiding CRD Deletion on Uninstall
| Annotation | Effect |
|---|---|
helm.sh/resource-policy: keep | Retains resource on helm uninstall |
CRDs in crds/ | Always retained (Helm never deletes) |
7. Validating CRD Schemas
| Tool | Use |
|---|---|
kubeconform --strict | Validate CRs against CRD schemas |
kubectl apply --dry-run=server | Live admission validation |
| CEL validation rules | Inline schema with x-kubernetes-validations |
8. Using CRDs with Operators
Example: Operator chart layout
operator-chart/
├── Chart.yaml
├── crds/ # CRDs installed first
│ └── myresource.yaml
├── templates/
│ ├── deployment.yaml # Operator pod
│ ├── rbac.yaml
│ └── examples/ # Sample CRs (optional)
└── values.yaml
9. Testing CRD Installation
Example: Verify CRD post-install
helm install op ./chart
kubectl get crd myresources.example.com
kubectl explain MyResource.spec
10. Troubleshooting CRD Issues
| Issue | Fix |
|---|---|
| CRD missing during template install | CRDs install before templates — check timing if using webhooks |
| CRD not upgraded | Helm crds/ never updates; use kubectl apply -f crds/ manually |
| Stuck on uninstall | CRs reference CRD; delete CRs first or set finalizer policy |
| Schema validation fails | Run kubectl get crd ... -o yaml + check openAPIV3Schema |