Managing Custom Resource Definitions

1. Creating CRD

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata: { name: widgets.example.com }
spec:
  group: example.com
  scope: Namespaced
  names: { plural: widgets, singular: widget, kind: Widget, shortNames: [wd] }
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            required: [size]
            properties:
              size: { type: integer, minimum: 1, maximum: 10 }
              color: { type: string, enum: [red, green, blue] }
    subresources: { status: {} }

2. Listing CRDs

kubectl get crd
kubectl api-resources --api-group=example.com

3. Describing CRD Details

FieldInfo
EstablishedDiscovery API serves it
NamesAcceptedNames not conflicting

4. Defining CRD Versions

FieldEffect
servedVersion reachable via API
storageExactly one storage version
deprecatedWarn on use
conversionNone / Webhook (for multi-version)

5. Setting CRD Scope

scopeDetail
NamespacedCR lives in a namespace
ClusterCluster-wide (e.g., ClusterIssuer)

6. Configuring Validation Schema

OpenAPI FeatureUse
requiredMandatory fields
enum / patternConstrain values
x-kubernetes-validationsCEL rules (1.28+ stable)
x-kubernetes-preserve-unknown-fieldsAllow extra fields

7. Using CRD Subresources

subresources:
  status: {}
  scale:
    specReplicasPath: .spec.replicas
    statusReplicasPath: .status.replicas
    labelSelectorPath: .status.labelSelector

8. Setting Printer Columns

additionalPrinterColumns:
- { name: Size, type: integer, jsonPath: .spec.size }
- { name: Ready, type: string, jsonPath: .status.conditions[?(@.type=="Ready")].status }
- { name: Age, type: date, jsonPath: .metadata.creationTimestamp }

9. Creating Custom Resources

apiVersion: example.com/v1
kind: Widget
metadata: { name: my-widget }
spec: { size: 5, color: blue }

10. Understanding CRD Finalizers

BehaviorDetail
Block deleteObject stuck in Terminating until finalizer removed
Force deletekubectl patch ... -p '{"metadata":{"finalizers":[]}}' --type=merge

11. Deleting CRDs

kubectl delete crd widgets.example.com
Warning: Deleting a CRD removes ALL custom resources of that kind cluster-wide.