diff --git a/slides/k8s/cni.md b/slides/k8s/cni.md
index 26a736b9..b468f1ee 100644
--- a/slides/k8s/cni.md
+++ b/slides/k8s/cni.md
@@ -110,9 +110,9 @@ class: extra-details
## In practice: kube-router
-- We are going to set up a new cluster
+- We are going to reconfigure our cluster
-- For this new cluster, we will use kube-router
+ (control plane and kubelets
- kube-router will provide the "pod network"
@@ -184,73 +184,79 @@ class: extra-details
## The plan
-- We'll work in a new cluster (named `kuberouter`)
+- We'll update the control plane's configuration
-- We will run a simple control plane (like before)
+ - the controller manager will allocate `podCIDR` subnets
-- ... But this time, the controller manager will allocate `podCIDR` subnets
-
- (so that we don't have to manually assign subnets to individual nodes)
+ - we will allow privileged containers
- We will create a DaemonSet for kube-router
-- We will join nodes to the cluster
+- We will restart kubelets in CNI mode
- The DaemonSet will automatically start a kube-router pod on each node
---
-## Logging into the new cluster
+## Getting the files
.exercise[
-- Log into node `kuberouter1`
-
-- Clone the workshop repository:
+- If you haven't cloned the training repo yet, do it:
```bash
- git clone https://@@GITREPO@@
+ cd ~
+ git clone https://container.training
```
-- Move to this directory:
+- Then move to this directory:
```bash
- cd container.training/compose/kube-router-k8s-control-plane
+ cd ~/container.training/compose/kube-router-k8s-control-plane
```
]
---
-## Our control plane
+## Changes to the control plane
-- We will use a Compose file to start the control plane
-
-- It is similar to the one we used with the `kubenet` cluster
-
-- The API server is started with `--allow-privileged`
+- The API server must be started with `--allow-privileged`
(because we will start kube-router in privileged pods)
-- The controller manager is started with extra flags too:
+- The controller manager must be started with extra flags too:
`--allocate-node-cidrs` and `--cluster-cidr`
-- We need to edit the Compose file to set the Cluster CIDR
+.exercise[
+
+- Make these changes!
+
+ (You might have to restart scheduler and controller manager, too.)
+
+]
+
+.footnote[If your control plane is broken, don't worry!
+
We provide a Compose file to catch up.]
---
-## Starting the control plane
+## Catching up
-- Our cluster CIDR will be `10.C.0.0/16`
-
- (where `C` is our cluster number)
+- If your control plane is broken, here is how to start a new one
.exercise[
-- Edit the Compose file to set the Cluster CIDR:
+- Make sure the Docker Engine is running, or start it with:
```bash
- vim docker-compose.yaml
+ dockerd
```
+- Edit the Compose file to change the `--cluster-cidr`
+
+- Our cluster CIDR will be `10.C.0.0/16`
+
+ (where `C` is our cluster number)
+
- Start the control plane:
```bash
docker-compose up
@@ -278,7 +284,7 @@ class: extra-details
- The address of the API server will be `http://A.B.C.D:8080`
- (where `A.B.C.D` is the public address of `kuberouter1`, running the control plane)
+ (where `A.B.C.D` is the public address of `node1`, running the control plane)
.exercise[
@@ -298,42 +304,7 @@ Note: the DaemonSet won't create any pods (yet) since there are no nodes (yet).
---
-## Generating the kubeconfig for kubelet
-
-- This is similar to what we did for the `kubenet` cluster
-
-.exercise[
-
-- Generate the kubeconfig file (replacing `X.X.X.X` with the address of `kuberouter1`):
- ```bash
- kubectl config set-cluster cni --server http://`X.X.X.X`:8080
- kubectl config set-context cni --cluster cni
- kubectl config use-context cni
- cp ~/.kube/config ~/kubeconfig
- ```
-
-]
-
----
-
-## Distributing kubeconfig
-
-- We need to copy that kubeconfig file to the other nodes
-
-.exercise[
-
-- Copy `kubeconfig` to the other nodes:
- ```bash
- for N in 2 3; do
- scp ~/kubeconfig kuberouter$N:
- done
- ```
-
-]
-
----
-
-## Starting kubelet
+## Restarting kubelets
- We don't need the `--pod-cidr` option anymore
@@ -350,33 +321,30 @@ Note: the DaemonSet won't create any pods (yet) since there are no nodes (yet).
- Open more terminals and join the other nodes:
```bash
- ssh kuberouter2 sudo kubelet --kubeconfig ~/kubeconfig --network-plugin=cni
- ssh kuberouter3 sudo kubelet --kubeconfig ~/kubeconfig --network-plugin=cni
+ ssh node2 sudo kubelet --kubeconfig ~/kubeconfig --network-plugin=cni
+ ssh node3 sudo kubelet --kubeconfig ~/kubeconfig --network-plugin=cni
```
]
---
-## Setting up a test
+## Testing
-- Let's create a Deployment and expose it with a Service
+- Let's delete all pods
+
+- They should be re-created with new, correct addresses
.exercise[
-- Create a Deployment running a web server:
+- Delete all pods:
```bash
- kubectl create deployment web --image=jpetazzo/httpenv
+ kubectl delete pods --all
```
-- Scale it so that it spans multiple nodes:
+- Check the new pods:
```bash
- kubectl scale deployment web --replicas=5
- ```
-
-- Expose it with a Service:
- ```bash
- kubectl expose deployment web --port=8888
+ kuectl get pods -o wide
```
]
@@ -462,7 +430,7 @@ We should see the local pod CIDR connected to `kube-bridge`, and the other nodes
These commands will give an error message that includes:
```
-dial tcp: lookup kuberouterX on 127.0.0.11:53: no such host
+dial tcp: lookup nodeX on 127.0.0.11:53: no such host
```
What does that mean?
@@ -475,7 +443,7 @@ What does that mean?
- By default, it creates a connection using the kubelet's name
- (e.g. `http://kuberouter1:...`)
+ (e.g. `http://node1:...`)
- This requires our nodes names to be in DNS
diff --git a/slides/k8s/dmuc.md b/slides/k8s/dmuc.md
index 17f60543..43e7c705 100644
--- a/slides/k8s/dmuc.md
+++ b/slides/k8s/dmuc.md
@@ -31,31 +31,12 @@
---
-## Our environment
-
-- We will use the machine indicated as `dmuc1`
-
- (this stands for "Dessine Moi Un Cluster" or "Draw Me A Sheep",
-
in homage to Saint-Exupery's "The Little Prince")
-
-- This machine:
-
- - runs Ubuntu LTS
-
- - has Kubernetes, Docker, and etcd binaries installed
-
- - but nothing is running
-
----
-
## Checking our environment
- Let's make sure we have everything we need first
.exercise[
-- Log into the `dmuc1` machine
-
- Get root:
```bash
sudo -i
@@ -559,7 +540,7 @@ Success!
Our node should show up.
-Its name will be its hostname (it should be `dmuc1`).
+Its name will be its hostname (it should be `node1`).
---
diff --git a/slides/k8s/multinode.md b/slides/k8s/multinode.md
index af6b6194..0ae2719b 100644
--- a/slides/k8s/multinode.md
+++ b/slides/k8s/multinode.md
@@ -4,41 +4,11 @@
- Let's see what it takes to add more nodes
-- We are going to use another set of machines: `kubenet`
-
---
-## The environment
+## Next steps
-- We have 3 identical machines: `kubenet1`, `kubenet2`, `kubenet3`
-
-- The Docker Engine is installed (and running) on these machines
-
-- The Kubernetes packages are installed, but nothing is running
-
-- We will use `kubenet1` to run the control plane
-
----
-
-## The plan
-
-- Start the control plane on `kubenet1`
-
-- Join the 3 nodes to the cluster
-
-- Deploy and scale a simple web server
-
-.exercise[
-
-- Log into `kubenet1`
-
-]
-
----
-
-## Running the control plane
-
-- We will use a Compose file to start the control plane components
+- We will need some files that are on the tutorial GitHub repo
.exercise[
@@ -47,6 +17,56 @@
git clone https://@@GITREPO@@
```
+]
+
+---
+
+## Control plane
+
+- We can use the control plane that we deployed on node1
+
+- If that didn't quite work, don't panic!
+
+- We provide a way to catch up and get a control plane in a pinch
+
+---
+
+## Cleaning up
+
+- Only do this if your control plane doesn't work and want to start over
+
+.exercise[
+
+- Reboot the node to make sure nothing else is running:
+ ```bash
+ sudo reboot
+ ```
+
+- Log in again:
+ ```bash
+ ssh docker@`A.B.C.D`
+ ```
+
+- Get root:
+ ```
+ sudo -i
+ ```
+
+]
+
+---
+
+## Catching up
+
+- We will use a Compose file to start the control plane components
+
+.exercise[
+
+- Start the Docker Engine:
+ ```bash
+ dockerd
+ ```
+
- Go to the `compose/simple-k8s-control-plane` directory:
```bash
cd container.training/compose/simple-k8s-control-plane
@@ -84,7 +104,7 @@
class: extra-details
-## Differences from `dmuc`
+## Differences with the other control plane
- Our new control plane listens on `0.0.0.0` instead of the default `127.0.0.1`
@@ -123,7 +143,7 @@ class: extra-details
- Copy `kubeconfig` to the other nodes:
```bash
for N in 2 3; do
- scp ~/kubeconfig kubenet$N:
+ scp ~/kubeconfig node$N:
done
```
@@ -144,17 +164,35 @@ class: extra-details
- Open more terminals and join the other nodes to the cluster:
```bash
- ssh kubenet2 sudo kubelet --kubeconfig ~/kubeconfig
- ssh kubenet3 sudo kubelet --kubeconfig ~/kubeconfig
+ ssh node2 sudo kubelet --kubeconfig ~/kubeconfig
+ ssh node3 sudo kubelet --kubeconfig ~/kubeconfig
```
]
---
+## If we're running the "old" control plane
+
+- By default, the API server only listens on localhost
+
+- The other nodes will not be able to connect
+
+ (symptom: a flood of `node "nodeX" not found` messages)
+
+- We need to add `--address 0.0.0.0` to the API server
+
+ (yes, [this will expose our API server to all kinds of shenanigans](https://twitter.com/TabbySable/status/1188901099446554624))
+
+- Restarting API server might cause scheduler and controller manager to quit
+
+ (you might have to restart them)
+
+---
+
## Checking cluster status
-- We should now see all 3 nodes
+- We should now see all the nodes
- At first, their `STATUS` will be `NotReady`
@@ -179,14 +217,14 @@ class: extra-details
.exercise[
-- Create a Deployment running NGINX:
+- Create a Deployment running httpenv:
```bash
- kubectl create deployment web --image=nginx
+ kubectl create deployment httpenv --image=jpetazzo/httpenv
```
- Scale it:
```bash
- kubectl scale deployment web --replicas=5
+ kubectl scale deployment httpenv --replicas=5
```
]
@@ -197,7 +235,7 @@ class: extra-details
- The pods will be scheduled on the nodes
-- The nodes will pull the `nginx` image, and start the pods
+- The nodes will pull the `jpetazzo/httpenv` image, and start the pods
- What are the IP addresses of our pods?
@@ -399,7 +437,7 @@ class: extra-details
- Expose our Deployment:
```bash
- kubectl expose deployment web --port=80
+ kubectl expose deployment httpenv --port=8888
```
]
@@ -412,7 +450,7 @@ class: extra-details
- Retrieve the ClusterIP address:
```bash
- kubectl get svc web
+ kubectl get svc httpenv
```
- Send a few requests to the ClusterIP address (with `curl`)
diff --git a/slides/lisa.html b/slides/lisa.html
index a8d2d23e..97ae4475 100644
--- a/slides/lisa.html
+++ b/slides/lisa.html
@@ -1,8 +1,3 @@
Slides for the talk (Monday)
|
-Slides for the tutorial (Wednesday)
-
-
-
-Tutorial slides will be available in a few days.
-Thanks for understanding!
+Slides for the tutorial (Wednesday)
diff --git a/slides/lisa/begin.md b/slides/lisa/begin.md
index d2d84ce9..202f09de 100644
--- a/slides/lisa/begin.md
+++ b/slides/lisa/begin.md
@@ -28,6 +28,24 @@ Introductions
---
+class: tutorial-only
+
+## Viewer advisory
+
+- Have you attended my talk on Monday?
+
+--
+
+- Then you may experience *déjà-vu* during the next few minutes
+
+ (Sorry!)
+
+--
+
+- But I promise we'll soon build (and break) some clusters!
+
+---
+
## Hi!
- Jérôme Petazzoni ([@jpetazzo](https://twitter.com/jpetazzo))
@@ -128,6 +146,12 @@ As you can see, I love emojis, but if you don't, it's OK.
- (Other, please specify)
+--
+
+class: tutorial-only
+
+.footnote[*Damn. Jérôme is even using the same jokes for his talk and his tutorial!
This guy really has no shame. Tsk.*]
+
---
class: title
diff --git a/slides/lisa/end.md b/slides/lisa/end.md
index 3ac44f8d..0d0aa6f9 100644
--- a/slides/lisa/end.md
+++ b/slides/lisa/end.md
@@ -1,4 +1,4 @@
-class: title
+class: title, talk-only
What's missing?
diff --git a/slides/lisa/env.md b/slides/lisa/env.md
new file mode 100644
index 00000000..c00bfaee
--- /dev/null
+++ b/slides/lisa/env.md
@@ -0,0 +1,77 @@
+class: title
+
+Let's get this party started!
+
+---
+
+class: pic
+
+
+
+---
+
+## Everyone gets their own cluster
+
+- Everyone should have a little printed card
+
+- That card has IP address / login / password for a personal cluster
+
+- That cluster will be up for the duration of the tutorial
+
+ (but not much longer, alas, because these cost $$$)
+
+---
+
+## How these clusters are deployed
+
+- Create a bunch of cloud VMs
+
+ (today: Ubuntu 18.04 on AWS EC2)
+
+- Install binaries, create user account
+
+ (with parallel-ssh because it's *fast*)
+
+- Generate the little cards with a Jinja2 template
+
+- If you want to do it for your own tutorial:
+
+ check the [prepare-vms](https://github.com/jpetazzo/container.training/tree/master/prepare-vms) directory in the training repo!
+
+---
+
+## Exercises
+
+- Labs and exercises are clearly identified
+
+.exercise[
+
+- This indicate something that you are invited to do
+
+- First, let's log into the first node of the cluster:
+ ```bash
+ ssh docker@`A.B.C.D`
+ ```
+
+ (Replace A.B.C.D with the IP address of the first node)
+
+]
+
+---
+
+## Slides
+
+- These slides are available online
+
+.exercise[
+
+- Open this slides deck in a local browser:
+ ```open
+ @@SLIDES@@
+ ```
+
+- Select the tutorial link
+
+- Type the number of that slide + ENTER
+
+]
diff --git a/slides/talk.yml b/slides/talk.yml
index 71f8e5f9..2c0f8891 100644
--- a/slides/talk.yml
+++ b/slides/talk.yml
@@ -3,7 +3,7 @@ title: |
Kubernetes Internals
for Builders and Operators
- (LISA2019)
+ (LISA2019 talk)
chat: ""
gitrepo: ""
diff --git a/slides/tutorial.yml b/slides/tutorial.yml
new file mode 100644
index 00000000..f5754ee9
--- /dev/null
+++ b/slides/tutorial.yml
@@ -0,0 +1,22 @@
+title: |
+ Deep Dive into
+ Kubernetes Internals
+ for Builders and Operators
+
+ (LISA2019 tutorial)
+
+chat: ""
+gitrepo: container.training
+slides: https://lisa-2019-10.container.training
+
+exclude:
+- talk-only
+
+chapters:
+- lisa/begin.md
+- k8s/deploymentslideshow.md
+- lisa/env.md
+- k8s/dmuc.md
+- k8s/multinode.md
+- k8s/cni.md
+- lisa/end.md