Files
container.training/slides/k8s/dryrun.md
2020-03-31 09:09:24 -05:00

4.3 KiB

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:
    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:

    kubectl create deployment web --image=nginx -o yaml > web.yaml
    
  • Change the kind in the YAML to make it a DaemonSet:

    sed -i s/Deployment/DaemonSet/ web.yaml
    
  • Ask kubectl what would be applied:

    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

  • 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:
    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:
    kubectl diff -f web.yaml
    

]

Note: we don't need to specify --validate=false here.


Advantage of YAML

  • Using YAML (instead of kubectl create <kind>) 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 create deployment and kubectl expose

  • 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