From 0e4ed4fa5a531da0a24a9459a8903fc4811f296b Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 29 Oct 2019 19:37:28 -0500 Subject: [PATCH] Tutorial --- slides/k8s/cni.md | 130 +++++++++++++++------------------------- slides/k8s/dmuc.md | 21 +------ slides/k8s/multinode.md | 124 +++++++++++++++++++++++++------------- slides/lisa.html | 7 +-- slides/lisa/begin.md | 24 ++++++++ slides/lisa/end.md | 2 +- slides/lisa/env.md | 77 ++++++++++++++++++++++++ slides/talk.yml | 2 +- slides/tutorial.yml | 22 +++++++ 9 files changed, 257 insertions(+), 152 deletions(-) create mode 100644 slides/lisa/env.md create mode 100644 slides/tutorial.yml 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 + +![Oprah's "you get a car" picture](images/you-get-a-cluster.jpg) + +--- + +## 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