diff --git a/k8s/efk.yaml b/k8s/efk.yaml index 48d6c1ce..f2c9ea84 100644 --- a/k8s/efk.yaml +++ b/k8s/efk.yaml @@ -32,13 +32,16 @@ subjects: name: fluentd namespace: default --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd labels: app: fluentd spec: + selector: + matchLabels: + app: fluentd template: metadata: labels: @@ -86,7 +89,7 @@ spec: hostPath: path: /var/lib/docker/containers --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: labels: @@ -128,7 +131,7 @@ spec: app: elasticsearch type: ClusterIP --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: labels: diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml index 09445e1e..a40f3dff 100644 --- a/k8s/ingress.yaml +++ b/k8s/ingress.yaml @@ -1,13 +1,13 @@ apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: - name: cheddar + name: kibana spec: rules: - - host: cheddar.A.B.C.D.nip.io + - host: kibana.185.145.251.54.nip.io http: paths: - path: / backend: - serviceName: cheddar - servicePort: 80 + serviceName: kibana + servicePort: 5601 diff --git a/k8s/insecure-dashboard.yaml b/k8s/insecure-dashboard.yaml index 44ec1d65..43ea51fa 100644 --- a/k8s/insecure-dashboard.yaml +++ b/k8s/insecure-dashboard.yaml @@ -162,7 +162,7 @@ spec: selector: k8s-app: kubernetes-dashboard --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: labels: diff --git a/k8s/local-path-storage.yaml b/k8s/local-path-storage.yaml index 7374a02a..b163792a 100644 --- a/k8s/local-path-storage.yaml +++ b/k8s/local-path-storage.yaml @@ -45,7 +45,7 @@ subjects: name: local-path-provisioner-service-account namespace: local-path-storage --- -apiVersion: apps/v1beta2 +apiVersion: apps/v1 kind: Deployment metadata: name: local-path-provisioner diff --git a/k8s/traefik.yaml b/k8s/traefik.yaml index 72b4173b..959ea198 100644 --- a/k8s/traefik.yaml +++ b/k8s/traefik.yaml @@ -6,13 +6,16 @@ metadata: namespace: kube-system --- kind: DaemonSet -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 metadata: name: traefik-ingress-controller namespace: kube-system labels: k8s-app: traefik-ingress-lb spec: + selector: + matchLabels: + k8s-app: traefik-ingress-lb template: metadata: labels: @@ -26,7 +29,7 @@ spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 60 containers: - - image: traefik + - image: traefik:1.7 name: traefik-ingress-lb ports: - name: http diff --git a/slides/k8s/buildshiprun-dockerhub.md b/slides/k8s/buildshiprun-dockerhub.md index ea949cfc..1a75774f 100644 --- a/slides/k8s/buildshiprun-dockerhub.md +++ b/slides/k8s/buildshiprun-dockerhub.md @@ -33,7 +33,7 @@ **make sure that you set `$REGISTRY` and `$TAG` first!** - For example: - ``` + ```bash export REGISTRY=dockercoins TAG=v0.1 ``` diff --git a/slides/k8s/dashboard.md b/slides/k8s/dashboard.md index bae2d732..8d284f90 100644 --- a/slides/k8s/dashboard.md +++ b/slides/k8s/dashboard.md @@ -105,6 +105,22 @@ The dashboard will then ask you which authentication you want to use. --- +## Other dashboards + +- [Kube Web View](https://codeberg.org/hjacobs/kube-web-view) + + - read-only dashboard + + - optimized for "troubleshooting and incident response" + + - see [vision and goals](https://kube-web-view.readthedocs.io/en/latest/vision.html#vision) for details + +- [Kube Ops View](https://github.com/hjacobs/kube-ops-view) + + - "provides a common operational picture for multiple Kubernetes clusters" + +--- + # Security implications of `kubectl apply` - When we do `kubectl apply -f `, we create arbitrary resources @@ -156,4 +172,3 @@ The dashboard will then ask you which authentication you want to use. - It introduces new failure modes (for instance, if you try to apply YAML from a link that's no longer valid) - 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/k8s/healthchecks-more.md b/slides/k8s/healthchecks-more.md index b3093c93..fbfb0c9f 100644 --- a/slides/k8s/healthchecks-more.md +++ b/slides/k8s/healthchecks-more.md @@ -370,6 +370,8 @@ class: extra-details (and have gcr.io/pause take care of the reaping) +- Discussion of this in [Video - 10 Ways to Shoot Yourself in the Foot with Kubernetes, #9 Will Surprise You](https://www.youtube.com/watch?v=QKI-JRs2RIE) + --- ## Healthchecks for worker diff --git a/slides/k8s/resource-limits.md b/slides/k8s/resource-limits.md index 2a03c000..25e86406 100644 --- a/slides/k8s/resource-limits.md +++ b/slides/k8s/resource-limits.md @@ -515,3 +515,24 @@ services.nodeports 0 0 (with `kubectl describe resourcequota ...`) - Rinse and repeat regularly + +--- + +## Additional resources + +- [A Practical Guide to Setting Kubernetes Requests and Limits](http://blog.kubecost.com/blog/requests-and-limits/) + + - explains what requests and limits are + + - provides guidelines to set requests and limits + + - gives PromQL expressions to compute good values +
(our app needs to be running for a while) + +- [Kube Resource Report](https://github.com/hjacobs/kube-resource-report/) + + - generates web reports on resource usage + + - [static demo](https://hjacobs.github.io/kube-resource-report/sample-report/output/index.html) + | + [live demo](https://kube-resource-report.demo.j-serv.de/applications.html) diff --git a/slides/kube-fullday.yml b/slides/kube-fullday.yml index 605d704e..d8af50bf 100644 --- a/slides/kube-fullday.yml +++ b/slides/kube-fullday.yml @@ -51,6 +51,7 @@ chapters: - k8s/scalingdockercoins.md - shared/hastyconclusions.md - k8s/daemonset.md + #- k8s/dryrun.md - k8s/rollout.md #- k8s/healthchecks.md #- k8s/healthchecks-more.md