From ace911a208c90bc77ef4ec56c94eb47d7740fb16 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 23 Aug 2019 04:45:37 -0500 Subject: [PATCH 01/45] Restore ingress YAML template --- k8s/ingress.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml index e322bc10..09445e1e 100644 --- a/k8s/ingress.yaml +++ b/k8s/ingress.yaml @@ -4,11 +4,10 @@ metadata: name: cheddar spec: rules: - - host: px.3.123.33.38.nip.io + - host: cheddar.A.B.C.D.nip.io http: paths: - path: / backend: - serviceName: px-lighthouse + serviceName: cheddar servicePort: 80 - From 9e991d1900e3f32bd34936d1816aa8442cbfe262 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 23 Aug 2019 05:11:05 -0500 Subject: [PATCH 02/45] Add command to change the NodePort range This helps when the customer's internet connection filters out the default port range. It still requires to have a port range open somewhere, though. here we use 10000-10999, but this should be adjusted if necessary. --- prepare-vms/lib/commands.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/prepare-vms/lib/commands.sh b/prepare-vms/lib/commands.sh index 5fb3ed76..c53b7112 100644 --- a/prepare-vms/lib/commands.sh +++ b/prepare-vms/lib/commands.sh @@ -386,6 +386,20 @@ _cmd_pull_images() { pull_tag } +_cmd remap_nodeports "Remap NodePort range to 10000-10999" +_cmd_remap_nodeports() { + TAG=$1 + need_tag + + FIND_LINE=" - --service-cluster-ip-range=10.96.0.0\/12" + ADD_LINE=" - --service-node-port-range=10000-10999" + MANIFEST_FILE=/etc/kubernetes/manifests/kube-apiserver.yaml + pssh " + if i_am_first_node && ! grep -q '$ADD_LINE' $MANIFEST_FILE; then + sudo sed -i 's/\($FIND_LINE\)\$/\1\n$ADD_LINE/' $MANIFEST_FILE + fi" +} + _cmd quotas "Check our infrastructure quotas (max instances)" _cmd_quotas() { need_infra $1 From b5b005b6d2937f03c06430b00303f047abe1f281 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 23 Aug 2019 05:12:48 -0500 Subject: [PATCH 03/45] Bump k8s version --- slides/k8s/localkubeconfig.md | 6 +++--- slides/k8s/versions-k8s.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/slides/k8s/localkubeconfig.md b/slides/k8s/localkubeconfig.md index ce58b889..efcae788 100644 --- a/slides/k8s/localkubeconfig.md +++ b/slides/k8s/localkubeconfig.md @@ -34,11 +34,11 @@ - Download the `kubectl` binary from one of these links: - [Linux](https://storage.googleapis.com/kubernetes-release/release/v1.15.2/bin/linux/amd64/kubectl) + [Linux](https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kubectl) | - [macOS](https://storage.googleapis.com/kubernetes-release/release/v1.15.2/bin/darwin/amd64/kubectl) + [macOS](https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/darwin/amd64/kubectl) | - [Windows](https://storage.googleapis.com/kubernetes-release/release/v1.15.2/bin/windows/amd64/kubectl.exe) + [Windows](https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/windows/amd64/kubectl.exe) - On Linux and macOS, make the binary executable with `chmod +x kubectl` diff --git a/slides/k8s/versions-k8s.md b/slides/k8s/versions-k8s.md index e939876f..8f28c203 100644 --- a/slides/k8s/versions-k8s.md +++ b/slides/k8s/versions-k8s.md @@ -1,6 +1,6 @@ ## Versions installed -- Kubernetes 1.15.2 +- Kubernetes 1.15.3 - Docker Engine 19.03.1 - Docker Compose 1.24.1 From 46878ed6c788aac2a010f4e4838d974c59bdd1fc Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 23 Aug 2019 05:48:55 -0500 Subject: [PATCH 04/45] Update chapter about version upgrades --- prepare-vms/lib/commands.sh | 6 +-- prepare-vms/setup-admin-clusters.sh | 2 +- slides/k8s/cluster-upgrade.md | 74 +++++++++++++++++++++++++---- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/prepare-vms/lib/commands.sh b/prepare-vms/lib/commands.sh index c53b7112..602cf28a 100644 --- a/prepare-vms/lib/commands.sh +++ b/prepare-vms/lib/commands.sh @@ -157,10 +157,10 @@ _cmd_kube() { # Optional version, e.g. 1.13.5 KUBEVERSION=$2 if [ "$KUBEVERSION" ]; then - EXTRA_KUBELET="=$KUBEVERSION-00" + EXTRA_APTGET="=$KUBEVERSION-00" EXTRA_KUBEADM="--kubernetes-version=v$KUBEVERSION" else - EXTRA_KUBELET="" + EXTRA_APTGET="" EXTRA_KUBEADM="" fi @@ -172,7 +172,7 @@ _cmd_kube() { sudo tee /etc/apt/sources.list.d/kubernetes.list" pssh --timeout 200 " sudo apt-get update -q && - sudo apt-get install -qy kubelet$EXTRA_KUBELET kubeadm kubectl && + sudo apt-get install -qy kubelet$EXTRA_APTGET kubeadm$EXTRA_APTGET kubectl$EXTRA_APTGET && kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl" # Initialize kube master diff --git a/prepare-vms/setup-admin-clusters.sh b/prepare-vms/setup-admin-clusters.sh index 75717e52..ffbee227 100755 --- a/prepare-vms/setup-admin-clusters.sh +++ b/prepare-vms/setup-admin-clusters.sh @@ -61,6 +61,6 @@ TAG=$PREFIX-$SETTINGS --count $((3*$STUDENTS)) ./workshopctl deploy $TAG -./workshopctl kube $TAG 1.13.5 +./workshopctl kube $TAG 1.14.6 ./workshopctl cards $TAG diff --git a/slides/k8s/cluster-upgrade.md b/slides/k8s/cluster-upgrade.md index 0b477ce9..2051d78d 100644 --- a/slides/k8s/cluster-upgrade.md +++ b/slides/k8s/cluster-upgrade.md @@ -10,6 +10,8 @@ - Components can be upgraded one at a time without problems + + --- ## Checking what we're running @@ -166,7 +168,7 @@ - Upgrade kubelet: ```bash - apt install kubelet=1.14.2-00 + sudo apt install kubelet=1.15.3-00 ``` ] @@ -226,7 +228,7 @@ sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml ``` -- Look for the `image:` line, and update it to e.g. `v1.14.0` +- Look for the `image:` line, and update it to e.g. `v1.15.0` ] @@ -260,14 +262,52 @@ sudo kubeadm upgrade plan ``` - (Note: kubeadm is confused by our manual upgrade of the API server. -
It thinks the cluster is running 1.14.0!) +] - +Note 1: kubeadm thinks that our cluster is running 1.15.0. +
It is confused by our manual upgrade of the API server! + +Note 2: kubeadm itself is still version 1.14.6. +
It doesn't know how to upgrade do 1.15.X. + +--- + +## Upgrading kubeadm + +- First things first: we need to upgrade kubeadm + +.exercise[ + +- Upgrade kubeadm: + ``` + sudo apt install kubeadm + ``` + +- Check what kubeadm tells us: + ``` + sudo kubeadm upgrade plan + ``` + +] + +Note: kubeadm still thinks that our cluster is running 1.15.0. +
But at least it knows about version 1.15.X now. + +--- + +## Upgrading the cluster with kubeadm + +- Ideally, we should revert our `image:` change + + (so that kubeadm executes the right migration steps) + +- Or we can try the upgrade anyway + +.exercise[ - Perform the upgrade: ```bash - sudo kubeadm upgrade apply v1.14.2 + sudo kubeadm upgrade apply v1.15.3 ``` ] @@ -287,8 +327,8 @@ - Download the configuration on each node, and upgrade kubelet: ```bash for N in 1 2 3; do - ssh test$N sudo kubeadm upgrade node config --kubelet-version v1.14.2 - ssh test$N sudo apt install kubelet=1.14.2-00 + ssh test$N sudo kubeadm upgrade node config --kubelet-version v1.15.3 + ssh test$N sudo apt install kubelet=1.15.3-00 done ``` ] @@ -297,7 +337,7 @@ ## Checking what we've done -- All our nodes should now be updated to version 1.14.2 +- All our nodes should now be updated to version 1.15.3 .exercise[ @@ -307,3 +347,19 @@ ``` ] + +--- + +class: extra-details + +## Skipping versions + +- This example worked because we went from 1.14 to 1.15 + +- If you are upgrading from e.g. 1.13, you will generally have to go through 1.14 first + +- This means upgrading kubeadm to 1.14.X, then using it to upgrade the cluster + +- Then upgrading kubeadm to 1.15.X, etc. + +- **Make sure to read the release notes before upgrading!** From 49df28d44f90fbf01e508196adc12f4821898e55 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Mon, 26 Aug 2019 01:08:14 -0500 Subject: [PATCH 05/45] Add WebSSH snippet --- slides/kube-fullday.yml | 1 + slides/kube-halfday.yml | 1 + slides/kube-selfpaced.yml | 1 + slides/kube-twodays.yml | 1 + slides/shared/webssh.md | 29 +++++++++++++++++++++++++++++ 5 files changed, 33 insertions(+) create mode 100644 slides/shared/webssh.md diff --git a/slides/kube-fullday.yml b/slides/kube-fullday.yml index c521e707..3631fc96 100644 --- a/slides/kube-fullday.yml +++ b/slides/kube-fullday.yml @@ -21,6 +21,7 @@ chapters: - shared/toc.md - - shared/prereqs.md + #- shared/webssh.md - shared/connecting.md - k8s/versions-k8s.md - shared/sampleapp.md diff --git a/slides/kube-halfday.yml b/slides/kube-halfday.yml index 8d86a65e..4a4856b2 100644 --- a/slides/kube-halfday.yml +++ b/slides/kube-halfday.yml @@ -22,6 +22,7 @@ chapters: - shared/about-slides.md - shared/toc.md - - shared/prereqs.md + #- shared/webssh.md - shared/connecting.md - k8s/versions-k8s.md - shared/sampleapp.md diff --git a/slides/kube-selfpaced.yml b/slides/kube-selfpaced.yml index f43e80cc..f2647377 100644 --- a/slides/kube-selfpaced.yml +++ b/slides/kube-selfpaced.yml @@ -21,6 +21,7 @@ chapters: - shared/toc.md - - shared/prereqs.md + #- shared/webssh.md - shared/connecting.md - k8s/versions-k8s.md - shared/sampleapp.md diff --git a/slides/kube-twodays.yml b/slides/kube-twodays.yml index 0c1ef38a..b1d93be5 100644 --- a/slides/kube-twodays.yml +++ b/slides/kube-twodays.yml @@ -21,6 +21,7 @@ chapters: - shared/toc.md - - shared/prereqs.md + #- shared/webssh.md - shared/connecting.md - k8s/versions-k8s.md - shared/sampleapp.md diff --git a/slides/shared/webssh.md b/slides/shared/webssh.md new file mode 100644 index 00000000..45f345c0 --- /dev/null +++ b/slides/shared/webssh.md @@ -0,0 +1,29 @@ +## WebSSH + +- The virtual machines are also accessible via WebSSH + +- This can be useful if: + + - you can't install an SSH client on your machine + + - SSH connections are blocked (by firewall or local policy) + +- To use WebSSH, connect to the IP address of the remote VM on port 1080 + + (each machine runs a WebSSH server) + +- Then provide the login and password indicated on your card + +--- + +## Good to know + +- WebSSH uses WebSocket + +- If you're having connections issues, try to disable your HTTP proxy + + (many HTTP proxies can't handle WebSocket properly) + +- Most keyboard shortcuts should work, except Ctrl-W + + (as it is hardwired by the browser to "close this tab") From c4b408621cd6ac954f6199dda7dce204dc1f9110 Mon Sep 17 00:00:00 2001 From: AJ Bowen Date: Thu, 18 Jul 2019 09:32:30 +0200 Subject: [PATCH 06/45] Create .tmux.conf to allow mouse and scrolling support and vim bindings for changing panes --- prepare-vms/lib/postprep.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/prepare-vms/lib/postprep.py b/prepare-vms/lib/postprep.py index f4cd042a..28318d1b 100755 --- a/prepare-vms/lib/postprep.py +++ b/prepare-vms/lib/postprep.py @@ -75,6 +75,26 @@ set shiftwidth=2 set softtabstop=2 SQRL""") +# Custom .tmux.conf +system( + """sudo -u docker tee /home/docker/.tmux.conf < Date: Tue, 3 Sep 2019 04:49:03 -0500 Subject: [PATCH 07/45] Word tweaks for eksctl Just indicate that eksctl is now "the new way" to deploy EKS (since AWS now supports it officially). --- slides/k8s/setup-managed.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slides/k8s/setup-managed.md b/slides/k8s/setup-managed.md index 065f4e4f..e13fd18a 100644 --- a/slides/k8s/setup-managed.md +++ b/slides/k8s/setup-managed.md @@ -18,7 +18,7 @@ with a cloud provider --- -## EKS (the hard way) +## EKS (the old way) - [Read the doc](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-console.html) @@ -36,7 +36,7 @@ with a cloud provider --- -## EKS (the easy way) +## EKS (the new way) - Install `eksctl` From 5bbce4783a2406267315d681c158bd6a67296a04 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 3 Sep 2019 06:51:15 -0500 Subject: [PATCH 08/45] Better modularize card generation Most parameters used by the Jinja template for the cards can now be specified in settings.yaml. This should make the generation of cards for admin training much easier. --- prepare-vms/README.md | 51 +++++++++++++--------- prepare-vms/lib/ips-txt-to-html.py | 26 +++++------ prepare-vms/settings/admin-dmuc.yaml | 2 + prepare-vms/settings/admin-kubenet.yaml | 3 ++ prepare-vms/settings/admin-kuberouter.yaml | 3 ++ prepare-vms/settings/admin-test.yaml | 2 + prepare-vms/settings/jerome.yaml | 1 - prepare-vms/templates/cards.html | 31 +++++++++---- 8 files changed, 76 insertions(+), 43 deletions(-) diff --git a/prepare-vms/README.md b/prepare-vms/README.md index f325946b..c86c4c81 100644 --- a/prepare-vms/README.md +++ b/prepare-vms/README.md @@ -87,26 +87,37 @@ You're all set! ``` workshopctl - the orchestration workshop swiss army knife Commands: -ami Show the AMI that will be used for deployment -amis List Ubuntu AMIs in the current region -build Build the Docker image to run this program in a container -cards Generate ready-to-print cards for a group of VMs -deploy Install Docker on a bunch of running VMs -ec2quotas Check our EC2 quotas (max instances) -help Show available commands -ids List the instance IDs belonging to a given tag or token -ips List the IP addresses of the VMs for a given tag or token -kube Setup kubernetes clusters with kubeadm (must be run AFTER deploy) -kubetest Check that all notes are reporting as Ready -list List available groups in the current region -opensg Open the default security group to ALL ingress traffic -pull_images Pre-pull a bunch of Docker images -retag Apply a new tag to a group of VMs -start Start a group of VMs -status List instance status for a given group -stop Stop (terminate, shutdown, kill, remove, destroy...) instances -test Run tests (pre-flight checks) on a group of VMs -wrap Run this program in a container +build Build the Docker image to run this program in a container +cards Generate ready-to-print cards for a group of VMs +deploy Install Docker on a bunch of running VMs +disableaddrchecks Disable source/destination IP address checks +disabledocker Stop Docker Engine and don't restart it automatically +helmprom Install Helm and Prometheus +help Show available commands +ids (FIXME) List the instance IDs belonging to a given tag or token +kubebins Install Kubernetes and CNI binaries but don't start anything +kubereset Wipe out Kubernetes configuration on all nodes +kube Setup kubernetes clusters with kubeadm (must be run AFTER deploy) +kubetest Check that all nodes are reporting as Ready +listall List VMs running on all configured infrastructures +list List available groups for a given infrastructure +netfix Disable GRO and run a pinger job on the VMs +opensg Open the default security group to ALL ingress traffic +ping Ping VMs in a given tag, to check that they have network access +pssh Run an arbitrary command on all nodes +pull_images Pre-pull a bunch of Docker images +quotas Check our infrastructure quotas (max instances) +remap_nodeports Remap NodePort range to 10000-10999 +retag (FIXME) Apply a new tag to a group of VMs +ssh Open an SSH session to the first node of a tag +start Start a group of VMs +stop Stop (terminate, shutdown, kill, remove, destroy...) instances +tags List groups of VMs known locally +test Run tests (pre-flight checks) on a group of VMs +weavetest Check that weave seems properly setup +webssh Install a WEB SSH server on the machines (port 1080) +wrap Run this program in a container +www Run a web server to access card HTML and PDF ``` ### Summary of What `./workshopctl` Does For You diff --git a/prepare-vms/lib/ips-txt-to-html.py b/prepare-vms/lib/ips-txt-to-html.py index 5bc1873c..6f0891cc 100755 --- a/prepare-vms/lib/ips-txt-to-html.py +++ b/prepare-vms/lib/ips-txt-to-html.py @@ -4,17 +4,12 @@ import sys import yaml import jinja2 -def prettify(l): - l = [ip.strip() for ip in l] - ret = [ "node{}: {}".format(i+1, s) for (i, s) in zip(range(len(l)), l) ] - return ret # Read settings from user-provided settings file -SETTINGS = yaml.load(open(sys.argv[1])) - -clustersize = SETTINGS["clustersize"] +context = yaml.safe_load(open(sys.argv[1])) ips = list(open("ips.txt")) +clustersize = context["clustersize"] print("---------------------------------------------") print(" Number of IPs: {}".format(len(ips))) @@ -30,7 +25,9 @@ while ips: ips = ips[clustersize:] clusters.append(cluster) -template_file_name = SETTINGS["cards_template"] +context["clusters"] = clusters + +template_file_name = context["cards_template"] template_file_path = os.path.join( os.path.dirname(__file__), "..", @@ -39,18 +36,19 @@ template_file_path = os.path.join( ) template = jinja2.Template(open(template_file_path).read()) with open("ips.html", "w") as f: - f.write(template.render(clusters=clusters, **SETTINGS)) + f.write(template.render(**context)) print("Generated ips.html") + try: import pdfkit with open("ips.html") as f: pdfkit.from_file(f, "ips.pdf", options={ - "page-size": SETTINGS["paper_size"], - "margin-top": SETTINGS["paper_margin"], - "margin-bottom": SETTINGS["paper_margin"], - "margin-left": SETTINGS["paper_margin"], - "margin-right": SETTINGS["paper_margin"], + "page-size": context["paper_size"], + "margin-top": context["paper_margin"], + "margin-bottom": context["paper_margin"], + "margin-left": context["paper_margin"], + "margin-right": context["paper_margin"], }) print("Generated ips.pdf") except ImportError: diff --git a/prepare-vms/settings/admin-dmuc.yaml b/prepare-vms/settings/admin-dmuc.yaml index d4587009..6ac252c0 100644 --- a/prepare-vms/settings/admin-dmuc.yaml +++ b/prepare-vms/settings/admin-dmuc.yaml @@ -26,3 +26,5 @@ machine_version: 0.14.0 # Password used to connect with the "docker user" docker_user_password: training + +image: diff --git a/prepare-vms/settings/admin-kubenet.yaml b/prepare-vms/settings/admin-kubenet.yaml index b18cb5de..e283b10e 100644 --- a/prepare-vms/settings/admin-kubenet.yaml +++ b/prepare-vms/settings/admin-kubenet.yaml @@ -26,3 +26,6 @@ machine_version: 0.14.0 # Password used to connect with the "docker user" docker_user_password: training + +clusternumber: 100 +image: diff --git a/prepare-vms/settings/admin-kuberouter.yaml b/prepare-vms/settings/admin-kuberouter.yaml index 97f5283d..9e6c4133 100644 --- a/prepare-vms/settings/admin-kuberouter.yaml +++ b/prepare-vms/settings/admin-kuberouter.yaml @@ -26,3 +26,6 @@ machine_version: 0.14.0 # Password used to connect with the "docker user" docker_user_password: training + +clusternumber: 200 +image: diff --git a/prepare-vms/settings/admin-test.yaml b/prepare-vms/settings/admin-test.yaml index 7390a51c..691b60f8 100644 --- a/prepare-vms/settings/admin-test.yaml +++ b/prepare-vms/settings/admin-test.yaml @@ -26,3 +26,5 @@ machine_version: 0.14.0 # Password used to connect with the "docker user" docker_user_password: training + +image: diff --git a/prepare-vms/settings/jerome.yaml b/prepare-vms/settings/jerome.yaml index a618cc5a..4f68a3e4 100644 --- a/prepare-vms/settings/jerome.yaml +++ b/prepare-vms/settings/jerome.yaml @@ -26,4 +26,3 @@ machine_version: 0.14.0 # Password used to connect with the "docker user" docker_user_password: training - diff --git a/prepare-vms/templates/cards.html b/prepare-vms/templates/cards.html index 1f58b8f6..7a30cd41 100644 --- a/prepare-vms/templates/cards.html +++ b/prepare-vms/templates/cards.html @@ -1,12 +1,23 @@ -{# Feel free to customize or override anything in there! #} +{# + The variables below can be customized here directly, or in your + settings.yaml file. Any variable in settings.yaml will be exposed + in here as well. +#} -{%- set url = "http://FIXME.container.training/" -%} -{%- set pagesize = 9 -%} -{%- set lang = "en" -%} -{%- set event = "training session" -%} -{%- set backside = False -%} -{%- set image = "kube" -%} -{%- set clusternumber = 100 -%} +{%- set url = url + | default("http://FIXME.container.training/") -%} +{%- set pagesize = pagesize + | default(9) -%} +{%- set lang = lang + | default("en") -%} +{%- set event = event + | default("training session") -%} +{%- set backside = backside + | default(False) -%} +{%- set image = image + | default("kube") -%} +{%- set clusternumber = clusternumber + | default(None) -%} {%- set image_src = { "docker": "https://s3-us-west-2.amazonaws.com/www.breadware.com/integrations/docker.png", @@ -161,7 +172,9 @@ img.kube {

{{ intro }}

+ {% if image_src %} + {% endif %} {% if clusternumber != None %} @@ -187,8 +200,10 @@ img.kube {

+ {% if url %} {{ slides_are_at }}

{{ url }}
+ {% endif %}

{% if loop.index%pagesize==0 or loop.last %} From 04f728c67ae36d5567e6e89fcfc6dac57fa0bb35 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 3 Sep 2019 09:04:42 -0500 Subject: [PATCH 09/45] Add nowrap to vimrc The certificates embedded in .kube/config make the file a bit hard to read. This will make it easier. --- prepare-vms/lib/postprep.py | 1 + 1 file changed, 1 insertion(+) diff --git a/prepare-vms/lib/postprep.py b/prepare-vms/lib/postprep.py index 28318d1b..14c45478 100755 --- a/prepare-vms/lib/postprep.py +++ b/prepare-vms/lib/postprep.py @@ -73,6 +73,7 @@ set expandtab set number set shiftwidth=2 set softtabstop=2 +set nowrap SQRL""") # Custom .tmux.conf From ab77d892323d6c6d088f6d5c2f5db17e1896d9eb Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 6 Sep 2019 13:19:53 -0400 Subject: [PATCH 10/45] added GOTO Berlin to index --- slides/index.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/slides/index.yaml b/slides/index.yaml index 4c69e4b6..3e1ea465 100644 --- a/slides/index.yaml +++ b/slides/index.yaml @@ -14,6 +14,14 @@ title: Déployer ses applications avec Kubernetes (in French) lang: fr attend: http://2019.devops-dday.com/Workshop.html + +- date: 2019-10-22 + country: de + city: Berlin + event: GOTO + speaker: bretfisher + title: Kubernetes or Swarm? Build Both, Deploy Apps, Learn The Differences + attend: https://gotober.com/2019/workshops/194 - date: [2019-09-24, 2019-09-25] country: fr From f3622d98fe988fa7b99fa627f4a59277235f41d4 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 13 Sep 2019 16:49:47 -0400 Subject: [PATCH 11/45] fixing uppercase K in yaml for static pods --- k8s/just-a-pod.yaml | 2 +- slides/k8s/staticpods.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/k8s/just-a-pod.yaml b/k8s/just-a-pod.yaml index 346525de..a6d1ff4f 100644 --- a/k8s/just-a-pod.yaml +++ b/k8s/just-a-pod.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -Kind: Pod +kind: Pod metadata: name: hello namespace: default diff --git a/slides/k8s/staticpods.md b/slides/k8s/staticpods.md index 31ad23ea..63974122 100644 --- a/slides/k8s/staticpods.md +++ b/slides/k8s/staticpods.md @@ -224,7 +224,7 @@ In the manifest, the pod was named `hello`. ```yaml apiVersion: v1 -Kind: Pod +kind: Pod metadata: name: hello namespace: default From f4f0fb0f23d976e5b7fd54d735262c21322d4ab4 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 17 Sep 2019 06:13:21 -0500 Subject: [PATCH 12/45] http.server requires python3 --- prepare-vms/lib/commands.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prepare-vms/lib/commands.sh b/prepare-vms/lib/commands.sh index 602cf28a..cc8b6c60 100644 --- a/prepare-vms/lib/commands.sh +++ b/prepare-vms/lib/commands.sh @@ -596,7 +596,7 @@ _cmd_www() { echo "http://$IPADDR:8000/$F" done info "Press Ctrl-C to stop server." - python -m http.server + python3 -m http.server } greet() { From 82b7b7ba882b4f1babe11e4f0f099c9f4cb42c48 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Wed, 18 Sep 2019 13:08:54 -0500 Subject: [PATCH 13/45] Add slides for ENIX training --- slides/index.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/slides/index.yaml b/slides/index.yaml index 3e1ea465..b7150f4a 100644 --- a/slides/index.yaml +++ b/slides/index.yaml @@ -31,6 +31,7 @@ title: Déployer ses applications avec Kubernetes (in French) lang: fr attend: https://enix.io/fr/services/formation/deployer-ses-applications-avec-kubernetes/ + slides: https://kube-2019-09.container.training/ - date: 2019-08-27 country: tr From 5a5a08cf25c29d23f167c8c1125e58715d3f5f1b Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 19 Sep 2019 13:22:59 -0500 Subject: [PATCH 14/45] Add CLT training --- slides/index.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/slides/index.yaml b/slides/index.yaml index b7150f4a..aac47fa3 100644 --- a/slides/index.yaml +++ b/slides/index.yaml @@ -14,6 +14,22 @@ title: Déployer ses applications avec Kubernetes (in French) lang: fr attend: http://2019.devops-dday.com/Workshop.html + +- date: [2019-10-22, 2019-10-24] + country: us + city: Charlotte, NC + event: Ardan Labs + speaker: jpetazzo + title: Kubernetes Training + attend: https://www.eventbrite.com/e/containers-docker-and-kubernetes-training-for-devs-and-ops-charlotte-nc-november-2019-tickets-73296659281 + +- date: 2019-10-22 + country: us + city: Charlotte, NC + event: Ardan Labs + speaker: jpetazzo + title: Docker & Containers Training + attend: https://www.eventbrite.com/e/containers-docker-and-kubernetes-training-for-devs-and-ops-charlotte-nc-november-2019-tickets-73296659281 - date: 2019-10-22 country: de From 96104193baf40684e962a26583acd3c44c1dbc42 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 20 Sep 2019 09:57:27 -0500 Subject: [PATCH 15/45] Add LISA tutorial --- slides/index.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/slides/index.yaml b/slides/index.yaml index aac47fa3..c98a0d1a 100644 --- a/slides/index.yaml +++ b/slides/index.yaml @@ -15,6 +15,14 @@ lang: fr attend: http://2019.devops-dday.com/Workshop.html +- date: 2019-10-30 + country: us + city: Portland, OR + event: LISA + speaker: jpetazzo + title: Deep Dive into Kubernetes Internals for Builders and Operators + attend: https://www.usenix.org/conference/lisa19/presentation/petazzoni-tutorial + - date: [2019-10-22, 2019-10-24] country: us city: Charlotte, NC From 169d850fc7d2182c1cf5c6005a3f01feedb36b4f Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Mon, 23 Sep 2019 08:30:16 -0500 Subject: [PATCH 16/45] bump apiversion for 1.16 --- k8s/metrics-server.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/metrics-server.yaml b/k8s/metrics-server.yaml index 5864e25d..ddb2998d 100644 --- a/k8s/metrics-server.yaml +++ b/k8s/metrics-server.yaml @@ -58,7 +58,7 @@ metadata: name: metrics-server namespace: kube-system --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: name: metrics-server From eb2e74f236b56cbe39c89614fb47889902e8b7ca Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Mon, 23 Sep 2019 08:53:38 -0500 Subject: [PATCH 17/45] Adjust apiVersion for k8s 1.16 --- k8s/efk.yaml | 9 ++++++--- k8s/ingress.yaml | 8 ++++---- k8s/insecure-dashboard.yaml | 2 +- k8s/local-path-storage.yaml | 2 +- k8s/traefik.yaml | 7 +++++-- 5 files changed, 17 insertions(+), 11 deletions(-) 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 From c409c6997aae24e2227672e941dd4c73b2bd0bae Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 3 Oct 2019 05:09:17 -0500 Subject: [PATCH 18/45] Add kubecost blog post about requests and limits --- slides/k8s/resource-limits.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/slides/k8s/resource-limits.md b/slides/k8s/resource-limits.md index 2a03c000..d485c956 100644 --- a/slides/k8s/resource-limits.md +++ b/slides/k8s/resource-limits.md @@ -515,3 +515,17 @@ 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 + + (this implies that our app has been running for a while) From 381cd270372a26f9c3dacd57728eb470e342ac99 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 3 Oct 2019 05:19:51 -0500 Subject: [PATCH 19/45] Add kube resource report --- slides/k8s/resource-limits.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/slides/k8s/resource-limits.md b/slides/k8s/resource-limits.md index d485c956..25e86406 100644 --- a/slides/k8s/resource-limits.md +++ b/slides/k8s/resource-limits.md @@ -520,12 +520,19 @@ services.nodeports 0 0 ## Additional resources -[A Practical Guide to Setting Kubernetes Requests and Limits](http://blog.kubecost.com/blog/requests-and-limits/) +- [A Practical Guide to Setting Kubernetes Requests and Limits](http://blog.kubecost.com/blog/requests-and-limits/) -- Explains what requests and limits are + - explains what requests and limits are -- Provides guidelines to set requests and limits + - provides guidelines to set requests and limits -- Gives PromQL expressions to compute good values + - gives PromQL expressions to compute good values +
(our app needs to be running for a while) - (this implies that our app has been 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) From 370bdf9aafb976a936c4164f4b945c4a16bba2f2 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 3 Oct 2019 05:28:13 -0500 Subject: [PATCH 20/45] Add kube web view and kube ops view --- slides/k8s/dashboard.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) 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) - From 5958874071018d202a910a8e96f2878d0ce24b8b Mon Sep 17 00:00:00 2001 From: Christian Bewernitz Date: Sat, 5 Oct 2019 14:54:52 +0200 Subject: [PATCH 21/45] highlight code that is recommended to be used (#522) Better highlight code that is recommended to be used. (Thanks @karfau for the patch!) --- slides/k8s/buildshiprun-dockerhub.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ``` From f96da2d260e54c2e16a2397ea042cca4a38fe54d Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Sun, 6 Oct 2019 09:24:30 -0500 Subject: [PATCH 22/45] 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 From be2374c67283c997318fe11f11a3fc93a576e0ea Mon Sep 17 00:00:00 2001 From: Joe McMahon Date: Tue, 8 Oct 2019 09:52:44 -0700 Subject: [PATCH 23/45] Add instructions for pyyml, jinja2, default Python Installing `mosh` via Homebrew may change `/usr/local/bin/python` to Python 2. Adds docs to check and fix this so that `pyyml` and `jinja2` can be installed. --- prepare-vms/README.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/prepare-vms/README.md b/prepare-vms/README.md index c86c4c81..17a10f9a 100644 --- a/prepare-vms/README.md +++ b/prepare-vms/README.md @@ -17,9 +17,10 @@ the Azure CLI, the AWS CLI, or terraform (for OpenStack deployment). And if you want to generate printable cards: -- [pyyaml](https://pypi.python.org/pypi/PyYAML) (on a Mac: `brew install pyyaml`) -- [jinja2](https://pypi.python.org/pypi/Jinja2) (on a Mac: `brew install jinja2`) - +- [pyyaml](https://pypi.python.org/pypi/PyYAML) `pip install pyyaml` +- [jinja2](https://pypi.python.org/pypi/Jinja2) `pip install jinja2` +- +-(These require Python 3; see below for information on setting Python3 as your default Python on the Mac. If you installed `mosh`, Homebrew may have changed your default Python to Python 2.) ## General Workflow - fork/clone repo @@ -256,3 +257,22 @@ If you don't have `wkhtmltopdf` installed, you will get a warning that it is a m - Don't write to bash history in system() in postprep - compose, etc version inconsistent (int vs str) + +## Making sure Python3 is your default on the Mac + +Check the `/usr/local/bin/python` symlink. It should be pointing to `//usr/local/Cellar/python/3`-something. If it isn't, do the following: + + - Verify that python 3 is installed: + - + ls -la /usr/local/Cellar/Python + + - You should see one or more versions of Python 3. If you don't, `brew install python` to install it. + - Verify that `python` points to Python3. + + ls -la /usr/local/bin/python + + - If this points to `/usr/local/Cellar/python@2`, then we'll need to change it. + + rm /usr/local/bin/python + ln -s /usr/local/Cellar/Python/xxxx /usr/local/bin/python # where xxxx is the most recent Python 3 version you saw above + From 13ba8cef9d664b492811dcf4bcc922a1f5457825 Mon Sep 17 00:00:00 2001 From: Tim Vroom Date: Wed, 9 Oct 2019 10:47:52 -0700 Subject: [PATCH 24/45] Add link to conference video mentioning issues with zombie'd exec healthcheck --- slides/k8s/healthchecks-more.md | 2 ++ 1 file changed, 2 insertions(+) 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 From 4c285b53181a2be73c7a004a82c6bd3f1e7bc883 Mon Sep 17 00:00:00 2001 From: Joe McMahon Date: Thu, 10 Oct 2019 09:27:48 -0700 Subject: [PATCH 25/45] Add instruction to install stern on OS X --- slides/k8s/logs-cli.md | 1 + 1 file changed, 1 insertion(+) diff --git a/slides/k8s/logs-cli.md b/slides/k8s/logs-cli.md index 5a9a6c1a..1017bb52 100644 --- a/slides/k8s/logs-cli.md +++ b/slides/k8s/logs-cli.md @@ -65,6 +65,7 @@ Exactly what we need! https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64 sudo chmod +x /usr/local/bin/stern ``` + On OS X, `brew install stern` From 0b8023873697b8195107bb9c9694661390c9eeed Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 25 Oct 2019 12:25:49 -0500 Subject: [PATCH 26/45] Bump up versions of kubebins --- prepare-vms/lib/commands.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/prepare-vms/lib/commands.sh b/prepare-vms/lib/commands.sh index cc8b6c60..99d8452f 100644 --- a/prepare-vms/lib/commands.sh +++ b/prepare-vms/lib/commands.sh @@ -127,11 +127,11 @@ _cmd_kubebins() { set -e cd /usr/local/bin if ! [ -x etcd ]; then - curl -L https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz \ + curl -L https://github.com/etcd-io/etcd/releases/download/v3.3.15/etcd-v3.3.15-linux-amd64.tar.gz \ | sudo tar --strip-components=1 --wildcards -zx '*/etcd' '*/etcdctl' fi if ! [ -x hyperkube ]; then - curl -L https://dl.k8s.io/v1.14.1/kubernetes-server-linux-amd64.tar.gz \ + curl -L https://dl.k8s.io/v1.16.2/kubernetes-server-linux-amd64.tar.gz \ | sudo tar --strip-components=3 -zx kubernetes/server/bin/hyperkube fi if ! [ -x kubelet ]; then @@ -143,7 +143,7 @@ _cmd_kubebins() { sudo mkdir -p /opt/cni/bin cd /opt/cni/bin if ! [ -x bridge ]; then - curl -L https://github.com/containernetworking/plugins/releases/download/v0.7.5/cni-plugins-amd64-v0.7.5.tgz \ + curl -L https://github.com/containernetworking/plugins/releases/download/v0.8.2/cni-plugins-amd64-v0.8.2.tgz \ | sudo tar -zx fi " From 6cbcc4ae697a071e6c4767c7f0d0b3ab0a848e33 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 29 Oct 2019 19:44:41 -0500 Subject: [PATCH 27/45] Fix CNI version (0.8 is unsupported yet) --- prepare-vms/lib/commands.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prepare-vms/lib/commands.sh b/prepare-vms/lib/commands.sh index 99d8452f..ade36b6e 100644 --- a/prepare-vms/lib/commands.sh +++ b/prepare-vms/lib/commands.sh @@ -143,7 +143,7 @@ _cmd_kubebins() { sudo mkdir -p /opt/cni/bin cd /opt/cni/bin if ! [ -x bridge ]; then - curl -L https://github.com/containernetworking/plugins/releases/download/v0.8.2/cni-plugins-amd64-v0.8.2.tgz \ + curl -L https://github.com/containernetworking/plugins/releases/download/v0.7.6/cni-plugins-amd64-v0.7.6.tgz \ | sudo tar -zx fi " From 23aaf7f58ceed72b3d04359835050c85cd4a600f Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 29 Oct 2019 19:48:23 -0500 Subject: [PATCH 28/45] Improve DMUC slides --- slides/k8s/dmuc.md | 26 +++++++------------------- slides/k8s/multinode.md | 20 ++++++++++++-------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/slides/k8s/dmuc.md b/slides/k8s/dmuc.md index 17f60543..94658c6b 100644 --- a/slides/k8s/dmuc.md +++ b/slides/k8s/dmuc.md @@ -481,13 +481,13 @@ docker run alpine echo hello world .exercise[ -- Create the file `kubeconfig.kubelet` with `kubectl`: +- Create the file `~/.kube/config` with `kubectl`: ```bash - kubectl --kubeconfig kubeconfig.kubelet config \ + kubectl config \ set-cluster localhost --server http://localhost:8080 - kubectl --kubeconfig kubeconfig.kubelet config \ + kubectl config \ set-context localhost --cluster localhost - kubectl --kubeconfig kubeconfig.kubelet config \ + kubectl config \ use-context localhost ``` @@ -495,19 +495,7 @@ docker run alpine echo hello world --- -## All Kubernetes clients can use `kubeconfig` - -- The `kubeconfig.kubelet` file has the same format as e.g. `~/.kubeconfig` - -- All Kubernetes clients can use a similar file - -- The `kubectl config` commands can be used to manipulate these files - -- This highlights that kubelet is a "normal" client of the API server - ---- - -## Our `kubeconfig.kubelet` file +## Our `~/.kube/config` file The file that we generated looks like the one below. @@ -533,9 +521,9 @@ clusters: .exercise[ -- Start kubelet with that `kubeconfig.kubelet` file: +- Start kubelet with that kubeconfig file: ```bash - kubelet --kubeconfig kubeconfig.kubelet + kubelet --kubeconfig ~/.kube/config ``` ] diff --git a/slides/k8s/multinode.md b/slides/k8s/multinode.md index af6b6194..ac224b20 100644 --- a/slides/k8s/multinode.md +++ b/slides/k8s/multinode.md @@ -218,6 +218,18 @@ class: extra-details ## What's going on? +- Without the `--network-plugin` flag, kubelet defaults to "no-op" networking + +- It lets the container engine use a default network + + (in that case, we end up with the default Docker bridge) + +- Our pods are running on independent, disconnected, host-local networks + +--- + +## What do we need to do? + - On a normal cluster, kubelet is configured to set up pod networking with CNI plugins - This requires: @@ -228,14 +240,6 @@ class: extra-details - running kubelet with `--network-plugin=cni` -- Without the `--network-plugin` flag, kubelet defaults to "no-op" networking - -- It lets the container engine use a default network - - (in that case, we end up with the default Docker bridge) - -- Our pods are running on independent, disconnected, host-local networks - --- ## Using network plugins From fb64c0d68f6f797a1ea449d8a3ab0bf96e2a5d3e Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 29 Oct 2019 20:31:18 -0500 Subject: [PATCH 29/45] Update kube-proxy command --- slides/k8s/multinode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slides/k8s/multinode.md b/slides/k8s/multinode.md index ac224b20..829208db 100644 --- a/slides/k8s/multinode.md +++ b/slides/k8s/multinode.md @@ -398,7 +398,7 @@ class: extra-details - Start kube-proxy: ```bash - sudo kube-proxy --kubeconfig ~/kubeconfig + sudo kube-proxy --kubeconfig ~/.kube/config ``` - Expose our Deployment: From 0fc7c2316cda10d18927530f8d49cc3848160062 Mon Sep 17 00:00:00 2001 From: Nadine Whitfield Date: Tue, 29 Oct 2019 23:48:50 -0700 Subject: [PATCH 30/45] Updated for python 3.7 --- prepare-local/README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/prepare-local/README.md b/prepare-local/README.md index 0fb0057f..304ee2e9 100644 --- a/prepare-local/README.md +++ b/prepare-local/README.md @@ -7,9 +7,10 @@ workshop. ## 1. Prerequisites - Virtualbox, Vagrant and Ansible +Before installing, navigate to container.training/prepare-local/. + - Virtualbox: https://www.virtualbox.org/wiki/Downloads - Vagrant: https://www.vagrantup.com/downloads.html @@ -25,7 +26,7 @@ Virtualbox, Vagrant and Ansible $ git clone --recursive https://github.com/ansible/ansible.git $ cd ansible - $ git checkout stable-2.0.0.1 + $ git checkout stable-{{ getStableVersionFromProject }} $ git submodule update - source the setup script to make Ansible available on this terminal session: @@ -66,6 +67,14 @@ will reflect inside the instance. - Depending on the Vagrant version, `sudo apt-get install bsdtar` may be needed +- If you get an error like "no Vagrant file found" or you have a file but "cannot open base box" when running `vagrant up`, +chances are good you not in the correct directory. +Make sure you are in sub directory named "prepare-local". It has all the config files required by ansible, vagrant and virtualbox + +- If you are using Python 3.7, running the ansible-playbook provisioning, see an error like "SyntaxError: invalid syntax" and it mentions +the word "async", you need to upgrade your Ansible version to 2.6 or higher to resolve the keyword conflict. +https://github.com/ansible/ansible/issues/42105 + - If you get strange Ansible errors about dependencies, try to check your pip version with `pip --version`. The current version is 8.1.1. If your pip is older than this, upgrade it with `sudo pip install --upgrade pip`, restart From 5c161d209084598a4437dc0dedd7705022858b55 Mon Sep 17 00:00:00 2001 From: Nadine Whitfield Date: Tue, 29 Oct 2019 23:51:57 -0700 Subject: [PATCH 31/45] Update README.md --- prepare-local/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prepare-local/README.md b/prepare-local/README.md index 304ee2e9..96ad0ba3 100644 --- a/prepare-local/README.md +++ b/prepare-local/README.md @@ -9,7 +9,6 @@ workshop. ## 1. Prerequisites Virtualbox, Vagrant and Ansible -Before installing, navigate to container.training/prepare-local/. - Virtualbox: https://www.virtualbox.org/wiki/Downloads @@ -26,7 +25,7 @@ Before installing, navigate to container.training/prepare-local/. $ git clone --recursive https://github.com/ansible/ansible.git $ cd ansible - $ git checkout stable-{{ getStableVersionFromProject }} + $ git checkout stable-{{ getStableVersionFromAnsibleProject }} $ git submodule update - source the setup script to make Ansible available on this terminal session: @@ -39,6 +38,7 @@ Before installing, navigate to container.training/prepare-local/. ## 2. Preparing the environment +Change into directory that has your Vagrantfile Run the following commands: From 84198b3fdcb94206f10ab69d707e85c948832503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Petazzoni?= Date: Wed, 30 Oct 2019 17:13:13 -0500 Subject: [PATCH 32/45] Update README.md --- prepare-vms/README.md | 49 ++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/prepare-vms/README.md b/prepare-vms/README.md index 17a10f9a..4dbaff56 100644 --- a/prepare-vms/README.md +++ b/prepare-vms/README.md @@ -10,17 +10,22 @@ These tools can help you to create VMs on: - [Docker](https://docs.docker.com/engine/installation/) - [Docker Compose](https://docs.docker.com/compose/install/) -- [Parallel SSH](https://code.google.com/archive/p/parallel-ssh/) (on a Mac: `brew install pssh`) - the configuration scripts require this +- [Parallel SSH](https://code.google.com/archive/p/parallel-ssh/) (on a Mac: `brew install pssh`) Depending on the infrastructure that you want to use, you also need to install the Azure CLI, the AWS CLI, or terraform (for OpenStack deployment). And if you want to generate printable cards: -- [pyyaml](https://pypi.python.org/pypi/PyYAML) `pip install pyyaml` -- [jinja2](https://pypi.python.org/pypi/Jinja2) `pip install jinja2` -- --(These require Python 3; see below for information on setting Python3 as your default Python on the Mac. If you installed `mosh`, Homebrew may have changed your default Python to Python 2.) +- [pyyaml](https://pypi.python.org/pypi/PyYAML) +- [jinja2](https://pypi.python.org/pypi/Jinja2) + +You can install them with pip (perhaps with `pip install --user`, or even use `virtualenv` if that's your thing). + +These require Python 3. If you are on a Mac, see below for specific instructions on setting up +Python 3 to be the default Python on a Mac. In particular, if you installed `mosh`, Homebrew +may have changed your default Python to Python 2. + ## General Workflow - fork/clone repo @@ -258,21 +263,31 @@ If you don't have `wkhtmltopdf` installed, you will get a warning that it is a m - Don't write to bash history in system() in postprep - compose, etc version inconsistent (int vs str) -## Making sure Python3 is your default on the Mac +## Making sure Python3 is the default (Mac only) -Check the `/usr/local/bin/python` symlink. It should be pointing to `//usr/local/Cellar/python/3`-something. If it isn't, do the following: +Check the `/usr/local/bin/python` symlink. It should be pointing to +`/usr/local/Cellar/python/3`-something. If it isn't, follow these +instructions. - - Verify that python 3 is installed: - - - ls -la /usr/local/Cellar/Python +1) Verify that Python 3 is installed. - - You should see one or more versions of Python 3. If you don't, `brew install python` to install it. - - Verify that `python` points to Python3. +``` +ls -la /usr/local/Cellar/Python +``` + +You should see one or more versions of Python 3. If you don't, +install it with `brew install python`. + +2) Verify that `python` points to Python3. - ls -la /usr/local/bin/python +``` +ls -la /usr/local/bin/python +``` - - If this points to `/usr/local/Cellar/python@2`, then we'll need to change it. - - rm /usr/local/bin/python - ln -s /usr/local/Cellar/Python/xxxx /usr/local/bin/python # where xxxx is the most recent Python 3 version you saw above +If this points to `/usr/local/Cellar/python@2`, then we'll need to change it. +``` +rm /usr/local/bin/python +ln -s /usr/local/Cellar/Python/xxxx /usr/local/bin/python +# where xxxx is the most recent Python 3 version you saw above +``` From b667cf7cfcd9fb81e4497a28161d8801a3a83d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Petazzoni?= Date: Wed, 30 Oct 2019 17:19:25 -0500 Subject: [PATCH 33/45] Update logs-cli.md --- slides/k8s/logs-cli.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slides/k8s/logs-cli.md b/slides/k8s/logs-cli.md index 1017bb52..5dda900b 100644 --- a/slides/k8s/logs-cli.md +++ b/slides/k8s/logs-cli.md @@ -65,7 +65,8 @@ Exactly what we need! https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64 sudo chmod +x /usr/local/bin/stern ``` - On OS X, `brew install stern` + +- On OS X, just `brew install stern` From e08e7848ed45dd564577ca52ec46cba5923cacef Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 31 Oct 2019 16:07:33 -0500 Subject: [PATCH 34/45] Add instructions about shpod --- slides/shared/connecting.md | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/slides/shared/connecting.md b/slides/shared/connecting.md index 2e83d996..eb40ec6d 100644 --- a/slides/shared/connecting.md +++ b/slides/shared/connecting.md @@ -4,7 +4,12 @@ class: in-person .exercise[ -- Log into the first VM (`node1`) with your SSH client +- Log into the first VM (`node1`) with your SSH client: + ```bash + ssh `user`@`A.B.C.D` + ``` + + (Replace `user` and `A.B.C.D` with the user and IP address provided to you) -- Check that you can SSH (without password) to `node2`: - ```bash - ssh node2 - ``` -- Type `exit` or `^D` to come back to `node1` - - - ] +You should see a prompt looking like this: +``` +[A.B.C.D] (...) user@node1 ~ +$ +``` If anything goes wrong — ask for help! --- @@ -52,6 +54,20 @@ If anything goes wrong — ask for help! --- +## For a consistent Kubernetes experience ... + +- If you are using your own Kubernetes cluster, you can use [shpod](https://github.com/jpetazzo/shpod) + +- `shpod` provides a shell running in a pod on your own cluster + +- It comes with many tools pre-installed (helm, stern...) + +- These tools are used in many exercises in these slides + +- `shpod` also gives you completion and a fancy prompt + +--- + class: self-paced ## Get your own Docker nodes From 4ec7b1d7f4aa3927b903d622b10e07b0a8d8a0f8 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 31 Oct 2019 17:15:01 -0500 Subject: [PATCH 35/45] Improve section on healthchecks, and add information about startup probes --- slides/k8s/healthchecks-more.md | 60 -------------- slides/k8s/healthchecks.md | 140 ++++++++++++++++++++++++++++---- 2 files changed, 123 insertions(+), 77 deletions(-) diff --git a/slides/k8s/healthchecks-more.md b/slides/k8s/healthchecks-more.md index fbfb0c9f..a812966c 100644 --- a/slides/k8s/healthchecks-more.md +++ b/slides/k8s/healthchecks-more.md @@ -1,41 +1,3 @@ -## Questions to ask before adding healthchecks - -- Do we want liveness, readiness, both? - - (sometimes, we can use the same check, but with different failure thresholds) - -- Do we have existing HTTP endpoints that we can use? - -- Do we need to add new endpoints, or perhaps use something else? - -- Are our healthchecks likely to use resources and/or slow down the app? - -- Do they depend on additional services? - - (this can be particularly tricky, see next slide) - ---- - -## Healthchecks and dependencies - -- A good healthcheck should always indicate the health of the service itself - -- It should not be affected by the state of the service's dependencies - -- Example: a web server requiring a database connection to operate - - (make sure that the healthcheck can report "OK" even if the database is down; -
- because it won't help us to restart the web server if the issue is with the DB!) - -- Example: a microservice calling other microservices - -- Example: a worker process - - (these will generally require minor code changes to report health) - ---- - ## Adding healthchecks to an app - Let's add healthchecks to DockerCoins! @@ -371,25 +333,3 @@ 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 - -- Readiness isn't useful - - (because worker isn't a backend for a service) - -- Liveness may help us restart a broken worker, but how can we check it? - -- Embedding an HTTP server is an option - - (but it has a high potential for unwanted side effects and false positives) - -- Using a "lease" file can be relatively easy: - - - touch a file during each iteration of the main loop - - - check the timestamp of that file from an exec probe - -- Writing logs (and checking them from the probe) also works diff --git a/slides/k8s/healthchecks.md b/slides/k8s/healthchecks.md index a72fedbf..8055bfd8 100644 --- a/slides/k8s/healthchecks.md +++ b/slides/k8s/healthchecks.md @@ -42,9 +42,11 @@ - internal corruption (causing all requests to error) -- If the liveness probe fails *N* consecutive times, the container is killed +- Anything where our incident response would be "just restart/reboot it" -- *N* is the `failureThreshold` (3 by default) +.warning[**Do not** use liveness probes for problems that can't be fixed by a restart] + +- Otherwise we just restart our pods for no reason, creating useless load --- @@ -52,7 +54,7 @@ - Indicates if the container is ready to serve traffic -- If a container becomes "unready" (let's say busy!) it might be ready again soon +- If a container becomes "unready" it might be ready again soon - If the readiness probe fails: @@ -66,19 +68,79 @@ ## When to use a readiness probe -- To indicate temporary failures +- To indicate failure due to an external cause - - the application can only service *N* parallel connections + - database is down or unreachable - - the runtime is busy doing garbage collection or initial data load + - mandatory auth or other backend service unavailable -- The container is marked as "not ready" after `failureThreshold` failed attempts +- To indicate temporary failure or unavailability - (3 by default) + - application can only service *N* parallel connections -- It is marked again as "ready" after `successThreshold` successful attempts + - runtime is busy doing garbage collection or initial data load - (1 by default) +- For processes that take a long time to start + + (more on that later) + +--- + +## Dependencies + +- If a web server depends on a database to function, and the database is down: + + - the web server's liveness probe should succeed + + - the web server's readiness probe should fail + +- Same thing for any hard dependency (without which the container can't work) + +.warning[**Do not** fail liveness probes for problems that are external to the container] + +--- + +## Timing and thresholds + +- Probes are executed at intervals of `periodSeconds` (default: 10) + +- The timeout for a probe is set with `timeoutSeconds` (default: 1) + +.warning[If a probe takes longer than that, it is considered as a FAIL] + +- A probe is considered successful after `successThreshold` successes (default: 1) + +- A probe is considered failing after `failureThreshold` failures (default: 3) + +- A probe can have an `initialDelaySeconds` parameter (default: 0) + +- Kubernetes will wait that amount of time before running the probe for the first time + + (this is important to avoid killing services that take a long time to start) + +--- + +class: extra-details + +## Startup probe + +- Kubernetes 1.16 introduces a third type of probe: `startupProbe` + + (it is in `alpha` in Kubernetes 1.16) + +- It can be used to indicate "container not ready *yet*" + + - process is still starting + + - loading external data, priming caches + +- Before Kubernetes 1.16, we had to use the `initialDelaySeconds` parameter + + (available for both liveness and readiness probes) + +- `initialDelaySeconds` is a rigid delay (always wait X before running probes) + +- `startupProbe` works better when a container start time can vary a lot --- @@ -112,10 +174,12 @@ (instead of serving errors or timeouts) -- Overloaded backends get removed from load balancer rotation +- Unavailable backends get removed from load balancer rotation (thus improving response times across the board) +- If a probe is not defined, it's as if there was an "always successful" probe + --- ## Example: HTTP probe @@ -165,14 +229,56 @@ If the Redis process becomes unresponsive, it will be killed. --- -## Details about liveness and readiness probes +## Questions to ask before adding healthchecks -- Probes are executed at intervals of `periodSeconds` (default: 10) +- Do we want liveness, readiness, both? -- The timeout for a probe is set with `timeoutSeconds` (default: 1) + (sometimes, we can use the same check, but with different failure thresholds) -- A probe is considered successful after `successThreshold` successes (default: 1) +- Do we have existing HTTP endpoints that we can use? -- A probe is considered failing after `failureThreshold` failures (default: 3) +- Do we need to add new endpoints, or perhaps use something else? -- If a probe is not defined, it's as if there was an "always successful" probe +- Are our healthchecks likely to use resources and/or slow down the app? + +- Do they depend on additional services? + + (this can be particularly tricky, see next slide) + +--- + +## Healthchecks and dependencies + +- Liveness checks should not be influenced by the state of external services + +- All checks should reply quickly (by default, less than 1 second) + +- Otherwise, they are considered to fail + +- This might require to check the health of dependencies asynchronously + + (e.g. if a database or API might be healthy but still take more than + 1 second to reply, we should check the status asynchronously and report + a cached status) + +--- + +## Healthchecks for workers + +(In that context, worker = process that doesn't accept connections) + +- Readiness isn't useful + + (because workers aren't backends for a service) + +- Liveness may help us restart a broken worker, but how can we check it? + +- Embedding an HTTP server is a (potentially expensive) option + +- Using a "lease" file can be relatively easy: + + - touch a file during each iteration of the main loop + + - check the timestamp of that file from an exec probe + +- Writing logs (and checking them from the probe) also works From ff132fd728d76bb516089690c30e2cf500e09471 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 31 Oct 2019 17:26:01 -0500 Subject: [PATCH 36/45] Add mention to Review Access / rakkess --- slides/k8s/authn-authz.md | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/slides/k8s/authn-authz.md b/slides/k8s/authn-authz.md index a2c0c431..57f2c965 100644 --- a/slides/k8s/authn-authz.md +++ b/slides/k8s/authn-authz.md @@ -667,17 +667,12 @@ class: extra-details - For auditing purposes, sometimes we want to know who can perform an action -- There is a proof-of-concept tool by Aqua Security which does exactly that: +- There are a few tools to help us with that - https://github.com/aquasecurity/kubectl-who-can + - [kubectl-who-can](https://github.com/aquasecurity/kubectl-who-can) by Aqua Security -- This is one way to install it: - ```bash - docker run --rm -v /usr/local/bin:/go/bin golang \ - go get -v github.com/aquasecurity/kubectl-who-can - ``` + - [Review Access (aka Rakkess)](https://github.com/corneliusweig/rakkess) -- This is one way to use it: - ```bash - kubectl-who-can create pods - ``` +- Both are available as standalone programs, or as plugins for `kubectl` + + (`kubectl` plugins can be installed and managed with `krew`) From 7d4331477a1eba394b4c93ef196d5b3697efec55 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 31 Oct 2019 19:49:35 -0500 Subject: [PATCH 37/45] Get rid of $TAG and $REGISTRY These variables are useful when deploying images from a local registry (or from another place than the Docker Hub) but they turned out to be quite confusing. After holding to them for a while, I think it is time to see the errors of my ways and simplify that stuff. --- slides/k8s/buildshiprun-dockerhub.md | 23 ----------- slides/k8s/ourapponkube.md | 28 ++++++++++++-- slides/k8s/rollout.md | 58 +++++----------------------- 3 files changed, 33 insertions(+), 76 deletions(-) diff --git a/slides/k8s/buildshiprun-dockerhub.md b/slides/k8s/buildshiprun-dockerhub.md index 1a75774f..3d414c49 100644 --- a/slides/k8s/buildshiprun-dockerhub.md +++ b/slides/k8s/buildshiprun-dockerhub.md @@ -15,26 +15,3 @@ - `dockercoins/webui:v0.1` - `dockercoins/worker:v0.1` - ---- - -## Setting `$REGISTRY` and `$TAG` - -- In the upcoming exercises and labs, we use a couple of environment variables: - - - `$REGISTRY` as a prefix to all image names - - - `$TAG` as the image version tag - -- For example, the worker image is `$REGISTRY/worker:$TAG` - -- If you copy-paste the commands in these exercises: - - **make sure that you set `$REGISTRY` and `$TAG` first!** - -- For example: - ```bash - export REGISTRY=dockercoins TAG=v0.1 - ``` - - (this will expand `$REGISTRY/worker:$TAG` to `dockercoins/worker:v0.1`) diff --git a/slides/k8s/ourapponkube.md b/slides/k8s/ourapponkube.md index 50eed1ea..abe48620 100644 --- a/slides/k8s/ourapponkube.md +++ b/slides/k8s/ourapponkube.md @@ -11,16 +11,36 @@ - Deploy everything else: ```bash - set -u - for SERVICE in hasher rng webui worker; do - kubectl create deployment $SERVICE --image=$REGISTRY/$SERVICE:$TAG - done + kubectl create deployment hasher --image=dockercoins/hasher:v0.1 + kubectl create deployment rng --image=dockercoins/rng:v0.1 + kubectl create deployment webui --image=dockercoins/webui:v0.1 + kubectl create deployment worker --image=dockercoins/worker:v0.1 ``` ] --- +class: extra-details + +## Deploying other images + +- If we wanted to deploy images from another registry ... + +- ... Or with a different tag ... + +- ... We could use the following snippet: + +```bash + REGISTRY=dockercoins + TAG=v0.1 + for SERVICE in hasher rng webui worker; do + kubectl create deployment $SERVICE --image=$REGISTRY/$SERVICE:$TAG + done +``` + +--- + ## Is this working? - After waiting for the deployment to complete, let's look at the logs! diff --git a/slides/k8s/rollout.md b/slides/k8s/rollout.md index 5783c020..41aba22d 100644 --- a/slides/k8s/rollout.md +++ b/slides/k8s/rollout.md @@ -61,32 +61,6 @@ --- -## Building a new version of the `worker` service - -.warning[ -Only run these commands if you have built and pushed DockerCoins to a local registry. -
-If you are using images from the Docker Hub (`dockercoins/worker:v0.1`), skip this. -] - -.exercise[ - -- Go to the `stacks` directory (`~/container.training/stacks`) - -- Edit `dockercoins/worker/worker.py`; update the first `sleep` line to sleep 1 second - -- Build a new tag and push it to the registry: - ```bash - #export REGISTRY=localhost:3xxxx - export TAG=v0.2 - docker-compose -f dockercoins.yml build - docker-compose -f dockercoins.yml push - ``` - -] - ---- - ## Rolling out the new `worker` service .exercise[ @@ -105,7 +79,7 @@ If you are using images from the Docker Hub (`dockercoins/worker:v0.1`), skip th - Update `worker` either with `kubectl edit`, or by running: ```bash - kubectl set image deploy worker worker=$REGISTRY/worker:$TAG + kubectl set image deploy worker worker=dockercoins/worker:v0.2 ``` ] @@ -146,8 +120,7 @@ That rollout should be pretty quick. What shows in the web UI? - Update `worker` by specifying a non-existent image: ```bash - export TAG=v0.3 - kubectl set image deploy worker worker=$REGISTRY/worker:$TAG + kubectl set image deploy worker worker=dockercoins/worker:v0.3 ``` - Check what's going on: @@ -216,27 +189,14 @@ If you didn't deploy the Kubernetes dashboard earlier, just skip this slide. .exercise[ -- Check which port the dashboard is on: - ```bash - kubectl -n kube-system get svc socat - ``` +- Connect to the dashboard that we deployed earlier + +- Check that we have failures in Deployments, Pods, and Replica Sets + +- Can we see the reason for the failure? ] -Note the `3xxxx` port. - -.exercise[ - -- Connect to http://oneofournodes:3xxxx/ - - - -] - --- - -- We have failures in Deployments, Pods, and Replica Sets - --- ## Recovering from a bad rollout @@ -285,7 +245,7 @@ spec: spec: containers: - name: worker - image: $REGISTRY/worker:v0.1 + image: dockercoins/worker:v0.1 strategy: rollingUpdate: maxUnavailable: 0 @@ -316,7 +276,7 @@ class: extra-details spec: containers: - name: worker - image: $REGISTRY/worker:v0.1 + image: dockercoins/worker:v0.1 strategy: rollingUpdate: maxUnavailable: 0 From c9bc417a328814ea6744945542b7ac892b0b5e78 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 31 Oct 2019 20:19:33 -0500 Subject: [PATCH 38/45] Update logs section --- slides/k8s/kubectlrun.md | 74 ++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/slides/k8s/kubectlrun.md b/slides/k8s/kubectlrun.md index 2c8a9c2b..240bb0e7 100644 --- a/slides/k8s/kubectlrun.md +++ b/slides/k8s/kubectlrun.md @@ -153,10 +153,7 @@ pod/pingpong-7c8bbcd9bc-6c9qz 1/1 Running 0 10m kubectl logs deploy/pingpong --tail 1 --follow ``` - +- Leave that command running, so that we can keep an eye on these logs ] @@ -186,6 +183,44 @@ We could! But the *deployment* would notice it right away, and scale back to the --- +## Log streaming + +- Let's look again at the output of `kubectl logs` + + (the one we started before scaling up) + +- `kubectl logs` shows us one line per second + +- We could expect 3 lines per second + + (since we should now have 3 pods running `ping`) + +- Let's try to figure out what's happening! + +--- + +## Streaming logs of multiple pods + +- What happens if we restart `kubectl logs`? + +.exercise[ + +- Interrupt `kubectl logs` (with Ctrl-C) + +- Restart it: + ```bash + kubectl logs deploy/pingpong --tail 1 --follow + ``` + +] + +`kubectl logs` will warn us that multiple pods were found, and that it's showing us only one of them. + +Let's leave `kubectl logs` running while we keep exploring. + +--- + + ## Resilience - The *deployment* `pingpong` watches its *replica set* @@ -196,20 +231,12 @@ We could! But the *deployment* would notice it right away, and scale back to the .exercise[ -- In a separate window, list pods, and keep watching them: +- In a separate window, watch the list of pods: ```bash - kubectl get pods -w + watch kubectl get pods ``` - - -- Destroy a pod: +- Destroy the pod currently shown by `kubectl logs`: ``` kubectl delete pod pingpong-xxxxxxxxxx-yyyyy ``` @@ -217,6 +244,23 @@ We could! But the *deployment* would notice it right away, and scale back to the --- +## What happened? + +- `kubectl delete pod` terminates the pod gracefully + + (sending it the TERM signal and waiting for it to shutdown) + +- As soon as the pod is in "Terminating" state, the Replica Set replaces it + +- But we can still see the output of the "Terminating" pod in `kubectl logs` + +- Until 30 seconds later, when the grace period expires + +- The pod is then killed, and `kubectl logs` exits + +--- + + ## What if we wanted something different? - What if we wanted to start a "one-shot" container that *doesn't* get restarted? From 7444f8d71e0998532d153b8a7aa57ea99d9b2e85 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 1 Nov 2019 22:46:43 -0500 Subject: [PATCH 39/45] Add cronjobs and YAML catch up instructions --- k8s/dockercoins.yaml | 160 ++++++++++++++++++++++++++++++++++++++ slides/k8s/kubectlrun.md | 66 ++++++++++++++++ slides/k8s/yamldeploy.md | 93 ++++++++++++++++++++++ slides/kube-fullday.yml | 11 +-- slides/kube-selfpaced.yml | 7 +- slides/kube-twodays.yml | 15 ++-- 6 files changed, 337 insertions(+), 15 deletions(-) create mode 100644 k8s/dockercoins.yaml create mode 100644 slides/k8s/yamldeploy.md diff --git a/k8s/dockercoins.yaml b/k8s/dockercoins.yaml new file mode 100644 index 00000000..4e754715 --- /dev/null +++ b/k8s/dockercoins.yaml @@ -0,0 +1,160 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: hasher + name: hasher +spec: + replicas: 1 + selector: + matchLabels: + app: hasher + template: + metadata: + labels: + app: hasher + spec: + containers: + - image: dockercoins/hasher:v0.1 + name: hasher +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: hasher + name: hasher +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: hasher + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: redis + name: redis +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - image: redis + name: redis +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: redis + name: redis +spec: + ports: + - port: 6379 + protocol: TCP + targetPort: 6379 + selector: + app: redis + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: rng + name: rng +spec: + replicas: 1 + selector: + matchLabels: + app: rng + template: + metadata: + labels: + app: rng + spec: + containers: + - image: dockercoins/rng:v0.1 + name: rng +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: rng + name: rng +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: rng + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: webui + name: webui +spec: + replicas: 1 + selector: + matchLabels: + app: webui + template: + metadata: + labels: + app: webui + spec: + containers: + - image: dockercoins/webui:v0.1 + name: webui +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: webui + name: webui +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: webui + type: NodePort +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: worker + name: worker +spec: + replicas: 1 + selector: + matchLabels: + app: worker + template: + metadata: + labels: + app: worker + spec: + containers: + - image: dockercoins/worker:v0.1 + name: worker diff --git a/slides/k8s/kubectlrun.md b/slides/k8s/kubectlrun.md index 240bb0e7..9b7ae2ec 100644 --- a/slides/k8s/kubectlrun.md +++ b/slides/k8s/kubectlrun.md @@ -278,6 +278,72 @@ Let's leave `kubectl logs` running while we keep exploring. --- +## Scheduling periodic background work + +- A Cron Job is a job that will be executed at specific intervals + + (the name comes from the traditional cronjobs executed by the UNIX crond) + +- It requires a *schedule*, represented as five space-separated fields: + + - minute [0,59] + - hour [0,23] + - day of the month [1,31] + - month of the year [1,12] + - day of the week ([0,6] with 0=Sunday) + +- `*` means "all valid values"; `/N` means "every N" + +- Example: `*/3 * * * *` means "every three minutes" + +--- + +## Creating a Cron Job + +- Let's create a simple job to be executed every three minutes + +- Cron Jobs need to terminate, otherwise they'd run forever + +.exercise[ + +- Create the Cron Job: + ```bash + kubectl run --schedule="*/3 * * * *" --restart=OnFailure --image=alpine sleep 10 + ``` + +- Check the resource that was created: + ```bash + kubectl get cronjobs + ``` + +] + +--- + +## Cron Jobs in action + +- At the specified schedule, the Cron Job will create a Job + +- The Job will create a Pod + +- The Job will make sure that the Pod completes + + (re-creating another one if it fails, for instance if its node fails) + +.exercise[ + +- Check the Jobs that are created: + ```bash + kubectl get jobs + ``` + +] + +(It will take a few minutes before the first job is scheduled.) + +--- + + ## What about that deprecation warning? - As we can see from the previous slide, `kubectl run` can do many things diff --git a/slides/k8s/yamldeploy.md b/slides/k8s/yamldeploy.md new file mode 100644 index 00000000..f9bf9250 --- /dev/null +++ b/slides/k8s/yamldeploy.md @@ -0,0 +1,93 @@ +# Deploying with YAML + +- So far, we created resources with the following commands: + + - `kubectl run` + + - `kubectl create deployment` + + - `kubectl expose` + +- We can also create resources directly with YAML manifests + +--- + +## `kubectl apply` vs `create` + +- `kubectl create -f whatever.yaml` + + - creates resources if they don't exist + + - if resources already exist, don't alter them +
(and display error message) + +- `kubectl apply -f whatever.yaml` + + - creates resources if they don't exist + + - if resources already exist, update them +
(to match the definition provided by the YAML file) + + - stores the manifest as an *annotation* in the resource + +--- + +## Creating multiple resources + +- The manifest can contain multiple resources separated by `---` + +```yaml + kind: ... + apiVersion: ... + metadata: ... + name: ... + ... + --- + kind: ... + apiVersion: ... + metadata: ... + name: ... + ... +``` + +--- + +## Creating multiple resources + +- The manifest can also contain a list of resources + +```yaml + apiVersion: v1 + kind: List + items: + - kind: ... + apiVersion: ... + ... + - kind: ... + apiVersion: ... + ... +``` + +--- + +## Deploying dockercoins with YAML + +- We provide a YAML manifest with all the resources for Dockercoins + + (Deployments and Services) + +- We can use it if we need to deploy or redeploy Dockercoins + +.exercise[ + +- Deploy or redeploy Dockercoins: + ```bash + kubectl apply -f ~/container.training/k8s/dockercoins.yaml + ``` + +] + +(If we deployed Dockercoins earlier, we will see warning messages, +because the resources that we created lack the necessary annotation. +We can safely ignore them.) + diff --git a/slides/kube-fullday.yml b/slides/kube-fullday.yml index 35574248..06049482 100644 --- a/slides/kube-fullday.yml +++ b/slides/kube-fullday.yml @@ -23,7 +23,7 @@ chapters: - shared/prereqs.md #- shared/webssh.md - shared/connecting.md - - k8s/versions-k8s.md + #- k8s/versions-k8s.md - shared/sampleapp.md #- shared/composescale.md #- shared/hastyconclusions.md @@ -42,17 +42,18 @@ chapters: #- k8s/buildshiprun-selfhosted.md - k8s/buildshiprun-dockerhub.md - k8s/ourapponkube.md - #- k8s/kubectlproxy.md - #- k8s/localkubeconfig.md - #- k8s/accessinternal.md - - - k8s/setup-k8s.md + - k8s/yamldeploy.md + #- k8s/setup-k8s.md - k8s/dashboard.md #- k8s/kubectlscale.md - k8s/scalingdockercoins.md - shared/hastyconclusions.md - k8s/daemonset.md #- k8s/dryrun.md + #- k8s/kubectlproxy.md + #- k8s/localkubeconfig.md + #- k8s/accessinternal.md - k8s/rollout.md #- k8s/healthchecks.md #- k8s/healthchecks-more.md diff --git a/slides/kube-selfpaced.yml b/slides/kube-selfpaced.yml index 9a21f941..e4823caa 100644 --- a/slides/kube-selfpaced.yml +++ b/slides/kube-selfpaced.yml @@ -43,9 +43,7 @@ chapters: - k8s/buildshiprun-dockerhub.md - k8s/ourapponkube.md - - - k8s/kubectlproxy.md - - k8s/localkubeconfig.md - - k8s/accessinternal.md + - k8s/yamldeploy.md - k8s/setup-k8s.md - k8s/dashboard.md #- k8s/kubectlscale.md @@ -53,6 +51,9 @@ chapters: - shared/hastyconclusions.md - k8s/daemonset.md - k8s/dryrun.md + - k8s/kubectlproxy.md + - k8s/localkubeconfig.md + - k8s/accessinternal.md - - k8s/rollout.md - k8s/healthchecks.md diff --git a/slides/kube-twodays.yml b/slides/kube-twodays.yml index eb976900..b8666817 100644 --- a/slides/kube-twodays.yml +++ b/slides/kube-twodays.yml @@ -23,7 +23,7 @@ chapters: - shared/prereqs.md #- shared/webssh.md - shared/connecting.md - - k8s/versions-k8s.md + #- k8s/versions-k8s.md - shared/sampleapp.md #- shared/composescale.md #- shared/hastyconclusions.md @@ -43,20 +43,21 @@ chapters: - k8s/buildshiprun-dockerhub.md - k8s/ourapponkube.md - - - k8s/kubectlproxy.md - - k8s/localkubeconfig.md - - k8s/accessinternal.md - - k8s/setup-k8s.md + - k8s/yamldeploy.md + #- k8s/setup-k8s.md - k8s/dashboard.md #- k8s/kubectlscale.md - k8s/scalingdockercoins.md - shared/hastyconclusions.md - k8s/daemonset.md -- - k8s/dryrun.md +- + #- k8s/kubectlproxy.md + - k8s/localkubeconfig.md + - k8s/accessinternal.md - k8s/rollout.md - k8s/healthchecks.md - - k8s/healthchecks-more.md + #- k8s/healthchecks-more.md - k8s/record.md - - k8s/namespaces.md From 74ece659471d6869709d61a634f782153f49d6f5 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Sun, 3 Nov 2019 07:11:05 -0600 Subject: [PATCH 40/45] Add Velocity slides --- slides/index.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/slides/index.yaml b/slides/index.yaml index c98a0d1a..788d3b1f 100644 --- a/slides/index.yaml +++ b/slides/index.yaml @@ -5,6 +5,7 @@ speaker: jpetazzo title: Deploying and scaling applications with Kubernetes attend: https://conferences.oreilly.com/velocity/vl-eu/public/schedule/detail/79109 + slides: https://velocity-2019-11.container.training/ - date: 2019-11-13 country: fr From 8320534a5c10272ca9f68a1256baccfce4a85329 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Sun, 3 Nov 2019 07:42:24 -0600 Subject: [PATCH 41/45] Add prefix to slide numbers --- slides/intro-fullday.yml | 2 ++ slides/intro-selfpaced.yml | 2 ++ slides/kadm-fullday.yml | 2 ++ slides/kadm-twodays.yml | 2 ++ slides/kube-fullday.yml | 2 ++ slides/kube-halfday.yml | 2 ++ slides/kube-selfpaced.yml | 2 ++ slides/kube-twodays.yml | 2 ++ slides/markmaker.py | 3 ++- slides/swarm-fullday.yml | 2 ++ slides/swarm-halfday.yml | 2 ++ slides/swarm-selfpaced.yml | 2 ++ slides/swarm-video.yml | 2 ++ slides/workshop.html | 1 + 14 files changed, 27 insertions(+), 1 deletion(-) diff --git a/slides/intro-fullday.yml b/slides/intro-fullday.yml index b137fb59..a0e31be0 100644 --- a/slides/intro-fullday.yml +++ b/slides/intro-fullday.yml @@ -9,6 +9,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced diff --git a/slides/intro-selfpaced.yml b/slides/intro-selfpaced.yml index 5ebc32c5..14c494b3 100644 --- a/slides/intro-selfpaced.yml +++ b/slides/intro-selfpaced.yml @@ -9,6 +9,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - in-person diff --git a/slides/kadm-fullday.yml b/slides/kadm-fullday.yml index 18d0a334..9e63d8eb 100644 --- a/slides/kadm-fullday.yml +++ b/slides/kadm-fullday.yml @@ -10,6 +10,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced - static-pods-exercise diff --git a/slides/kadm-twodays.yml b/slides/kadm-twodays.yml index 2c5d4c66..ac78d49f 100644 --- a/slides/kadm-twodays.yml +++ b/slides/kadm-twodays.yml @@ -11,6 +11,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced diff --git a/slides/kube-fullday.yml b/slides/kube-fullday.yml index 06049482..47449152 100644 --- a/slides/kube-fullday.yml +++ b/slides/kube-fullday.yml @@ -10,6 +10,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced diff --git a/slides/kube-halfday.yml b/slides/kube-halfday.yml index 4a4856b2..1cbc5337 100644 --- a/slides/kube-halfday.yml +++ b/slides/kube-halfday.yml @@ -10,6 +10,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced diff --git a/slides/kube-selfpaced.yml b/slides/kube-selfpaced.yml index e4823caa..3cf05c7f 100644 --- a/slides/kube-selfpaced.yml +++ b/slides/kube-selfpaced.yml @@ -10,6 +10,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - in-person diff --git a/slides/kube-twodays.yml b/slides/kube-twodays.yml index b8666817..992c7d68 100644 --- a/slides/kube-twodays.yml +++ b/slides/kube-twodays.yml @@ -10,6 +10,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced diff --git a/slides/markmaker.py b/slides/markmaker.py index dd50291f..37cbf6bc 100755 --- a/slides/markmaker.py +++ b/slides/markmaker.py @@ -80,7 +80,7 @@ def flatten(titles): def generatefromyaml(manifest, filename): - manifest = yaml.load(manifest) + manifest = yaml.safe_load(manifest) markdown, titles = processchapter(manifest["chapters"], filename) logging.debug("Found {} titles.".format(len(titles))) @@ -111,6 +111,7 @@ def generatefromyaml(manifest, filename): html = html.replace("@@GITREPO@@", manifest["gitrepo"]) html = html.replace("@@SLIDES@@", manifest["slides"]) html = html.replace("@@TITLE@@", manifest["title"].replace("\n", " ")) + html = html.replace("@@SLIDENUMBERPREFIX@@", manifest.get("slidenumberprefix", "")) return html diff --git a/slides/swarm-fullday.yml b/slides/swarm-fullday.yml index 8f30665d..279be3d1 100644 --- a/slides/swarm-fullday.yml +++ b/slides/swarm-fullday.yml @@ -9,6 +9,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced - snap diff --git a/slides/swarm-halfday.yml b/slides/swarm-halfday.yml index a80a0733..30029a95 100644 --- a/slides/swarm-halfday.yml +++ b/slides/swarm-halfday.yml @@ -9,6 +9,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - self-paced - snap diff --git a/slides/swarm-selfpaced.yml b/slides/swarm-selfpaced.yml index 2510eed5..36e1d353 100644 --- a/slides/swarm-selfpaced.yml +++ b/slides/swarm-selfpaced.yml @@ -8,6 +8,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - in-person - btp-auto diff --git a/slides/swarm-video.yml b/slides/swarm-video.yml index 0d361a40..02c1e6b2 100644 --- a/slides/swarm-video.yml +++ b/slides/swarm-video.yml @@ -8,6 +8,8 @@ gitrepo: github.com/jpetazzo/container.training slides: http://container.training/ +#slidenumberprefix: "#SomeHashTag — " + exclude: - in-person - btp-auto diff --git a/slides/workshop.html b/slides/workshop.html index ffb378ce..96f56b04 100644 --- a/slides/workshop.html +++ b/slides/workshop.html @@ -28,6 +28,7 @@ var slideshow = remark.create({ ratio: '16:9', highlightSpans: true, + slideNumberFormat: '@@SLIDENUMBERPREFIX@@%current%/%total%', excludedClasses: [@@EXCLUDE@@] }); From 98d2b79c97ab98681998d53660892174e709a439 Mon Sep 17 00:00:00 2001 From: Sean OMeara Date: Mon, 4 Nov 2019 10:08:04 +0100 Subject: [PATCH 42/45] adding editors --- prepare-vms/lib/postprep.py | 1 + 1 file changed, 1 insertion(+) diff --git a/prepare-vms/lib/postprep.py b/prepare-vms/lib/postprep.py index 14c45478..3ee70ed4 100755 --- a/prepare-vms/lib/postprep.py +++ b/prepare-vms/lib/postprep.py @@ -106,6 +106,7 @@ system("sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /e system("sudo service ssh restart") system("sudo apt-get -q update") system("sudo apt-get -qy install git jq") +system("sudo apt-get -qy install emacs-nox joe") ####################### ### DOCKER INSTALLS ### From eb17b4c62879806b13db6f6c2357555ea0fb84d3 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 7 Nov 2019 11:15:14 -0600 Subject: [PATCH 43/45] Tweak single-day workshop content --- slides/k8s/setup-k8s.md | 3 ++- slides/kube-fullday.yml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/slides/k8s/setup-k8s.md b/slides/k8s/setup-k8s.md index 6b704ef0..91740afa 100644 --- a/slides/k8s/setup-k8s.md +++ b/slides/k8s/setup-k8s.md @@ -61,7 +61,8 @@ - [minikube](https://kubernetes.io/docs/setup/minikube/), [kubespawn](https://github.com/kinvolk/kube-spawn), - [Docker Desktop](https://docs.docker.com/docker-for-mac/kubernetes/): + [Docker Desktop](https://docs.docker.com/docker-for-mac/kubernetes/), + [kind](https://kind.sigs.k8s.io): for local development - [kubicorn](https://github.com/kubicorn/kubicorn), diff --git a/slides/kube-fullday.yml b/slides/kube-fullday.yml index 47449152..9687dc1e 100644 --- a/slides/kube-fullday.yml +++ b/slides/kube-fullday.yml @@ -46,8 +46,8 @@ chapters: - k8s/ourapponkube.md - - k8s/yamldeploy.md - #- k8s/setup-k8s.md - - k8s/dashboard.md + - k8s/setup-k8s.md + #- k8s/dashboard.md #- k8s/kubectlscale.md - k8s/scalingdockercoins.md - shared/hastyconclusions.md From bbe35a39016b7ae9cf724728a30783515d05e53a Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 7 Nov 2019 11:21:20 -0600 Subject: [PATCH 44/45] Update the mention of Prometheus exposition format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks @qerub for letting me know that the protobuf format was deprecated in Prom 2. Also, that technical document by @beorn7 is a real delight to read. 💯 --- slides/k8s/prometheus.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slides/k8s/prometheus.md b/slides/k8s/prometheus.md index 9032657c..049bea18 100644 --- a/slides/k8s/prometheus.md +++ b/slides/k8s/prometheus.md @@ -60,10 +60,12 @@ (by default: every minute; can be more/less frequent) -- If you're worried about parsing overhead: exporters can also use protobuf - - The list of URLs to scrape (the *scrape targets*) is defined in configuration +.footnote[Worried about the overhead of parsing a text format? +
+Check this [comparison](https://github.com/RichiH/OpenMetrics/blob/master/markdown/protobuf_vs_text.md) of the text format with the (now deprecated) protobuf format!] + --- ## Defining scrape targets From bc885f3dcaee88cdee06ccd121d81a0b8d3c9b39 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Thu, 7 Nov 2019 11:39:19 -0600 Subject: [PATCH 45/45] Update information re/ JVM resource limits Thanks @qerub for the heads up. --- slides/k8s/configuration.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/slides/k8s/configuration.md b/slides/k8s/configuration.md index 47b23ca7..0283e888 100644 --- a/slides/k8s/configuration.md +++ b/slides/k8s/configuration.md @@ -193,7 +193,12 @@ - Best practice: set a memory limit, and pass it to the runtime - (see [this blog post](https://very-serio.us/2017/12/05/running-jvms-in-kubernetes/) for a detailed example) +- Note: recent versions of the JVM can do this automatically + + (see [JDK-8146115](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8146115)) + and + [this blog post](https://very-serio.us/2017/12/05/running-jvms-in-kubernetes/) + for detailed examples) ---
cluster: