mirror of
https://github.com/jpetazzo/container.training.git
synced 2026-05-06 00:46:56 +00:00
Update CRD section
This commit is contained in:
@@ -187,7 +187,7 @@ Save this script as `/opt/cni/bin/debug` and make it executable.
|
||||
|
||||
❓️ What is calling our plugins?
|
||||
|
||||
---
|
||||
???
|
||||
|
||||
:EN:- Deep dive into CNI internals
|
||||
:FR:- La Container Network Interface (CNI) en détails
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
|
||||
## A very simple CRD
|
||||
|
||||
The YAML below describes a very simple CRD representing different kinds of coffee:
|
||||
|
||||
@@LINK[k8s/coffee-1.yaml]
|
||||
The file @@LINK[k8s/coffee-1.yaml] describes a very simple CRD representing different kinds of coffee:
|
||||
|
||||
```yaml
|
||||
@@INCLUDE[k8s/coffee-1.yaml]
|
||||
@@ -81,7 +79,7 @@ spec:
|
||||
|
||||
]
|
||||
|
||||
- We can improve that, but it's outside the scope of this section!
|
||||
- We'll see in a bit how to improve that
|
||||
|
||||
---
|
||||
|
||||
@@ -108,16 +106,180 @@ There are many possibilities!
|
||||
|
||||
---
|
||||
|
||||
## Little details
|
||||
## What's next?
|
||||
|
||||
- Creating a basic CRD is quick and easy
|
||||
|
||||
- But there is a lot more that we can (and probably should) do:
|
||||
|
||||
- improve input with *data validation*
|
||||
|
||||
- improve output with *custom columns*
|
||||
|
||||
- And of course, we probably need a *controller* to go with our CRD!
|
||||
|
||||
(otherwise, we're just using the Kubernetes API as a fancy data store)
|
||||
|
||||
---
|
||||
|
||||
## Additional printer columns
|
||||
|
||||
- We can specify `additionalPrinterColumns` in the CRD
|
||||
|
||||
- This is similar to `-o custom-columns`
|
||||
|
||||
(map a column name to a path in the object, e.g. `.spec.taste`)
|
||||
|
||||
```yaml
|
||||
additionalPrinterColumns:
|
||||
- jsonPath: .spec.taste
|
||||
description: Subjective taste of that kind of coffee bean
|
||||
name: Taste
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Using additional printer columns
|
||||
|
||||
- Let's update our CRD using @@LINK[k8s/coffee-3.yaml]
|
||||
|
||||
.exercise[
|
||||
|
||||
- Update the CRD:
|
||||
```bash
|
||||
kubectl apply -f ~/container.training/k8s/coffee-3.yaml
|
||||
```
|
||||
|
||||
- Look at our Coffee resources:
|
||||
```bash
|
||||
kubectl get coffees
|
||||
```
|
||||
|
||||
]
|
||||
|
||||
Note: we can update a CRD without having to re-create the corresponding resources.
|
||||
|
||||
(Good news, right?)
|
||||
|
||||
---
|
||||
|
||||
## Data validation
|
||||
|
||||
- By default, CRDs are not *validated*
|
||||
|
||||
(we can put anything we want in the `spec`)
|
||||
|
||||
- When creating a CRD, we can pass an OpenAPI v3 schema (BETA!)
|
||||
- When creating a CRD, we can pass an OpenAPI v3 schema
|
||||
|
||||
(which will then be used to validate resources)
|
||||
|
||||
- More advanced validation can also be done with admission webhooks, e.g.:
|
||||
|
||||
- consistency between parameters
|
||||
|
||||
- advanced integer filters (e.g. odd number of replicas)
|
||||
|
||||
- things that can change in one direction but not the other
|
||||
|
||||
---
|
||||
|
||||
## OpenAPI v3 scheme exapmle
|
||||
|
||||
This is what we have in @@INC[k8s/coffee-3.yaml]:
|
||||
|
||||
```yaml
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
required: [ spec ]
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
taste:
|
||||
description: Subjective taste of that kind of coffee bean
|
||||
type: string
|
||||
required: [ taste ]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation *a posteriori*
|
||||
|
||||
- Some of the "coffees" that we defined earlier *do not* pass validation
|
||||
|
||||
- How is that possible?
|
||||
|
||||
--
|
||||
|
||||
- Validation happens at *admission*
|
||||
|
||||
(when resources get written into the database)
|
||||
|
||||
- Therefore, we can have "invalid" resources in etcd
|
||||
|
||||
(they are invalid from the CRD perspective, but the CRD can be changed)
|
||||
|
||||
🤔 How should we handle that ?
|
||||
|
||||
---
|
||||
|
||||
## Versions
|
||||
|
||||
- If the data format changes, we can roll out a new version of the CRD
|
||||
|
||||
(e.g. go from `v1alpha1` to `v1alpha2`)
|
||||
|
||||
- In a CRD we can specify the versions that exist, that are *served*, and *stored*
|
||||
|
||||
- multiple versions can be *served*
|
||||
|
||||
- only one can be *stored*
|
||||
|
||||
- Kubernetes doesn't automatically migrate the content of the database
|
||||
|
||||
- However, it can convert between versions when resources are read/written
|
||||
|
||||
---
|
||||
|
||||
## Conversion
|
||||
|
||||
- When *creating* a new resource, the *stored* version is used
|
||||
|
||||
(if we create it with another version, it gets converted)
|
||||
|
||||
- When *getting* or *watching* resources, the *requested* version is used
|
||||
|
||||
(if it is stored with another version, it gets converted)
|
||||
|
||||
- By default, "conversion" only changes the `apiVersion` field
|
||||
|
||||
- ... But we can register *conversion webhooks*
|
||||
|
||||
(see [that doc page](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion) for details)
|
||||
|
||||
---
|
||||
|
||||
## Migrating database content
|
||||
|
||||
- We need to *serve* a version as long as we *store* objects in that version
|
||||
|
||||
(=as long as the database has at least one object with that version)
|
||||
|
||||
- If we want to "retire" a version, we need to migrate these objects first
|
||||
|
||||
- All we have to do is to read and re-write them
|
||||
|
||||
(the [kube-storage-version-migrator](https://github.com/kubernetes-sigs/kube-storage-version-migrator) tool can help)
|
||||
|
||||
---
|
||||
|
||||
## What's next?
|
||||
|
||||
- Generally, when creating a CRD, we also want to run a *controller*
|
||||
|
||||
(otherwise nothing will happen when we create resources of that type)
|
||||
@@ -126,11 +288,29 @@ There are many possibilities!
|
||||
|
||||
(and take action when they are created/updated)
|
||||
|
||||
*
|
||||
Examples:
|
||||
[YAML to install the gitkube CRD](https://storage.googleapis.com/gitkube/gitkube-setup-stable.yaml),
|
||||
[YAML to install a redis operator CRD](https://github.com/amaizfinance/redis-operator/blob/master/deploy/crds/k8s_v1alpha1_redis_crd.yaml)
|
||||
*
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user