From 7d6ab6974db10d746bdd2e16fae870c34093bf51 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Sat, 18 Jan 2020 09:49:18 -0600 Subject: [PATCH] Big autopilot update 'keys' does not handle special keys (like ^J) anymore. Instead, we should use `key`, which will pass its entire argument to tmux, without any processing. It is therefore possible to do something like: ```key ^C``` Or ```key Escape``` Most (if not all) calls to special keys have been converted to use 'key' instead of 'keys'. Action ```copypaste``` has been deprecated in favor of three separate actions: ```copy REGEX``` (searches the regex in the active pane, and if found, places it in an internal clipboard) ```paste``` (inserts the content of the clipboard as keystrokes) ```check``` (forces a status check) Also, a 'tmux' command has been added. It allows to do stuff like: ```tmux split-pane -v``` --- k8s/efk.yaml | 6 +++ slides/autopilot/autotest.py | 52 ++++++++++++++----- slides/containers/links.md | 13 ++++- slides/k8s/accessinternal.md | 4 +- slides/k8s/authn-authz.md | 2 +- slides/k8s/build-with-docker.md | 2 +- slides/k8s/build-with-kaniko.md | 2 +- slides/k8s/daemonset.md | 44 ++++++++++------ slides/k8s/dryrun.md | 2 + slides/k8s/horizontal-pod-autoscaler.md | 69 +++++++++++++++++++++++-- slides/k8s/kubectlexpose.md | 7 ++- slides/k8s/kubectlproxy.md | 2 +- slides/k8s/kubectlrun.md | 41 ++++++++++++++- slides/k8s/kubectlscale.md | 4 +- slides/k8s/kustomize.md | 7 +++ slides/k8s/logs-cli.md | 18 +++---- slides/k8s/netpol.md | 11 ++++ slides/k8s/ourapponkube.md | 2 +- slides/k8s/podsecuritypolicy.md | 33 ++++++++++++ slides/k8s/portworx.md | 12 ++--- slides/k8s/rollout.md | 12 ++--- slides/k8s/scalingdockercoins.md | 12 +++-- slides/k8s/shippingimages.md | 5 ++ slides/k8s/statefulsets.md | 2 +- slides/k8s/volumes.md | 25 +++++++++ slides/shared/composescale.md | 6 +-- slides/shared/sampleapp.md | 2 +- slides/swarm/creatingswarm.md | 2 +- slides/swarm/ipsec.md | 2 +- slides/swarm/logging.md | 4 +- 30 files changed, 323 insertions(+), 82 deletions(-) mode change 120000 => 100644 slides/containers/links.md diff --git a/k8s/efk.yaml b/k8s/efk.yaml index f2c9ea84..cb1e97d4 100644 --- a/k8s/efk.yaml +++ b/k8s/efk.yaml @@ -3,6 +3,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: fluentd + namespace: default --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole @@ -36,6 +37,7 @@ apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd + namespace: default labels: app: fluentd spec: @@ -95,6 +97,7 @@ metadata: labels: app: elasticsearch name: elasticsearch + namespace: default spec: selector: matchLabels: @@ -122,6 +125,7 @@ metadata: labels: app: elasticsearch name: elasticsearch + namespace: default spec: ports: - port: 9200 @@ -137,6 +141,7 @@ metadata: labels: app: kibana name: kibana + namespace: default spec: selector: matchLabels: @@ -160,6 +165,7 @@ metadata: labels: app: kibana name: kibana + namespace: default spec: ports: - port: 5601 diff --git a/slides/autopilot/autotest.py b/slides/autopilot/autotest.py index 760de79c..cdd3e603 100755 --- a/slides/autopilot/autotest.py +++ b/slides/autopilot/autotest.py @@ -26,6 +26,7 @@ IPADDR = None class State(object): def __init__(self): + self.clipboard = "" self.interactive = True self.verify_status = False self.simulate_type = True @@ -38,6 +39,7 @@ class State(object): def load(self): data = yaml.load(open("state.yaml")) + self.clipboard = str(data["clipboard"]) self.interactive = bool(data["interactive"]) self.verify_status = bool(data["verify_status"]) self.simulate_type = bool(data["simulate_type"]) @@ -51,6 +53,7 @@ class State(object): def save(self): with open("state.yaml", "w") as f: yaml.dump(dict( + clipboard=self.clipboard, interactive=self.interactive, verify_status=self.verify_status, simulate_type=self.simulate_type, @@ -85,9 +88,11 @@ class Snippet(object): # On single-line snippets, the data follows the method immediately if '\n' in content: self.method, self.data = content.split('\n', 1) - else: + self.data = self.data.strip() + elif ' ' in content: self.method, self.data = content.split(' ', 1) - self.data = self.data.strip() + else: + self.method, self.data = content, None self.next = None def __str__(self): @@ -186,7 +191,7 @@ def wait_for_prompt(): if last_line == "$": # This is a perfect opportunity to grab the node's IP address global IPADDR - IPADDR = re.findall("^\[(.*)\]", output, re.MULTILINE)[-1] + IPADDR = re.findall("\[(.*)\]", output, re.MULTILINE)[-1] return # When we are in an alpine container, the prompt will be "/ #" if last_line == "/ #": @@ -264,19 +269,31 @@ for slide in re.split("\n---?\n", content): slides.append(Slide(slide)) +# Send a single key. +# Useful for special keys, e.g. tmux interprets these strings: +# ^C (and all other sequences starting with a caret) +# Space +# ... and many others (check tmux manpage for details). +def send_key(data): + subprocess.check_call(["tmux", "send-keys", data]) + + +# Send multiple keys. +# If keystroke simulation is off, all keys are sent at once. +# If keystroke simulation is on, keys are sent one by one, with a delay between them. def send_keys(data): - if state.simulate_type and data[0] != '^': + if not state.simulate_type: + subprocess.check_call(["tmux", "send-keys", data]) + else: for key in data: if key == ";": key = "\\;" if key == "\n": if interruptible_sleep(1): return - subprocess.check_call(["tmux", "send-keys", key]) + send_key(key) if interruptible_sleep(0.15*random.random()): return if key == "\n": if interruptible_sleep(1): return - else: - subprocess.check_call(["tmux", "send-keys", data]) def capture_pane(): @@ -323,7 +340,10 @@ def check_bounds(): while True: state.save() slide = slides[state.slide] - snippet = slide.snippets[state.snippet-1] if state.snippet else None + if state.snippet and state.snippet <= len(slide.snippets): + snippet = slide.snippets[state.snippet-1] + else: + snippet = None click.clear() print("[Slide {}/{}] [Snippet {}/{}] [simulate_type:{}] [verify_status:{}] " "[switch_desktop:{}] [sync_slides:{}] [open_links:{}] [run_hidden:{}]" @@ -398,7 +418,9 @@ while True: continue method, data = snippet.method, snippet.data logging.info("Running with method {}: {}".format(method, data)) - if method == "keys": + if method == "key": + send_key(data) + elif method == "keys": send_keys(data) elif method == "bash" or (method == "hide" and state.run_hidden): # Make sure that we're ready @@ -421,7 +443,7 @@ while True: wait_for_prompt() # Verify return code check_exit_status() - elif method == "copypaste": + elif method == "copy": screen = capture_pane() matches = re.findall(data, screen, flags=re.DOTALL) if len(matches) == 0: @@ -430,8 +452,12 @@ while True: match = matches[-1] # Remove line breaks (like a screen copy paste would do) match = match.replace('\n', '') - send_keys(match + '\n') - # FIXME: we should factor out the "bash" method + logging.info("Copied {} to clipboard.".format(match)) + state.clipboard = match + elif method == "paste": + logging.info("Pasting {} from clipboard.".format(state.clipboard)) + send_keys(state.clipboard) + elif method == "check": wait_for_prompt() check_exit_status() elif method == "open": @@ -445,6 +471,8 @@ while True: if state.interactive: print("Press any key to continue to next step...") click.getchar() + elif method == "tmux": + subprocess.check_call(["tmux"] + data.split()) else: logging.warning("Unknown method {}: {!r}".format(method, data)) move_forward() diff --git a/slides/containers/links.md b/slides/containers/links.md deleted file mode 120000 index 3b5a5fbc..00000000 --- a/slides/containers/links.md +++ /dev/null @@ -1 +0,0 @@ -../swarm/links.md \ No newline at end of file diff --git a/slides/containers/links.md b/slides/containers/links.md new file mode 100644 index 00000000..f824ca98 --- /dev/null +++ b/slides/containers/links.md @@ -0,0 +1,12 @@ +# Links and resources + +- [Docker Community Slack](https://community.docker.com/registrations/groups/4316) +- [Docker Community Forums](https://forums.docker.com/) +- [Docker Hub](https://hub.docker.com) +- [Docker Blog](https://blog.docker.com/) +- [Docker documentation](https://docs.docker.com/) +- [Docker on StackOverflow](https://stackoverflow.com/questions/tagged/docker) +- [Docker on Twitter](https://twitter.com/docker) +- [Play With Docker Hands-On Labs](https://training.play-with-docker.com/) + +.footnote[These slides (and future updates) are on → https://container.training/] diff --git a/slides/k8s/accessinternal.md b/slides/k8s/accessinternal.md index 437ffbf5..6767f44f 100644 --- a/slides/k8s/accessinternal.md +++ b/slides/k8s/accessinternal.md @@ -118,9 +118,9 @@ installed and set up `kubectl` to communicate with your cluster. - Terminate the port forwarder: diff --git a/slides/k8s/authn-authz.md b/slides/k8s/authn-authz.md index 57f2c965..a27b8424 100644 --- a/slides/k8s/authn-authz.md +++ b/slides/k8s/authn-authz.md @@ -547,7 +547,7 @@ It's important to note a couple of details in these flags... - Exit the container with `exit` or `^D` - + ] diff --git a/slides/k8s/build-with-docker.md b/slides/k8s/build-with-docker.md index ec2e9a20..8e73c042 100644 --- a/slides/k8s/build-with-docker.md +++ b/slides/k8s/build-with-docker.md @@ -109,7 +109,7 @@ spec: ] diff --git a/slides/k8s/build-with-kaniko.md b/slides/k8s/build-with-kaniko.md index be28a94a..6db7913b 100644 --- a/slides/k8s/build-with-kaniko.md +++ b/slides/k8s/build-with-kaniko.md @@ -174,7 +174,7 @@ spec: ] diff --git a/slides/k8s/daemonset.md b/slides/k8s/daemonset.md index 44e071f6..d6668748 100644 --- a/slides/k8s/daemonset.md +++ b/slides/k8s/daemonset.md @@ -110,20 +110,22 @@ ```bash vim rng.yml``` ```wait kind: Deployment``` ```keys /Deployment``` -```keys ^J``` +```key ^J``` ```keys cwDaemonSet``` -```keys ^[``` ] +```key ^[``` ] ```keys :wq``` -```keys ^J``` +```key ^J``` --> - Save, quit - Try to create our new resource: - ``` + ```bash kubectl apply -f rng.yml ``` + + ] -- @@ -501,11 +503,11 @@ be any interruption.* ] @@ -538,19 +540,18 @@ be any interruption.* .exercise[ -- Update the service to add `enabled: "yes"` to its selector: - ```bash - kubectl edit service rng - ``` +- Update the YAML manifest of the service + +- Add `enabled: "yes"` to its selector ] @@ -589,16 +590,25 @@ If we did everything correctly, the web UI shouldn't show any change. ```bash POD=$(kubectl get pod -l app=rng,pod-template-hash -o name) kubectl logs --tail 1 --follow $POD - ``` (We should see a steady stream of HTTP logs) + + - In another window, remove the label from the pod: ```bash kubectl label pod -l app=rng,pod-template-hash enabled- ``` (The stream of HTTP logs should stop immediately) + + ] There might be a slight change in the web UI (since we removed a bit diff --git a/slides/k8s/dryrun.md b/slides/k8s/dryrun.md index f319c8b6..6078d9dd 100644 --- a/slides/k8s/dryrun.md +++ b/slides/k8s/dryrun.md @@ -162,6 +162,8 @@ Instead, it has the fields expected in a DaemonSet. kubectl diff -f web.yaml ``` + + ] Note: we don't need to specify `--validate=false` here. diff --git a/slides/k8s/horizontal-pod-autoscaler.md b/slides/k8s/horizontal-pod-autoscaler.md index 069c479d..04ead202 100644 --- a/slides/k8s/horizontal-pod-autoscaler.md +++ b/slides/k8s/horizontal-pod-autoscaler.md @@ -105,19 +105,36 @@ - Monitor pod CPU usage: ```bash - watch kubectl top pods + watch kubectl top pods -l app=busyhttp ``` + + - Monitor service latency: ```bash - httping http://`ClusterIP`/ + httping http://`$CLUSTERIP`/ ``` + + - Monitor cluster events: ```bash kubectl get events -w ``` + + ] --- @@ -130,9 +147,15 @@ - Send a lot of requests to the service, with a concurrency level of 3: ```bash - ab -c 3 -n 100000 http://`ClusterIP`/ + ab -c 3 -n 100000 http://`$CLUSTERIP`/ ``` + + ] The latency (reported by `httping`) should increase above 3s. @@ -193,6 +216,20 @@ This can also be set with `--cpu-percent=`. kubectl edit deployment busyhttp ``` + + - In the `containers` list, add the following block: ```yaml resources: @@ -243,3 +280,29 @@ This can also be set with `--cpu-percent=`. - The metrics provided by metrics server are standard; everything else is custom - For more details, see [this great blog post](https://medium.com/uptime-99/kubernetes-hpa-autoscaling-with-custom-and-external-metrics-da7f41ff7846) or [this talk](https://www.youtube.com/watch?v=gSiGFH4ZnS8) + +--- + +## Cleanup + +- Since `busyhttp` uses CPU cycles, let's stop it before moving on + +.exercise[ + +- Delete the `busyhttp` Deployment: + ```bash + kubectl delete deployment busyhttp + ``` + + + +] diff --git a/slides/k8s/kubectlexpose.md b/slides/k8s/kubectlexpose.md index 8c1ad167..5bd4b6fc 100644 --- a/slides/k8s/kubectlexpose.md +++ b/slides/k8s/kubectlexpose.md @@ -124,7 +124,10 @@ kubectl create service externalname k8s --external-name kubernetes.io kubectl get pods -w ``` - + - Create a deployment for this very lightweight HTTP server: ```bash @@ -191,6 +194,8 @@ kubectl create service externalname k8s --external-name kubernetes.io - Send a few requests: diff --git a/slides/k8s/kubectlproxy.md b/slides/k8s/kubectlproxy.md index fa7f7505..c50618a1 100644 --- a/slides/k8s/kubectlproxy.md +++ b/slides/k8s/kubectlproxy.md @@ -101,7 +101,7 @@ If we wanted to talk to the API, we would need to: - Terminate the proxy: diff --git a/slides/k8s/kubectlrun.md b/slides/k8s/kubectlrun.md index d16e9b5e..01fe08e6 100644 --- a/slides/k8s/kubectlrun.md +++ b/slides/k8s/kubectlrun.md @@ -154,6 +154,11 @@ pod/pingpong-7c8bbcd9bc-6c9qz 1/1 Running 0 10m - Leave that command running, so that we can keep an eye on these logs + + ] --- @@ -206,11 +211,21 @@ We could! But the *deployment* would notice it right away, and scale back to the - 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. @@ -235,10 +250,30 @@ Let's leave `kubectl logs` running while we keep exploring. watch kubectl get pods ``` + + - Destroy the pod currently shown by `kubectl logs`: ``` kubectl delete pod pingpong-xxxxxxxxxx-yyyyy ``` + + + ] --- @@ -307,7 +342,7 @@ Let's leave `kubectl logs` running while we keep exploring. - Create the Cron Job: ```bash - kubectl run --schedule="*/3 * * * *" --restart=OnFailure --image=alpine sleep 10 + kubectl run every3mins --schedule="*/3 * * * *" --restart=OnFailure --image=alpine sleep 10 ``` - Check the resource that was created: @@ -418,7 +453,7 @@ Let's leave `kubectl logs` running while we keep exploring. ] @@ -447,6 +482,8 @@ class: extra-details kubectl logs -l run=pingpong --tail 1 -f ``` + + ] We see a message like the following one: diff --git a/slides/k8s/kubectlscale.md b/slides/k8s/kubectlscale.md index 488a6448..e78136aa 100644 --- a/slides/k8s/kubectlscale.md +++ b/slides/k8s/kubectlscale.md @@ -12,9 +12,9 @@ - Now, create more `worker` replicas: diff --git a/slides/k8s/kustomize.md b/slides/k8s/kustomize.md index 664f82f3..0554fadf 100644 --- a/slides/k8s/kustomize.md +++ b/slides/k8s/kustomize.md @@ -97,6 +97,8 @@ ship init https://github.com/jpetazzo/kubercoins ``` + + ] --- @@ -189,6 +191,11 @@ kubectl logs deploy/worker --tail=10 --follow --namespace=kustomcoins ``` + + ] Note: it might take a minute or two for the worker to start. diff --git a/slides/k8s/logs-cli.md b/slides/k8s/logs-cli.md index 5dda900b..9c810692 100644 --- a/slides/k8s/logs-cli.md +++ b/slides/k8s/logs-cli.md @@ -84,14 +84,14 @@ Exactly what we need! .exercise[ -- View the logs for all the rng containers: +- View the logs for all the pingpong containers: ```bash - stern rng + stern pingpong ``` ] @@ -117,7 +117,7 @@ Exactly what we need! ] @@ -138,14 +138,14 @@ Exactly what we need! .exercise[ -- View the logs for all the things started with `kubectl create deployment`: +- View the logs for all the things started with `kubectl run`: ```bash - stern -l app + stern -l run ``` ] diff --git a/slides/k8s/netpol.md b/slides/k8s/netpol.md index 21950c1b..5ec070d9 100644 --- a/slides/k8s/netpol.md +++ b/slides/k8s/netpol.md @@ -120,6 +120,12 @@ This is our game plan: kubectl create deployment testweb --image=nginx ``` + + - Find out the IP address of the pod with one of these two commands: ```bash kubectl get pods -o wide -l app=testweb @@ -154,6 +160,11 @@ The `curl` command should show us the "Welcome to nginx!" page. curl $IP ``` + + ] The `curl` command should now time out. diff --git a/slides/k8s/ourapponkube.md b/slides/k8s/ourapponkube.md index abe48620..992a38b3 100644 --- a/slides/k8s/ourapponkube.md +++ b/slides/k8s/ourapponkube.md @@ -108,7 +108,7 @@ kubectl wait deploy/worker --for condition=available ] diff --git a/slides/k8s/podsecuritypolicy.md b/slides/k8s/podsecuritypolicy.md index 97c721d1..0deb8284 100644 --- a/slides/k8s/podsecuritypolicy.md +++ b/slides/k8s/podsecuritypolicy.md @@ -220,6 +220,8 @@ sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml ``` + + ] --- @@ -240,6 +242,16 @@ - Save, quit + + ] --- @@ -271,6 +283,8 @@ kubectl run testpsp1 --image=nginx --restart=Never ``` + + - Try to create a Deployment: ```bash kubectl run testpsp2 --image=nginx @@ -498,3 +512,22 @@ class: extra-details - bind `psp:restricted` to the group `system:authenticated` - bind `psp:privileged` to the ServiceAccount `kube-system:default` + +--- + +## Fixing the cluster + +- Let's disable the PSP admission plugin + +.exercise[ + +- Edit the Kubernetes API server static pod manifest + +- Remove the PSP admission plugin + +- This can be done with this one-liner: + ```bash + sudo sed -i s/,PodSecurityPolicy// /etc/kubernetes/manifests/kube-apiserver.yaml + ``` + +] diff --git a/slides/k8s/portworx.md b/slides/k8s/portworx.md index ac0b7abd..46887b73 100644 --- a/slides/k8s/portworx.md +++ b/slides/k8s/portworx.md @@ -197,7 +197,7 @@ If you want to use an external key/value store, add one of the following: ] @@ -374,7 +374,7 @@ spec: autopilot prompt detection expects $ or # at the beginning of the line. ```wait postgres@postgres``` ```keys PS1="\u@\h:\w\n\$ "``` -```keys ^J``` +```key ^J``` --> - Check that default databases have been created correctly: @@ -428,7 +428,7 @@ autopilot prompt detection expects $ or # at the beginning of the line. psql demo -c "select count(*) from pgbench_accounts" ``` - + ] @@ -491,7 +491,7 @@ By "disrupt" we mean: "disconnect it from the network". - Logout to go back on `node1` - + - Watch the events unfolding with `kubectl get events -w` and `kubectl get pods -w` @@ -519,7 +519,7 @@ By "disrupt" we mean: "disconnect it from the network". - Check the number of rows in the `pgbench_accounts` table: @@ -527,7 +527,7 @@ By "disrupt" we mean: "disconnect it from the network". psql demo -c "select count(*) from pgbench_accounts" ``` - + ] diff --git a/slides/k8s/rollout.md b/slides/k8s/rollout.md index eb777c83..5e8c1a9f 100644 --- a/slides/k8s/rollout.md +++ b/slides/k8s/rollout.md @@ -94,7 +94,7 @@ - Update `worker` either with `kubectl edit`, or by running: @@ -150,7 +150,7 @@ That rollout should be pretty quick. What shows in the web UI? ] @@ -229,11 +229,7 @@ If you didn't deploy the Kubernetes dashboard earlier, just skip this slide. .exercise[ - + - Cancel the deployment and wait for the dust to settle: ```bash @@ -336,7 +332,7 @@ We might see something like 1, 4, 5. - Check the annotations for our replica sets: ```bash - kubectl describe replicasets -l app=worker | grep -A3 + kubectl describe replicasets -l app=worker | grep -A3 ^Annotations ``` ] diff --git a/slides/k8s/scalingdockercoins.md b/slides/k8s/scalingdockercoins.md index 75e9a7de..36ce2674 100644 --- a/slides/k8s/scalingdockercoins.md +++ b/slides/k8s/scalingdockercoins.md @@ -19,17 +19,14 @@ .exercise[ -- Open two new terminals to check what's going on with pods and deployments: +- Open a new terminal to keep an eye on our pods: ```bash kubectl get pods -w - kubectl get deployments -w ``` - Now, create more `worker` replicas: @@ -73,6 +70,11 @@ The graph in the web UI should go up again. kubectl scale deployment worker --replicas=10 ``` + + ] -- diff --git a/slides/k8s/shippingimages.md b/slides/k8s/shippingimages.md index 2529a303..6618501f 100644 --- a/slides/k8s/shippingimages.md +++ b/slides/k8s/shippingimages.md @@ -105,6 +105,11 @@ docker run ctr.run/github.com/jpetazzo/container.training/dockercoins/hasher ``` + + ] There might be a long pause before the first layer is pulled, diff --git a/slides/k8s/statefulsets.md b/slides/k8s/statefulsets.md index 6c7c15a9..102ef1c3 100644 --- a/slides/k8s/statefulsets.md +++ b/slides/k8s/statefulsets.md @@ -427,7 +427,7 @@ nodes and encryption of gossip traffic) were removed for simplicity. - Check the health of the cluster: diff --git a/slides/k8s/volumes.md b/slides/k8s/volumes.md index ef41b4cb..3952bcb9 100644 --- a/slides/k8s/volumes.md +++ b/slides/k8s/volumes.md @@ -110,6 +110,8 @@ It runs a single NGINX container. kubectl create -f ~/container.training/k8s/nginx-1-without-volume.yaml ``` + + - Get its IP address: ```bash IPADDR=$(kubectl get pod nginx-without-volume -o jsonpath={.status.podIP}) @@ -175,6 +177,8 @@ spec: kubectl create -f ~/container.training/k8s/nginx-2-with-volume.yaml ``` + + - Get its IP address: ```bash IPADDR=$(kubectl get pod nginx-with-volume -o jsonpath={.status.podIP}) @@ -269,6 +273,11 @@ spec: kubectl get pods -o wide --watch ``` + + ] --- @@ -282,11 +291,18 @@ spec: kubectl create -f ~/container.training/k8s/nginx-3-with-git.yaml ``` + + - As soon as we see its IP address, access it: ```bash curl $IP ``` + + - A few seconds later, the state of the pod will change; access it again: ```bash curl $IP @@ -399,10 +415,19 @@ spec: ## Trying the init container +.exercise[ + - Repeat the same operation as earlier (try to send HTTP requests as soon as the pod comes up) + + +] + - This time, instead of "403 Forbidden" we get a "connection refused" - NGINX doesn't start until the git container has done its job diff --git a/slides/shared/composescale.md b/slides/shared/composescale.md index ff8578f1..eba94dd5 100644 --- a/slides/shared/composescale.md +++ b/slides/shared/composescale.md @@ -40,7 +40,7 @@ class: extra-details ] @@ -75,7 +75,7 @@ Tip: use `^S` and `^Q` to pause/resume log output. ```bash top``` ```wait Tasks``` -```keys ^C``` +```key ^C``` --> - run `vmstat 1` to see I/O usage (si/so/bi/bo) @@ -85,7 +85,7 @@ Tip: use `^S` and `^Q` to pause/resume log output. ```bash vmstat 1``` ```wait memory``` -```keys ^C``` +```key ^C``` --> ] diff --git a/slides/shared/sampleapp.md b/slides/shared/sampleapp.md index 0636d2de..52a947f8 100644 --- a/slides/shared/sampleapp.md +++ b/slides/shared/sampleapp.md @@ -343,7 +343,7 @@ class: extra-details - Stop the application by hitting `^C` ] diff --git a/slides/swarm/creatingswarm.md b/slides/swarm/creatingswarm.md index 2f0d2f2f..7a053fb3 100644 --- a/slides/swarm/creatingswarm.md +++ b/slides/swarm/creatingswarm.md @@ -267,7 +267,7 @@ class: extra-details - Switch back to `node1` (with `exit`, `Ctrl-D` ...) - + - View the cluster from `node1`, which is a manager: ```bash diff --git a/slides/swarm/ipsec.md b/slides/swarm/ipsec.md index 5f8d48b5..b6803c24 100644 --- a/slides/swarm/ipsec.md +++ b/slides/swarm/ipsec.md @@ -72,7 +72,7 @@ ``` - + ] diff --git a/slides/swarm/logging.md b/slides/swarm/logging.md index 975949ed..6ebc7058 100644 --- a/slides/swarm/logging.md +++ b/slides/swarm/logging.md @@ -158,7 +158,7 @@ class: elk-manual ``` - + ] @@ -266,7 +266,7 @@ The test message should show up in the logstash container logs. ``` - + ]