From f96da2d260e54c2e16a2397ea042cca4a38fe54d Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Sun, 6 Oct 2019 09:24:30 -0500 Subject: [PATCH] Add dry-run, server-dry-run, kubectl diff Closes #523. --- slides/k8s/dryrun.md | 209 ++++++++++++++++++++++++++++++++++++++ slides/kube-fullday.yml | 1 + slides/kube-selfpaced.yml | 1 + slides/kube-twodays.yml | 1 + 4 files changed, 212 insertions(+) create mode 100644 slides/k8s/dryrun.md diff --git a/slides/k8s/dryrun.md b/slides/k8s/dryrun.md new file mode 100644 index 00000000..f319c8b6 --- /dev/null +++ b/slides/k8s/dryrun.md @@ -0,0 +1,209 @@ +# Authoring YAML + +- There are various ways to generate YAML with Kubernetes, e.g.: + + - `kubectl run` + + - `kubectl create deployment` (and a few other `kubectl create` variants) + + - `kubectl expose` + +- When and why do we need to write our own YAML? + +- How do we write YAML from scratch? + +--- + +## The limits of generated YAML + +- Many advanced (and even not-so-advanced) features require to write YAML: + + - pods with multiple containers + + - resource limits + + - healthchecks + + - DaemonSets, StatefulSets + + - and more! + +- How do we access these features? + +--- + +## We don't have to start from scratch + +- Create a resource (e.g. Deployment) + +- Dump its YAML with `kubectl get -o yaml ...` + +- Edit the YAML + +- Use `kubectl apply -f ...` with the YAML file to: + + - update the resource (if it's the same kind) + + - create a new resource (if it's a different kind) + +- Or: Use The Docs, Luke + + (the documentation almost always has YAML examples) + +--- + +## Generating YAML without creating resources + +- We can use the `--dry-run` option + +.exercise[ + +- Generate the YAML for a Deployment without creating it: + ```bash + kubectl create deployment web --image nginx --dry-run + ``` + +] + +- We can clean up that YAML even more if we want + + (for instance, we can remove the `creationTimestamp` and empty dicts) + +--- + +## Using `--dry-run` with `kubectl apply` + +- The `--dry-run` option can also be used with `kubectl apply` + +- However, it can be misleading (it doesn't do a "real" dry run) + +- Let's see what happens in the following scenario: + + - generate the YAML for a Deployment + + - tweak the YAML to transform it into a DaemonSet + + - apply that YAML to see what would actually be created + +--- + +## The limits of `kubectl apply --dry-run` + +.exercise[ + +- Generate the YAML for a deployment: + ```bash + kubectl create deployment web --image=nginx -o yaml > web.yaml + ``` + +- Change the `kind` in the YAML to make it a `DaemonSet`: + ```bash + sed -i s/Deployment/DaemonSet/ web.yaml + ``` + +- Ask `kubectl` what would be applied: + ```bash + kubectl apply -f web.yaml --dry-run --validate=false -o yaml + ``` + +] + +The resulting YAML doesn't represent a valid DaemonSet. + +--- + +## Server-side dry run + +- Since Kubernetes 1.13, we can use [server-side dry run and diffs](https://kubernetes.io/blog/2019/01/14/apiserver-dry-run-and-kubectl-diff/) + +- Server-side dry run will do all the work, but *not* persist to etcd + + (all validation and mutation hooks will be executed) + +.exercise[ + +- Try the same YAML file as earlier, with server-side dry run: + ```bash + kubectl apply -f web.yaml --server-dry-run --validate=false -o yaml + ``` + +] + +The resulting YAML doesn't have the `replicas` field anymore. + +Instead, it has the fields expected in a DaemonSet. + +--- + +## Advantages of server-side dry run + +- The YAML is verified much more extensively + +- The only step that is skipped is "write to etcd" + +- YAML that passes server-side dry run *should* apply successfully + + (unless the cluster state changes by the time the YAML is actually applied) + +- Validating or mutating hooks that have side effects can also be an issue + +--- + +## `kubectl diff` + +- Kubernetes 1.13 also introduced `kubectl diff` + +- `kubectl diff` does a server-side dry run, *and* shows differences + +.exercise[ + +- Try `kubectl diff` on the YAML that we tweaked earlier: + ```bash + kubectl diff -f web.yaml + ``` + +] + +Note: we don't need to specify `--validate=false` here. + +--- + +## Advantage of YAML + +- Using YAML (instead of `kubectl run`/`create`/etc.) allows to be *declarative* + +- The YAML describes the desired state of our cluster and applications + +- YAML can be stored, versioned, archived (e.g. in git repositories) + +- To change resources, change the YAML files + + (instead of using `kubectl edit`/`scale`/`label`/etc.) + +- Changes can be reviewed before being applied + + (with code reviews, pull requests ...) + +- This workflow is sometimes called "GitOps" + + (there are tools like Weave Flux or GitKube to facilitate it) + +--- + +## YAML in practice + +- Get started with `kubectl run`/`create`/`expose`/etc. + +- Dump the YAML with `kubectl get -o yaml` + +- Tweak that YAML and `kubectl apply` it back + +- Store that YAML for reference (for further deployments) + +- Feel free to clean up the YAML: + + - remove fields you don't know + + - check that it still works! + +- That YAML will be useful later when using e.g. Kustomize or Helm diff --git a/slides/kube-fullday.yml b/slides/kube-fullday.yml index 3631fc96..35574248 100644 --- a/slides/kube-fullday.yml +++ b/slides/kube-fullday.yml @@ -52,6 +52,7 @@ chapters: - k8s/scalingdockercoins.md - shared/hastyconclusions.md - k8s/daemonset.md + #- k8s/dryrun.md - k8s/rollout.md #- k8s/healthchecks.md #- k8s/healthchecks-more.md diff --git a/slides/kube-selfpaced.yml b/slides/kube-selfpaced.yml index f2647377..9a21f941 100644 --- a/slides/kube-selfpaced.yml +++ b/slides/kube-selfpaced.yml @@ -52,6 +52,7 @@ chapters: - k8s/scalingdockercoins.md - shared/hastyconclusions.md - k8s/daemonset.md + - k8s/dryrun.md - - k8s/rollout.md - k8s/healthchecks.md diff --git a/slides/kube-twodays.yml b/slides/kube-twodays.yml index b1d93be5..eb976900 100644 --- a/slides/kube-twodays.yml +++ b/slides/kube-twodays.yml @@ -53,6 +53,7 @@ chapters: - shared/hastyconclusions.md - k8s/daemonset.md - + - k8s/dryrun.md - k8s/rollout.md - k8s/healthchecks.md - k8s/healthchecks-more.md