diff --git a/slides/b b/slides/b new file mode 100755 index 00000000..140087d8 --- /dev/null +++ b/slides/b @@ -0,0 +1 @@ +./markmaker.py kube.yml >out.html diff --git a/slides/containers/Getting_Inside.md b/slides/containers/Getting_Inside.md index 15a887a9..af71c0b8 100644 --- a/slides/containers/Getting_Inside.md +++ b/slides/containers/Getting_Inside.md @@ -100,7 +100,11 @@ _We will give more details about namespaces and cgroups later._ * But it is easier to use `docker exec`. ```bash -$ docker exec -ti ticktock sh +$ docker ps -lq # Get Last Container ID +17e4e95e2702 +$ docker exec 17 + +$ docker exec -ti $(docker ps -lq) sh # bash-fu version ``` * This creates a new process (running `sh`) _inside_ the container. diff --git a/slides/containers/High_Level_View.md b/slides/containers/High_Level_View.md new file mode 100644 index 00000000..59d97582 --- /dev/null +++ b/slides/containers/High_Level_View.md @@ -0,0 +1,20 @@ + +class: title + +# High Level Discussion + +![image](images/title-understanding-docker-images.png) + +--- + +## White Board Topics + +* What is the real problem that containers solve? +* What are the inputs to a Unix Process? +* What is the init Process? +* Userland vs Kernel +* The Root File System +* What is an Overlay File System? +* Wrapping it all up to represent a container image +* Deploying Container images + diff --git a/slides/containers/Macro_View.md b/slides/containers/Macro_View.md new file mode 100644 index 00000000..d7d77128 --- /dev/null +++ b/slides/containers/Macro_View.md @@ -0,0 +1,318 @@ + + +class: title + +# A Macroscopic View + +--- + +## Macroscopic Items + +* The business case for containers + +* The problem containers are solving + +* What applications need + +* What is the OS doing provides? + +--- + +## What do CIOs worry about? + +Who are the CIO's customers? + +* Business Units: Need Computers to Run Applications + * Peak Capacity + +* CFO: Demanding Budget Justifications + * Spend Less + +--- + +## History of Solutions + +For Each Business Application Buy a Machine + +* Buy a machine for each application + + * Big enough for Peak Load (CPU, Memory, Disk) + +The Age of VMs + +* Buy bigger machines and chop them up into logical machines + + * Distribute your applications as VMs theses machines + +* Observe what and when the application load actually is + + * Possibly rebalance be to inform possibly moving + +But Maintaining Machines (Bare Metal or VM) is hard (Patches, Packages, Drivers, etc) + +--- + +## What Developers and Ops worry about + +* Getting Software deployed + +* Mysterious reasons why deployed application doesn't work + + * Developer to Ops: + + * "Hey it works on my development machine..." + + * "I don't know why it isn't working for ***you***" + + * "Everything ***looks*** the same" + + * "I have no idea what could be different" + +--- + +## The History of Software Deployment + +Software Deployment is just a reproducible way to install files: + +* Cards + +* Tapes + +* Floppy Disks + +* Zip/Tar Files + +* Installation "Files" (rpm/deb/msi) + +* VM Images + +--- + +## What is the Problem Containers are Solving? + +It depends on who you are: + + * For the CIO: Better resource utilization + + * For Ops: Software Distribution + + * For the Developer & Ops: Reproducible Environment + +

+ +Ummm, but what exactly are containers.... + + * Wait a few more slides... + +--- + +## Macroscopic view: Applications and the OS + +Applications: + +* What are the inputs/outputs to a program? + +The OS: + +* What does the OS provide? + +--- + +## What are the inputs/outputs to a program? + +Explicitly: +* Command Line Arguments +* Environment Variables +* Standard In +* Standard Out/Err + +Implicitly (via the File System): + +* Configuration Files +* Other Installed Applications +* Any other files + +Also Implicitly + +* Memory +* Network + + +--- + + +## What does the OS provide? + +* OS Kernel + * Kernel loded at boot time + * Sets up disk drives, network cards, other hardware, etc + * Manages all hardware, processes, memory, etc + * Kernel Space + * Low level innards of Kernel (fluid internal API) + * No direct access by applications of most Kernel functionality + + +* User Space (userland) Processes + * Code running outside the Kernel + * Very stable shim library access from User Space to Kernel Space (Think "fopen") + +* The "init" Process + * User Space Process run after Kernel has booted + * Always PID 1 + +--- + +## OS Processes + +* Created when an application is launched + * Each has a unique Process ID (PID) + +* Provides it its own logical 'view' of all implicit inputs/output when launching app + * File System ( root directory, / ) + * Memory + * Network Adaptors + * Other running processes + +--- + +## What do we mean by "The OS" + +Different Linux's + +* Ubuntu / Debian; Centos / RHEL; Raspberry Pi; etc + +What do they have in common? + +* They all have a kernel that provides access to Userland (ie fopen) + +* They typically have all the commands (bash, sh, ls, grep, ...) + +What may be different? + +* May use different versions of the Kernel (4.18, 5.4, ...) + * Internally different, but providing same Userland API + +* Many other bundled commands, packages and package management tools + * Namely what makes it 'Debian' vs 'Centos' + +--- + +## What might a 'Minimal' Linux be? + +You could actually just have: + +* A Linux Kernel + +* An application (for simplicity a statically linked C program) + +* The kernel configured to run that application as its 'init' process + +Would you ever do this? + +* Why not? + + * It certainly would be very secure + +--- + +## So Finally... What are Containers? + +Containers just a Linux process that 'thinks' it is it's own machine + +* With its own 'view' of things like: + * File System ( root directory, / ), Memory, Network Adaptors, Other running processes + +* Leverages our understanding that a (logical) Linux Machine is + * A kernel + * A bunch of files ( Maybe a few Environment Variables ) + +Since it is a process running on a host machine + +* It uses the kernel of the host machine +* And of course you need some tools to create the running container process + +--- + +## Container Runtimes and Container Images + +The Linux kernel actually has no concept of a container. + +* There have been many 'container' technologies + +* See [A Brief History of containers: From the 1970's till now](https://blog.aquasec.com/a-brief-history-of-containers-from-1970s-chroot-to-docker-2016) + +* Over the years more capabilities have been added to the kernel to make it easier + +
+A 'Container technology' is: + +* A Container Image Format of the unit of software deployment + * A bundle of all the files and miscellaneous configuration + +* A Container Runtime Engine + * Software that takes a Container Image and creates a running container + +--- + +## The Container Runtime War is now Over + +The Cloud Native Computing Foundation (CNCF) has standardized containers + +* A standard container image format + +* A standard for building and configuring container runtimes + +* A standard REST API for loading/downloading container image to a registries + +There primary Container Runtimes are: + +* containerd: using the 'docker' Command Line Interface (or Kubernetes) + +* CRI-O: using the 'podman' Command Line Interface (or Kubernetes/OpenShift) + +* Others exists, for example Singularity which has a history in HPC + +--- + +## Linux Namespaces Makes Containers Possible + +- Provide processes with their own isolated view of the system. + + - Namespaces limit what you can see (and therefore, what you can use). + +- These namespaces are available in modern kernels: + + - pid: processes + - net: network + - mnt: root file system (ie chroot) + - uts: hostname + - ipc + - user: UID/GID mapping + - time: time + - cgroup: Resource Monitoring and Limiting + +- Each process belongs to one namespace of each type. + +--- + +## Namespaces are always active + +- Namespaces exist even when you don't use containers. + +- This is a bit similar to the UID field in UNIX processes: + + - all processes have the UID field, even if no user exists on the system + + - the field always has a value / the value is always defined +
+ (i.e. any process running on the system has some UID) + + - the value of the UID field is used when checking permissions +
+ (the UID field determines which resources the process can access) + +- You can replace "UID field" with "namespace" above and it still works! + +- In other words: even when you don't use containers, +
there is one namespace of each type, containing all the processes on the system. + diff --git a/slides/containers/Training_Environment_And_Tmux.md b/slides/containers/Training_Environment_And_Tmux.md new file mode 100644 index 00000000..ab5f190a --- /dev/null +++ b/slides/containers/Training_Environment_And_Tmux.md @@ -0,0 +1,224 @@ + +class: title + +# Our training environment + +![SSH terminal](images/title-our-training-environment.jpg) + + +--- + +class: in-person + +## Connecting to your Virtual Machine + +You need an SSH client. + +* On OS X, Linux, and other UNIX systems, just use `ssh`: + +```bash +$ ssh @ +``` + +* On Windows, if you don't have an SSH client, you can download: + + * Putty (www.putty.org) + + * Git BASH (https://git-for-windows.github.io/) + + * MobaXterm (https://mobaxterm.mobatek.net/) + +--- + +class: in-person + +## Connecting to our lab environment + +.lab[ + +- Log into your VM 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) + + +] + +You should see a prompt looking like this: +``` +[A.B.C.D] (...) user@node1 ~ +$ +``` +If anything goes wrong — ask for help! + +--- +## Our Docker VM + +About the Lab VM + +- The VM is created just before the training. + +- It will stay up during the whole training. + +- It will be destroyed shortly after the training. + +- It comes pre-loaded with Docker and some other useful tools. + +--- + +## Why don't we run Docker locally? + +- I can log into your VMs to help you with labs + +- Installing docker is out of the scope of this class (lots of online docs) + + - It's better to spend time learning containers than fiddling with the installer! + +--- +class: in-person + +## `tailhist` + +- The shell history of the instructor is available online in real time + +- Note the IP address of the instructor's virtual machine (A.B.C.D) + +- Open http://A.B.C.D:1088 in your browser and you should see the history + +- The history is updated in real time (using a WebSocket connection) + +- It should be green when the WebSocket is connected + + (if it turns red, reloading the page should fix it) + +- If you want to play with it on your lab machine, tailhist is installed + + - sudo apt install firewalld + - sudo firewall-cmd --add-port=1088/tcp +--- + +## Checking your Virtual Machine + +Once logged in, make sure that you can run a basic Docker command: + +.small[ +```bash +$ docker version +Client: + Version: 18.03.0-ce + API version: 1.37 + Go version: go1.9.4 + Git commit: 0520e24 + Built: Wed Mar 21 23:10:06 2018 + OS/Arch: linux/amd64 + Experimental: false + Orchestrator: swarm + +Server: + Engine: + Version: 18.03.0-ce + API version: 1.37 (minimum version 1.12) + Go version: go1.9.4 + Git commit: 0520e24 + Built: Wed Mar 21 23:08:35 2018 + OS/Arch: linux/amd64 + Experimental: false +``` +] + +If this doesn't work, raise your hand so that an instructor can assist you! + +??? + +:EN:Container concepts +:FR:Premier contact avec les conteneurs + +:EN:- What's a container engine? +:FR:- Qu'est-ce qu'un *container engine* ? + + +--- + +## Doing or re-doing the workshop on your own? + +- Use something like + [Play-With-Docker](http://play-with-docker.com/) or + [Play-With-Kubernetes](https://training.play-with-kubernetes.com/) + + Zero setup effort; but environment are short-lived and + might have limited resources + +- Create your own cluster (local or cloud VMs) + + Small setup effort; small cost; flexible environments + +- Create a bunch of clusters for you and your friends + ([instructions](https://@@GITREPO@@/tree/master/prepare-vms)) + + Bigger setup effort; ideal for group training + +--- + +class: self-paced + +## Get your own Docker nodes + +- If you already have some Docker nodes: great! + +- If not: let's get some thanks to Play-With-Docker + +.lab[ + +- Go to http://www.play-with-docker.com/ + +- Log in + +- Create your first node + + + +] + +You will need a Docker ID to use Play-With-Docker. + +(Creating a Docker ID is free.) + +--- + +## Terminals + +Once in a while, the instructions will say: +
"Open a new terminal." + +There are multiple ways to do this: + +- create a new window or tab on your machine, and SSH into the VM; + +- use screen or tmux on the VM and open a new window from there. + +You are welcome to use the method that you feel the most comfortable with. + +--- + +## Tmux cheat sheet + +[Tmux](https://en.wikipedia.org/wiki/Tmux) is a terminal multiplexer like `screen`. + +*You don't have to use it or even know about it to follow along. +
+But some of us like to use it to switch between terminals. +
+It has been preinstalled on your workshop nodes.* + +- Ctrl-b c → creates a new window +- Ctrl-b n → go to next window +- Ctrl-b p → go to previous window +- Ctrl-b " → split window top/bottom +- Ctrl-b % → split window left/right +- Ctrl-b Alt-1 → rearrange windows in columns +- Ctrl-b Alt-2 → rearrange windows in rows +- Ctrl-b arrows → navigate to other windows +- Ctrl-b d → detach session +- tmux attach → re-attach to session diff --git a/slides/containers/Understanding_Images.md b/slides/containers/Understanding_Images.md new file mode 100644 index 00000000..254a20c1 --- /dev/null +++ b/slides/containers/Understanding_Images.md @@ -0,0 +1,27 @@ + + +```bash +$ docker run -it debian +root@ef22f9437171:/# apt-get update + +root@ef22f9437171:/# apt-get install skopeo + +root@ef22f9437171:/# apt-get wget curl jq + +root@ef22f9437171:/# skopeo login docker.io -u containertraining -p testaccount + +$ docker commit $(docker ps -lq) skop +``` + +```bash +root@0ab665194c4f:~# skopeo copy docker://docker.io/containertraining/test-image-0 dir:/root/test-image-0 +root@0ab665194c4f:~# cd /root/test-image-0 +root@0ab665194c4f:~# jq A && \ + echo "B is for Beetle" >B && \ + mkdir C/ && \ + echo "A is for Cowboy Allan" >C/CA && \ + mkdir -p C/CB && \ + echo "A is for Cowboy Buffalo Alex" >C/CB/CBA && \ + echo "B is for Cowboy Buffalo Bill" >C/CB/CBB && \ + echo "Z is for Cowboy Zeke" >> C/CZ && \ + mkdir D/ && \ + echo "A is for Detective Alisha" >D/DA && \ + echo "B is for Detective Betty" >D/DB && \ + echo "E is for Elephant" >E && \ + find . >../state.layer-0 diff --git a/slides/containers/exploring-images/Dockerfile.test-image-1 b/slides/containers/exploring-images/Dockerfile.test-image-1 new file mode 100644 index 00000000..0debe3cc --- /dev/null +++ b/slides/containers/exploring-images/Dockerfile.test-image-1 @@ -0,0 +1,17 @@ +FROM test-image-0 + +WORKDIR /play + +RUN echo "== LAYER 1 == Change File B, Create File C/CC, Add Dir C/CD, Remove File E, Create Dir F, Add File G, Create Empty Dir H" && \ + echo "B is for Butterfly" >B && \ + echo "C is for Cowboy Chuck">C/CC && \ + mkdir -p C/CD && \ + echo "A is for Cowboy Dandy Austin" >C/CD/CDA && \ + rm E && \ + mkdir F && \ + echo "A is for Ferret Albert" >F/FA && \ + echo "G is for Gorilla" >G && \ + mkdir H && \ + find . >../state.layer-1 + + diff --git a/slides/containers/exploring-images/Dockerfile.test-image-2 b/slides/containers/exploring-images/Dockerfile.test-image-2 new file mode 100644 index 00000000..e4cbf270 --- /dev/null +++ b/slides/containers/exploring-images/Dockerfile.test-image-2 @@ -0,0 +1,18 @@ +FROM test-image-1 + +WORKDIR /play + +RUN echo "== LAYER 2 == Remove File C/CA, Remove Dir G, Remove Dir D / Replace with new Dir D, Remove Dir C/CB, Remove Dir C/CB, Remove Dir F, Add File G, Remove Dir H / Create File H" && \ + rm C/CA && \ + rm -rf C/CB && \ + echo "Z is for Cowboy Zoe" >> CZ && \ + rm -rf D && \ + mkdir -p D && \ + echo "A is for Duplicitous Albatros" >D/DA && \ + rm -rf F && \ + rm G && \ + echo "G is for Geccos" >G && \ + rmdir H \ + echo "H is for Human" >H && \ + find . >../state.layer-2 + diff --git a/slides/containers/exploring-images/testplan.sh b/slides/containers/exploring-images/testplan.sh new file mode 100644 index 00000000..da7387c1 --- /dev/null +++ b/slides/containers/exploring-images/testplan.sh @@ -0,0 +1,87 @@ +clear + +baseDir=$(pwd) + +rm -rf /tmp/exploringImags + +mkdir -p /tmp/exploringImags + +cd /tmp/exploringImags + + +echo "== LAYER 0 ==" + +echo "A is for Aardvark" >A +echo "B is for Beetle" >B + +mkdir C/ +echo "A is for Cowboy Allan" >C/CA + +mkdir -p C/CB +echo "A is for Cowboy Buffalo Alex" >C/CB/CBA +echo "B is for Cowboy Buffalo Bill" >C/CB/CBB + +echo "Z is for Cowboy Zeke" >C/CZ + +mkdir D/ +echo "A is for Detective Alisha" >D/DA +echo "B is for Detective Betty" >D/DB + +echo "E is for Elephant" >E + +find . >../state.layer-0 +tree | grep -v directories | tee ../tree.layer-0 + +$baseDir/verifyImageFiles.sh 0 $(pwd) + + +echo "== LAYER 1 == Change File B, Create File C/CC, Add Dir C/CD, Remove File E, Create Dir F, Add File G, Create Empty Dir H" + +echo "B is for Butterfly" >B + +echo "C is for Cowboy Chuck">C/CC + +mkdir -p C/CD +echo "A is for Cowboy Dandy Austin" >C/CD/CDA + +rm E + +mkdir F +echo "A is for Ferret Albert" >F/FA + +echo "G is for Gorilla" >G + +mkdir H + +find . >../state.layer-1 +tree | grep -v directories | tee ../tree.layer-1 + +$baseDir/verifyImageFiles.sh 1 $(pwd) + + +echo "== LAYER 2 == Remove File C/CA, Remove Dir G, Remove Dir D Replace with new Dir D, Remove Dir C/CB, Remove Dir C/CB, Add File H/HA, Add File, Create Dir I" + +rm C/CA + +rm -rf C/CB + +echo "Z is for Cowboy Zoe" >C/CZ + +rm -rf D +mkdir -p D +echo "A is for Duplicitous Albatros" >D/DA + +rm -rf F + +rm -rf G +echo "G is for Geccos" >G + +rmdir H +echo "H is for Human" >H + + +find . >../state.layer-2 +tree | grep -v directories | tee ../tree.layer-2 + +$baseDir/verifyImageFiles.sh 2 $(pwd) + diff --git a/slides/containers/exploring-images/verifyImageFiles.sh b/slides/containers/exploring-images/verifyImageFiles.sh new file mode 100644 index 00000000..c5a6b24e --- /dev/null +++ b/slides/containers/exploring-images/verifyImageFiles.sh @@ -0,0 +1,88 @@ + +fileContentsCompare() { + layer=$1 + text=$2 + file=$(pwd)/$3 + + if [ -f "$file" ]; then + + fileContents=$(cat $file) + + if [ "$fileContents" != "$text" ]; then + echo In Layer $layer Unexpected contents in file: $file + echo -- Contents: $fileContents + echo -- Expected: $text + fi + else + echo Missing File $file in Layer $layer + fi +} + +checkLayer() { + layer=$1 + + find . >/tmp/state + + + if [[ $(diff /tmp/state $targetDir/../state.layer-$layer) ]]; then + echo Directory Structure mismatch in layer: $layer + diff /tmp/state $targetDir/../state.layer-$layer + fi + + case $layer in + 0) + fileContentsCompare $layer "A is for Aardvark" A + fileContentsCompare $layer "B is for Beetle" B + fileContentsCompare $layer "A is for Cowboy Allan" C/CA + fileContentsCompare $layer "A is for Cowboy Buffalo Alex" C/CB/CBA + fileContentsCompare $layer "B is for Cowboy Buffalo Bill" C/CB/CBB + fileContentsCompare $layer "Z is for Cowboy Zeke" C/CZ + fileContentsCompare $layer "A is for Detective Alisha" D/DA + fileContentsCompare $layer "B is for Detective Betty" D/DB + fileContentsCompare $layer "E is for Elephant" E + ;; + + # echo "== LAYER 1 == Change File B, Create File C/CC, Add Dir C/CD, Remove File E, Create Dir F, Add File G, Create Empty Dir H" + 1) + fileContentsCompare $layer "A is for Aardvark" A + fileContentsCompare $layer "B is for Butterfly" B ## CHANGED FILE B + fileContentsCompare $layer "A is for Cowboy Allan" C/CA + fileContentsCompare $layer "A is for Cowboy Buffalo Alex" C/CB/CBA + fileContentsCompare $layer "B is for Cowboy Buffalo Bill" C/CB/CBB + fileContentsCompare $layer "C is for Cowboy Chuck" C/CC ## ADDED FILE C/CC + fileContentsCompare $layer "A is for Cowboy Dandy Austin" C/CD/CDA ## ADDED DIR C/CD, ADDED FILE C/CD/CDA + fileContentsCompare $layer "Z is for Cowboy Zeke" C/CZ + fileContentsCompare $layer "A is for Detective Alisha" D/DA + fileContentsCompare $layer "B is for Detective Betty" D/DB + ## REMOVED FILE E + fileContentsCompare $layer "A is for Ferret Albert" F/FA ## ADDED DIR F, ADDED FILE F/A + fileContentsCompare $layer "G is for Gorilla" G ## ADDED G + ## CREATED EMPTY DIR H + ;; + + # echo "== LAYER 2 == Remove File C/CA, Remove Dir C/CB, Remove Dir C/CB, Remove Dir D Replace with new Dir D, Delete and Recreatee File G, Add File H/HA Create Dir I" + 2) + fileContentsCompare $layer "A is for Aardvark" A + fileContentsCompare $layer "B is for Butterfly" B + ## REMOVED FILE C/CA + ## REMOVED DIR C/CB + fileContentsCompare $layer "C is for Cowboy Chuck" C/CC + fileContentsCompare $layer "A is for Cowboy Dandy Austin" C/CD/CDA + fileContentsCompare $layer "Z is for Cowboy Zoe" C/CZ ## CHANGED FILE C/CZ + ## REMOVE DIR D + fileContentsCompare $layer "A is for Duplicitous Albatros" D/DA ## RECREATE DIR D, ADD FILE D/DA + fileContentsCompare $layer "G is for Geccos" G ## DELETED FILE G, ADDED FILE G (Implicit CHANGED) + fileContentsCompare $layer "H is for Human" H ## ADDED FILE H + ;; + + esac +} + + + +layer=$1 +targetDir=$2 + +echo VERIFYING LAYER $layer + +checkLayer $layer \ No newline at end of file diff --git a/slides/containers/exploring-images/visualizingLayers.jpg b/slides/containers/exploring-images/visualizingLayers.jpg new file mode 100644 index 00000000..b7f1810f Binary files /dev/null and b/slides/containers/exploring-images/visualizingLayers.jpg differ diff --git a/slides/containers/software-deployment.md b/slides/containers/software-deployment.md new file mode 100644 index 00000000..4e2d4f6c --- /dev/null +++ b/slides/containers/software-deployment.md @@ -0,0 +1,120 @@ +# Container Based Software Deployment + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-1.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-2.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-3.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-4.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-5.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-6.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-7.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-8.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-9.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-10.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-11.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-12.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-13.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-14.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-15.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-16.jpg) + +--- + +class: pic + + +![dummmy](containers/software-deployment/slide-17.jpg) diff --git a/slides/containers/software-deployment/slide-1.jpg b/slides/containers/software-deployment/slide-1.jpg new file mode 100644 index 00000000..6d59d482 Binary files /dev/null and b/slides/containers/software-deployment/slide-1.jpg differ diff --git a/slides/containers/software-deployment/slide-10.jpg b/slides/containers/software-deployment/slide-10.jpg new file mode 100644 index 00000000..b9e2b5e9 Binary files /dev/null and b/slides/containers/software-deployment/slide-10.jpg differ diff --git a/slides/containers/software-deployment/slide-11.jpg b/slides/containers/software-deployment/slide-11.jpg new file mode 100644 index 00000000..585b8ffb Binary files /dev/null and b/slides/containers/software-deployment/slide-11.jpg differ diff --git a/slides/containers/software-deployment/slide-12.jpg b/slides/containers/software-deployment/slide-12.jpg new file mode 100644 index 00000000..455389a2 Binary files /dev/null and b/slides/containers/software-deployment/slide-12.jpg differ diff --git a/slides/containers/software-deployment/slide-13.jpg b/slides/containers/software-deployment/slide-13.jpg new file mode 100644 index 00000000..868228d7 Binary files /dev/null and b/slides/containers/software-deployment/slide-13.jpg differ diff --git a/slides/containers/software-deployment/slide-14.jpg b/slides/containers/software-deployment/slide-14.jpg new file mode 100644 index 00000000..293b03f1 Binary files /dev/null and b/slides/containers/software-deployment/slide-14.jpg differ diff --git a/slides/containers/software-deployment/slide-15.jpg b/slides/containers/software-deployment/slide-15.jpg new file mode 100644 index 00000000..cc70ea9f Binary files /dev/null and b/slides/containers/software-deployment/slide-15.jpg differ diff --git a/slides/containers/software-deployment/slide-16.jpg b/slides/containers/software-deployment/slide-16.jpg new file mode 100644 index 00000000..77483d06 Binary files /dev/null and b/slides/containers/software-deployment/slide-16.jpg differ diff --git a/slides/containers/software-deployment/slide-17.jpg b/slides/containers/software-deployment/slide-17.jpg new file mode 100644 index 00000000..90ccffec Binary files /dev/null and b/slides/containers/software-deployment/slide-17.jpg differ diff --git a/slides/containers/software-deployment/slide-2.jpg b/slides/containers/software-deployment/slide-2.jpg new file mode 100644 index 00000000..aa1cfa0a Binary files /dev/null and b/slides/containers/software-deployment/slide-2.jpg differ diff --git a/slides/containers/software-deployment/slide-3.jpg b/slides/containers/software-deployment/slide-3.jpg new file mode 100644 index 00000000..43e3c271 Binary files /dev/null and b/slides/containers/software-deployment/slide-3.jpg differ diff --git a/slides/containers/software-deployment/slide-4.jpg b/slides/containers/software-deployment/slide-4.jpg new file mode 100644 index 00000000..6474fcbe Binary files /dev/null and b/slides/containers/software-deployment/slide-4.jpg differ diff --git a/slides/containers/software-deployment/slide-5.jpg b/slides/containers/software-deployment/slide-5.jpg new file mode 100644 index 00000000..7b3fe72e Binary files /dev/null and b/slides/containers/software-deployment/slide-5.jpg differ diff --git a/slides/containers/software-deployment/slide-6.jpg b/slides/containers/software-deployment/slide-6.jpg new file mode 100644 index 00000000..4795c28e Binary files /dev/null and b/slides/containers/software-deployment/slide-6.jpg differ diff --git a/slides/containers/software-deployment/slide-7.jpg b/slides/containers/software-deployment/slide-7.jpg new file mode 100644 index 00000000..c86dbcad Binary files /dev/null and b/slides/containers/software-deployment/slide-7.jpg differ diff --git a/slides/containers/software-deployment/slide-8.jpg b/slides/containers/software-deployment/slide-8.jpg new file mode 100644 index 00000000..04958f91 Binary files /dev/null and b/slides/containers/software-deployment/slide-8.jpg differ diff --git a/slides/containers/software-deployment/slide-9.jpg b/slides/containers/software-deployment/slide-9.jpg new file mode 100644 index 00000000..40df45fe Binary files /dev/null and b/slides/containers/software-deployment/slide-9.jpg differ diff --git a/slides/k8s/alias-and-references.md b/slides/k8s/alias-and-references.md new file mode 100644 index 00000000..cad46ad8 --- /dev/null +++ b/slides/k8s/alias-and-references.md @@ -0,0 +1,45 @@ + + +# External References && kubectl Aliases + +Class Slides: https://2022-07-proofpoint.container.training/ + +Kubectl Cheat Sheet: https://kubernetes.io/docs/reference/kubectl/cheatsheet/ + +Kubernetes API Object and kubectl Explorers + +- https://github.com/GerrySeidman/Kubernetes-Explorer + +Gerry Kubernetes Storage Converence Talks + +- Vault '20: https://www.usenix.org/conference/vault20/presentation/seidman +- Data and Dev '21: https://www.youtube.com/watch?v=k_8rWPwJ_38 + +Gerry Seidman’s Info + +- gerry.seidman@ardanlabs.com +- https://www.linkedin.com/in/gerryseidman/ + + +--- + +## Kubectl Aliases + +```bash +alias k='kubectl' +alias kg='kubectl get' +alias kl='kubctl logs' +alias ka='kubectl apply -f' +alias kd='kubectl delete' +alias kdf='kubectl delete -f' +alias kb='kubectl describe' +alias kex='kubectl explain' +alias ke='kubectl edit' +alias kx='kubectl exec -it $1 -- /bin/sh' +``` +Note the below is only because of a quirk in how the lab VMs were installed: +```bash +echo 'kubectl exec -it $1 -- /bin/sh' >kx +chmod +x kx +sudo mv kx /usr/local/bin/kx +``` diff --git a/slides/k8s/kubectl-first.md b/slides/k8s/kubectl-first.md new file mode 100644 index 00000000..97bbc00a --- /dev/null +++ b/slides/k8s/kubectl-first.md @@ -0,0 +1,251 @@ +# First contact with `kubectl` + +- `kubectl` is (almost) the only tool we'll need to talk to Kubernetes + +- It is a rich CLI tool around the Kubernetes API + + (Everything you can do with `kubectl`, you can do directly with the API) + +- On our machines, there is a `~/.kube/config` file with: + + - the Kubernetes API address + + - the path to our TLS certificates used to authenticate + +- You can also use the `--kubeconfig` flag to pass a config file + +- Or directly `--server`, `--user`, etc. + +- `kubectl` can be pronounced "Cube C T L", "Cube cuttle", "Cube cuddle"... + +--- + +class: extra-details + +## `kubectl` is the new SSH + +- We often start managing servers with SSH + + (installing packages, troubleshooting ...) + +- At scale, it becomes tedious, repetitive, error-prone + +- Instead, we use config management, central logging, etc. + +- In many cases, we still need SSH: + + - as the underlying access method (e.g. Ansible) + + - to debug tricky scenarios + + - to inspect and poke at things + +--- + +class: extra-details + +## The parallel with `kubectl` + +- We often start managing Kubernetes clusters with `kubectl` + + (deploying applications, troubleshooting ...) + +- At scale (with many applications or clusters), it becomes tedious, repetitive, error-prone + +- Instead, we use automated pipelines, observability tooling, etc. + +- In many cases, we still need `kubectl`: + + - to debug tricky scenarios + + - to inspect and poke at things + +- The Kubernetes API is always the underlying access method + +--- + +## `kubectl get` + +- Let's look at our `Node` resources with `kubectl get`! + +.lab[ + +- Look at the composition of our cluster: + ```bash + kubectl get node + ``` + +- These commands are equivalent: + ```bash + kubectl get no + kubectl get node + kubectl get nodes + ``` + +] + +--- + +## Obtaining machine-readable output + +- `kubectl get` can output JSON, YAML, or be directly formatted + +.lab[ + +- Give us more info about the nodes: + ```bash + kubectl get nodes -o wide + ``` + +- Let's have some YAML: + ```bash + kubectl get no -o yaml + ``` + See that `kind: List` at the end? It's the type of our result! + +] + +--- + +## (Ab)using `kubectl` and `jq` + +- It's super easy to build custom reports + +.lab[ + +- Show the capacity of all our nodes as a stream of JSON objects: + ```bash + kubectl get nodes -o json | + jq ".items[] | {name:.metadata.name} + .status.capacity" + ``` + +] + +--- + +class: extra-details + +## Exploring types and definitions + +- We can list all available resource types by running `kubectl api-resources` +
+ (In Kubernetes 1.10 and prior, this command used to be `kubectl get`) + +- We can view the definition for a resource type with: + ```bash + kubectl explain type + ``` + +- We can view the definition of a field in a resource, for instance: + ```bash + kubectl explain node.spec + ``` + +- Or get the full definition of all fields and sub-fields: + ```bash + kubectl explain node --recursive + ``` + +--- + +class: extra-details + +## Introspection vs. documentation + +- We can access the same information by reading the [API documentation](https://kubernetes.io/docs/reference/#api-reference) + +- The API documentation is usually easier to read, but: + + - it won't show custom types (like Custom Resource Definitions) + + - we need to make sure that we look at the correct version + +- `kubectl api-resources` and `kubectl explain` perform *introspection* + + (they communicate with the API server and obtain the exact type definitions) + +--- + +## Type names + +- The most common resource names have three forms: + + - singular (e.g. `node`, `service`, `deployment`) + + - plural (e.g. `nodes`, `services`, `deployments`) + + - short (e.g. `no`, `svc`, `deploy`) + +- Some resources do not have a short name + +- `Endpoints` only have a plural form + + (because even a single `Endpoints` resource is actually a list of endpoints) + +--- + +## Viewing details + +- We can use `kubectl get -o yaml` to see all available details + +- However, YAML output is often simultaneously too much and not enough + +- For instance, `kubectl get node node1 -o yaml` is: + + - too much information (e.g.: list of images available on this node) + + - not enough information (e.g.: doesn't show pods running on this node) + + - difficult to read for a human operator + +- For a comprehensive overview, we can use `kubectl describe` instead + +--- + +## `kubectl describe` + +- `kubectl describe` needs a resource type and (optionally) a resource name + +- It is possible to provide a resource name *prefix* + + (all matching objects will be displayed) + +- `kubectl describe` will retrieve some extra information about the resource + +.lab[ + +- Look at the information available for `node1` with one of the following commands: + ```bash + kubectl describe node/node1 + kubectl describe node node1 + ``` + +] + +(We should notice a bunch of control plane pods.) + +--- + +## Listing running containers + +- Containers are manipulated through *pods* + +- A pod is a group of containers: + + - running together (on the same node) + + - sharing resources (RAM, CPU; but also network, volumes) + +.lab[ + +- List pods on our cluster: + ```bash + kubectl get pods + ``` + +] + +-- + +*Where are the pods that we saw just a moment earlier?!?* + diff --git a/slides/k8s/kubectl-more.md b/slides/k8s/kubectl-more.md new file mode 100644 index 00000000..316c6b81 --- /dev/null +++ b/slides/k8s/kubectl-more.md @@ -0,0 +1,340 @@ +# More contact with `kubectl` + +- Namespaces +- Clusters +- Proxy + +--- + +## Namespaces + +- Namespaces allow us to segregate resources + +.lab[ + +- List the namespaces on our cluster with one of these commands: + ```bash + kubectl get namespaces + kubectl get namespace + kubectl get ns + ``` + +] + +-- + +*You know what ... This `kube-system` thing looks suspicious.* + +*In fact, I'm pretty sure it showed up earlier, when we did:* + +`kubectl describe node node1` + +--- + +## Accessing namespaces + +- By default, `kubectl` uses the `default` namespace + +- We can see resources in all namespaces with `--all-namespaces` + +.lab[ + +- List the pods in all namespaces: + ```bash + kubectl get pods --all-namespaces + ``` + +- Since Kubernetes 1.14, we can also use `-A` as a shorter version: + ```bash + kubectl get pods -A + ``` + +] + +*Here are our system pods!* + +--- + +## What are all these control plane pods? + +- `etcd` is our etcd server + +- `kube-apiserver` is the API server + +- `kube-controller-manager` and `kube-scheduler` are other control plane components + +- `coredns` provides DNS-based service discovery ([replacing kube-dns as of 1.11](https://kubernetes.io/blog/2018/07/10/coredns-ga-for-kubernetes-cluster-dns/)) + +- `kube-proxy` is the (per-node) component managing port mappings and such + +- `weave` is the (per-node) component managing the network overlay + +- the `READY` column indicates the number of containers in each pod + + (1 for most pods, but `weave` has 2, for instance) + +--- + +## Scoping another namespace + +- We can also look at a different namespace (other than `default`) + +.lab[ + +- List only the pods in the `kube-system` namespace: + ```bash + kubectl get pods --namespace=kube-system + kubectl get pods -n kube-system + ``` + +] + +--- + +## Namespaces and other `kubectl` commands + +- We can use `-n`/`--namespace` with almost every `kubectl` command + +- Example: + + - `kubectl create --namespace=X` to create something in namespace X + +- We can use `-A`/`--all-namespaces` with most commands that manipulate multiple objects + +- Examples: + + - `kubectl delete` can delete resources across multiple namespaces + + - `kubectl label` can add/remove/update labels across multiple namespaces + +--- + +class: extra-details + +## What about `kube-public`? + +.lab[ + +- List the pods in the `kube-public` namespace: + ```bash + kubectl -n kube-public get pods + ``` + +] + +Nothing! + +`kube-public` is created by kubeadm & [used for security bootstrapping](https://kubernetes.io/blog/2017/01/stronger-foundation-for-creating-and-managing-kubernetes-clusters). + +--- + +class: extra-details + +## Exploring `kube-public` + +- The only interesting object in `kube-public` is a ConfigMap named `cluster-info` + +.lab[ + +- List ConfigMap objects: + ```bash + kubectl -n kube-public get configmaps + ``` + +- Inspect `cluster-info`: + ```bash + kubectl -n kube-public get configmap cluster-info -o yaml + ``` + +] + +Note the `selfLink` URI: `/api/v1/namespaces/kube-public/configmaps/cluster-info` + +We can use that! + +--- + +class: extra-details + +## Accessing `cluster-info` + +- Earlier, when trying to access the API server, we got a `Forbidden` message + +- But `cluster-info` is readable by everyone (even without authentication) + +.lab[ + +- Retrieve `cluster-info`: + ```bash + curl -k https://10.96.0.1/api/v1/namespaces/kube-public/configmaps/cluster-info + ``` + +] + +- We were able to access `cluster-info` (without auth) + +- It contains a `kubeconfig` file + +--- + +class: extra-details + +## Retrieving `kubeconfig` + +- We can easily extract the `kubeconfig` file from this ConfigMap + +.lab[ + +- Display the content of `kubeconfig`: + ```bash + curl -sk https://10.96.0.1/api/v1/namespaces/kube-public/configmaps/cluster-info \ + | jq -r .data.kubeconfig + ``` + +] + +- This file holds the canonical address of the API server, and the public key of the CA + +- This file *does not* hold client keys or tokens + +- This is not sensitive information, but allows us to establish trust + +--- + +class: extra-details + +## What about `kube-node-lease`? + +- Starting with Kubernetes 1.14, there is a `kube-node-lease` namespace + + (or in Kubernetes 1.13 if the NodeLease feature gate is enabled) + +- That namespace contains one Lease object per node + +- *Node leases* are a new way to implement node heartbeats + + (i.e. node regularly pinging the control plane to say "I'm alive!") + +- For more details, see [Efficient Node Heartbeats KEP] or the [node controller documentation] + +[Efficient Node Heartbeats KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/589-efficient-node-heartbeats/README.md +[node controller documentation]: https://kubernetes.io/docs/concepts/architecture/nodes/#node-controller + +--- + +## Services + +- A *service* is a stable endpoint to connect to "something" + + (In the initial proposal, they were called "portals") + +.lab[ + +- List the services on our cluster with one of these commands: + ```bash + kubectl get services + kubectl get svc + ``` + +] + +-- + +There is already one service on our cluster: the Kubernetes API itself. + +--- + +## ClusterIP services + +- A `ClusterIP` service is internal, available from the cluster only + +- This is useful for introspection from within containers + +.lab[ + +- Try to connect to the API: + ```bash + curl -k https://`10.96.0.1` + ``` + + - `-k` is used to skip certificate verification + + - Make sure to replace 10.96.0.1 with the CLUSTER-IP shown by `kubectl get svc` + +] + +The command above should either time out, or show an authentication error. Why? + +--- + +## Time out + +- Connections to ClusterIP services only work *from within the cluster* + +- If we are outside the cluster, the `curl` command will probably time out + + (Because the IP address, e.g. 10.96.0.1, isn't routed properly outside the cluster) + +- This is the case with most "real" Kubernetes clusters + +- To try the connection from within the cluster, we can use [shpod](https://github.com/jpetazzo/shpod) + +--- + +## Authentication error + +This is what we should see when connecting from within the cluster: +```json +$ curl -k https://10.96.0.1 +{ + "kind": "Status", + "apiVersion": "v1", + "metadata": { + + }, + "status": "Failure", + "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"", + "reason": "Forbidden", + "details": { + + }, + "code": 403 +} +``` + +--- + +## Explanations + +- We can see `kind`, `apiVersion`, `metadata` + +- These are typical of a Kubernetes API reply + +- Because we *are* talking to the Kubernetes API + +- The Kubernetes API tells us "Forbidden" + + (because it requires authentication) + +- The Kubernetes API is reachable from within the cluster + + (many apps integrating with Kubernetes will use this) + +--- + +## DNS integration + +- Each service also gets a DNS record + +- The Kubernetes DNS resolver is available *from within pods* + + (and sometimes, from within nodes, depending on configuration) + +- Code running in pods can connect to services using their name + + (e.g. https://kubernetes/...) + +??? + +:EN:- Getting started with kubectl +:FR:- Se familiariser avec kubectl diff --git a/slides/kube.orig.yml b/slides/kube.orig.yml new file mode 100644 index 00000000..42d4f047 --- /dev/null +++ b/slides/kube.orig.yml @@ -0,0 +1,99 @@ +title: | + Kubernetes + Intermediate + Training + +chat: "`Zoom Chat`" + +gitrepo: github.com/jpetazzo/container.training + +slides: https://2022-08-nr.container.training/ + +#slidenumberprefix: "#SomeHashTag — " + +exclude: +- self-paced + +content: +- shared/title.md +- logistics-gerry.md +- k8s/intro.md +- shared/about-slides.md +#- shared/chat-room-im.md +- shared/chat-room-slack.md +#- shared/chat-room-zoom-meeting.md +#- shared/chat-room-zoom-webinar.md +- shared/toc.md +- exercises/k8sfundamentals-brief.md +- exercises/localcluster-brief.md +- exercises/healthchecks-brief.md +- exercises/ingress-brief.md +- exercises/appconfig-brief.md +- # DAY 1 + - shared/prereqs.md + - shared/webssh.md + - shared/connecting.md + #- k8s/versions-k8s.md + - shared/sampleapp.md + - shared/composedown.md + - k8s/concepts-k8s.md + - k8s/kubectlget.md + - k8s/kubectl-run.md + - k8s/kubenet.md + - k8s/kubectlexpose.md + - k8s/shippingimages.md + #- k8s/buildshiprun-selfhosted.md + - k8s/buildshiprun-dockerhub.md + - exercises/k8sfundamentals-details.md +- # DAY 2 + - k8s/ourapponkube.md + - shared/declarative.md + - k8s/declarative.md + - k8s/deploymentslideshow.md + - k8s/labels-annotations.md + - k8s/kubectl-logs.md + - k8s/logs-cli.md + - k8s/namespaces.md + - k8s/yamldeploy.md + - k8s/setup-overview.md + - k8s/setup-devel.md + - k8s/localkubeconfig.md + - k8s/accessinternal.md + #- k8s/kubectlproxy.md + - k8s/k9s.md + - k8s/tilt.md + - exercises/localcluster-details.md +- # DAY 3 + - k8s/scalingdockercoins.md + - shared/hastyconclusions.md + - k8s/daemonset.md + - k8s/rollout.md + - k8s/healthchecks.md + - exercises/healthchecks-details.md + - k8s/ingress.md + #- k8s/ingress-tls.md + - exercises/ingress-details.md +- # DAY 4 + - k8s/netpol.md + - k8s/authn-authz.md + - k8s/resource-limits.md + - k8s/metrics-server.md + - k8s/cluster-sizing.md +- # DAY 5 + - k8s/volumes.md + - k8s/configuration.md + - k8s/secrets.md + - exercises/appconfig-details.md + - k8s/statefulsets.md + - k8s/consul.md + - k8s/pv-pvc-sc.md + - k8s/volume-claim-templates.md + #- k8s/portworx.md + #- k8s/openebs.md + #- k8s/stateful-failover.md +- # Extra + - | + # (Extra content) + - k8s/horizontal-pod-autoscaler.md + - k8s/dashboard.md + - k8s/batch-jobs.md diff --git a/slides/kube.yml b/slides/kube.yml index 9bd03d82..ee7b142f 100644 --- a/slides/kube.yml +++ b/slides/kube.yml @@ -3,7 +3,7 @@ title: | Intermediate Training -chat: "`#kubernetes-training-FIXME`" +chat: "`Zoom Chat`" gitrepo: github.com/jpetazzo/container.training @@ -16,84 +16,105 @@ exclude: content: - shared/title.md -- logistics.md +- logistics-gerry.md - k8s/intro.md - shared/about-slides.md #- shared/chat-room-im.md -- shared/chat-room-slack.md +# - shared/chat-room-slack.md #- shared/chat-room-zoom-meeting.md -#- shared/chat-room-zoom-webinar.md +- shared/chat-room-zoom-webinar.md +- shared/prereqs.md +- shared/webssh.md +- shared/connecting.md + - shared/toc.md - exercises/k8sfundamentals-brief.md - exercises/localcluster-brief.md - exercises/healthchecks-brief.md - exercises/ingress-brief.md - exercises/appconfig-brief.md -- # DAY 1 - - shared/prereqs.md - - shared/webssh.md - - shared/connecting.md +- +# DAY 1 + - containers/Macro_View.md + - containers/software-deployment.md + #- shared/webssh.md #- k8s/versions-k8s.md - - shared/sampleapp.md - - shared/composedown.md + #- shared/composescale.md - k8s/concepts-k8s.md - - k8s/kubectlget.md - - k8s/kubectl-run.md - - k8s/kubenet.md - - k8s/kubectlexpose.md - - k8s/shippingimages.md - #- k8s/buildshiprun-selfhosted.md - - k8s/buildshiprun-dockerhub.md - - exercises/k8sfundamentals-details.md -- # DAY 2 - - k8s/ourapponkube.md + - k8s/deploymentslideshow.md - shared/declarative.md - k8s/declarative.md - - k8s/deploymentslideshow.md - - k8s/labels-annotations.md + #- shared/hastyconclusions.md + # - k8s/shippingimages.md + + - k8s/kubectl-first.md + - k8s/authoring-yaml.md + #- k8s/buildshiprun-selfhosted.md + - k8s/alias-and-references.md + +- # DAY 2 - k8s/kubectl-logs.md - k8s/logs-cli.md + - k8s/labels-annotations.md + - k8s/kubectl-run.md + - k8s/kubectl-more.md + - k8s/rollout.md + - k8s/yamldeploy.md - k8s/namespaces.md - - k8s/yamldeploy.md + - k8s/daemonset.md + +- # DAY 3 + - k8s/healthchecks.md + - k8s/kubenet.md + - k8s/kubectlexpose.md + - k8s/volumes.md + - k8s/configuration.md + - k8s/secrets.md + - k8s/ingress.md + - exercises/ingress-details.md + - exercises/healthchecks-details.md + - exercises/appconfig-details.md + +- # DAY 4 + - k8s/statefulsets.md + - k8s/pv-pvc-sc.md + - k8s/volume-claim-templates.md - k8s/setup-overview.md - k8s/setup-devel.md - k8s/localkubeconfig.md - k8s/accessinternal.md - #- k8s/kubectlproxy.md - - k8s/k9s.md - - k8s/tilt.md + - k8s/kubectlproxy.md - exercises/localcluster-details.md -- # DAY 3 - - k8s/scalingdockercoins.md - - shared/hastyconclusions.md - - k8s/daemonset.md - - k8s/rollout.md - - k8s/healthchecks.md - - exercises/healthchecks-details.md - - k8s/ingress.md - #- k8s/ingress-tls.md - - exercises/ingress-details.md -- # DAY 4 + +- # DAY 5 - k8s/netpol.md - k8s/authn-authz.md - k8s/resource-limits.md - k8s/metrics-server.md - k8s/cluster-sizing.md -- # DAY 5 - - k8s/volumes.md - - k8s/configuration.md - - k8s/secrets.md - - exercises/appconfig-details.md - - k8s/statefulsets.md + - k8s/k9s.md + - k8s/tilt.md - k8s/consul.md - - k8s/pv-pvc-sc.md - - k8s/volume-claim-templates.md - #- k8s/portworx.md - #- k8s/openebs.md - #- k8s/stateful-failover.md + - shared/thankyou.md + +- # DockerCoins + - | + # (Docker Coins Example) + - shared/sampleapp.md + - shared/composedown.md + - k8s/buildshiprun-dockerhub.md + - k8s/shippingimages.md + - exercises/k8sfundamentals-details.md + - k8s/ourapponkube.md + - k8s/scalingdockercoins.md + - shared/hastyconclusions.md - # Extra - | # (Extra content) - k8s/horizontal-pod-autoscaler.md - k8s/dashboard.md - k8s/batch-jobs.md + - k8s/helm-intro.md + - k8s/helm-chart-format.md + - k8s/helm-create-basic-chart.md + - k8s/helm-create-better-chart.md diff --git a/slides/logistics-gerry.md b/slides/logistics-gerry.md new file mode 100644 index 00000000..1f1f7442 --- /dev/null +++ b/slides/logistics-gerry.md @@ -0,0 +1,60 @@ +## While We are Waiting To Get Started ... + +- If you have not already done so, please complete this survey: [https://tinyurl.com/mrx6fsrh +](https://docs.google.com/forms/d/1w6wmnvbzyBPbt6f-k0B1ueA-pnkY_zmvROoeRj-vdFU) + +- Your lab computers are assigned on this Google Sheet: [https://tinyurl.com/53dm9b66](https://docs.google.com/spreadsheets/d/1aXF46q5jtQUOEQGniPffljmrPX0PmYRc0x7XKogFmQU/edit) + + - Enter your name in column 1 in one of the unclaimed rows + + - Your Lab Computer IP address is found in the ** node1 ** column + + - Log into your lab computer: ** ssh -l k8s node1 ** + + - Password is: ** relics ** + + - Verify all is good with the command: ** kubectl version --short ** + +- Class Starts at 9AM PST / 11AM EST each day + +--- + +## Introductions + +- Hello! I'm [Gerry Seidman](https://www.linkedin.com/in/gerryseidman), Ardan Labs (gerry.seidman@ardanlabs.com) + +- The training will run Monday to Friday, from 8:00AM to 12:00PM PST (11AM-3PM EST) + +- There will be breaks! + +- Feel free to interrupt for questions at any time + +- *Especially when you see full screen container pictures!* + +- Live feedback, questions, help: @@CHAT@@ + + + +[@alexbuisine]: https://twitter.com/alexbuisine +[EphemeraSearch]: https://ephemerasearch.com/ +[@jpetazzo]: https://twitter.com/jpetazzo +[@s0ulshake]: https://twitter.com/s0ulshake +[Quantgene]: https://www.quantgene.com/ + +--- + +## Exercises + +- At the end of each day, there is a series of exercises + +- To make the most out of the training, please try the exercises! + + (it will help to practice and memorize the content of the day) + +- We'll try to finish a bit earlier each day so that you can have lab time + + (and if you can put some extra time that's even better ♥) + +- Each day will start with a quick review of the exercises of the previous day + +- If you have any questions, blockers, curiosities ... Ping me in the zoom chat diff --git a/slides/out.html b/slides/out.html new file mode 100644 index 00000000..028f4692 --- /dev/null +++ b/slides/out.html @@ -0,0 +1,20235 @@ + + + + Kubernetes Intermediate Training + + + + + + + + + + + + + + + diff --git a/slides/shared/prereqs.md b/slides/shared/prereqs.md index 7ed926fa..17f0c933 100644 --- a/slides/shared/prereqs.md +++ b/slides/shared/prereqs.md @@ -1,4 +1,4 @@ -# Pre-requirements +## Pre-requirements - Be comfortable with the UNIX command line