# Custom Resource Definitions - CRDs are one of the (many) ways to extend the API - CRDs can be defined dynamically (no need to recompile or reload the API server) - A CRD is defined with a CustomResourceDefinition resource (CustomResourceDefinition is conceptually similar to a *metaclass*) --- ## Creating a CRD - We will create a CRD to represent different recipes of pizzas - We will be able to run `kubectl get pizzas` and it will list the recipes - Creating/deleting recipes won't do anything else (because we won't implement a *controller*) --- ## A bit of history Things related to Custom Resource Definitions: - Kubernetes 1.??: `apiextensions.k8s.io/v1beta1` introduced - Kubernetes 1.16: `apiextensions.k8s.io/v1` introduced - Kubernetes 1.22: `apiextensions.k8s.io/v1beta1` [removed][changes-in-122] - Kubernetes 1.25: [CEL validation rules available in beta][crd-validation-rules-beta] - Kubernetes 1.28: [validation ratcheting][validation-ratcheting] in [alpha][feature-gates] - Kubernetes 1.29: [CEL validation rules available in GA][cel-validation-rules] - Kubernetes 1.30: [validation ratcheting][validation-ratcheting] in [beta][feature-gates]; enabled by default [crd-validation-rules-beta]: https://kubernetes.io/blog/2022/09/23/crd-validation-rules-beta/ [cel-validation-rules]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules [validation-ratcheting]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/4008-crd-ratcheting [feature-gates]: https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features [changes-in-122]: https://kubernetes.io/blog/2021/07/14/upcoming-changes-in-kubernetes-1-22/ --- ## First slice of pizza ```yaml @@INCLUDE[k8s/pizza-1.yaml] ``` --- ## The joys of API deprecation - Unfortunately, the CRD manifest on the previous slide is deprecated! - It is using `apiextensions.k8s.io/v1beta1`, which is dropped in Kubernetes 1.22 - We need to use `apiextensions.k8s.io/v1`, which is a little bit more complex (a few optional things become mandatory, see [this guide](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#customresourcedefinition-v122) for details) --- ## Second slice of pizza - The next slide will show file @@LINK[k8s/pizza-2.yaml] - Note the `spec.versions` list - we need exactly one version with `storage: true` - we can have multiple versions with `served: true` - `spec.versions[].schema.openAPI3Schema` is required (and must be a valid OpenAPI schema; here it's a trivial one) --- ```yaml @@INCLUDE[k8s/pizza-2.yaml] ``` --- ## Baking some pizza - Let's create the Custom Resource Definition for our Pizza resource .lab[ - Load the CRD: ```bash kubectl apply -f ~/container.training/k8s/pizza-2.yaml ``` - Confirm that it shows up: ```bash kubectl get crds ``` ] --- ## Creating custom resources The YAML below defines a resource using the CRD that we just created: ```yaml kind: Pizza apiVersion: container.training/v1alpha1 metadata: name: hawaiian spec: toppings: [ cheese, ham, pineapple ] ``` .lab[ - Try to create a few pizza recipes: ```bash kubectl apply -f ~/container.training/k8s/pizzas.yaml ``` ] --- ## Type validation - Recent versions of Kubernetes will issue errors about unknown fields - We need to improve our OpenAPI schema (to add e.g. the `spec.toppings` field used by our pizza resources) --- ## Creating a bland pizza - Let's try to create a pizza anyway! .lab[ - Only provide the most basic YAML manifest: ```bash kubectl create -f- < (e.g. major version downgrades) - checking a key or certificate format or validity - and much more! --- ## CRDs in the wild - [gitkube](https://storage.googleapis.com/gitkube/gitkube-setup-stable.yaml) - [A redis operator](https://github.com/amaizfinance/redis-operator/blob/master/deploy/crds/k8s_v1alpha1_redis_crd.yaml) - [cert-manager](https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager.yaml) *How big are these YAML files?* *What's the size (e.g. in lines) of each resource?* --- ## CRDs in practice - Production-grade CRDs can be extremely verbose (because of the openAPI schema validation) - This can (and usually will) be managed by a framework --- ## (Ab)using the API server - If we need to store something "safely" (as in: in etcd), we can use CRDs - This gives us primitives to read/write/list objects (and optionally validate them) - The Kubernetes API server can run on its own (without the scheduler, controller manager, and kubelets) - By loading CRDs, we can have it manage totally different objects (unrelated to containers, clusters, etc.) --- ## What's next? - Creating a basic CRD is relatively straightforward - But CRDs generally require a *controller* to do anything useful - The controller will typically *watch* our custom resources (and take action when they are created/updated) - Most serious use-cases will also require *validation web hooks* - When our CRD data format evolves, we'll also need *conversion web hooks* - Doing all that work manually is tedious; use a framework! ??? :EN:- Custom Resource Definitions (CRDs) :FR:- Les CRDs *(Custom Resource Definitions)*