From a824afec853d15437fc2df80452078e70c91fe65 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 29 Nov 2019 09:34:25 -0600 Subject: [PATCH 01/12] Add shortlinks for uDemy course --- slides/_redirects | 3 +++ 1 file changed, 3 insertions(+) diff --git a/slides/_redirects b/slides/_redirects index e7606e61..b274de0a 100644 --- a/slides/_redirects +++ b/slides/_redirects @@ -5,3 +5,6 @@ # And this allows to do "git clone https://container.training". /info/refs service=git-upload-pack https://github.com/jpetazzo/container.training/info/refs?service=git-upload-pack + +/dockermastery https://www.udemy.com/course/docker-mastery/?referralCode=7E09090AF9B79E6C283F +/kubernetesmastery https://www.udemy.com/course/kubernetesmastery/?referralCode=7E09090AF9B79E6C283F From 4811420d5566aa9b7f50eccdb9831b31b575507f Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 29 Nov 2019 12:48:59 -0600 Subject: [PATCH 02/12] Update Docker Mastery referral code --- slides/_redirects | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slides/_redirects b/slides/_redirects index b274de0a..0b254c7a 100644 --- a/slides/_redirects +++ b/slides/_redirects @@ -6,5 +6,5 @@ # And this allows to do "git clone https://container.training". /info/refs service=git-upload-pack https://github.com/jpetazzo/container.training/info/refs?service=git-upload-pack -/dockermastery https://www.udemy.com/course/docker-mastery/?referralCode=7E09090AF9B79E6C283F +/dockermastery https://www.udemy.com/course/docker-mastery/?referralCode=1410924A733D33635CCB /kubernetesmastery https://www.udemy.com/course/kubernetesmastery/?referralCode=7E09090AF9B79E6C283F From b37dd85effcaf1cd3f2ac43eb85f6d80bf42177f Mon Sep 17 00:00:00 2001 From: Julien Girardin Date: Thu, 5 Dec 2019 18:36:20 +0100 Subject: [PATCH 03/12] Add Init_system slides --- slides/containers/Init_systems.md | 79 +++++++++++++++++++++++++++++++ slides/intro-fullday.yml | 1 + 2 files changed, 80 insertions(+) create mode 100644 slides/containers/Init_systems.md diff --git a/slides/containers/Init_systems.md b/slides/containers/Init_systems.md new file mode 100644 index 00000000..60c9da22 --- /dev/null +++ b/slides/containers/Init_systems.md @@ -0,0 +1,79 @@ +# Init-systems and PID 1 + +In this chapter, we will consider the role of PID 1 in the world of Docker, + +and how to avoid some common pitfalls due to the misuse of init-systems. + +--- +## Don't use init-systems + +- It's often tempting to use init-systems (*systemd*, *supervisord*) + + and use docker as a "lightweight VM" + +- This often a bad idea, as it make things harder to debug: + + - *example 1*: if you start a container changing it's entrypoint to a shell, + + how to easily start the original process ? + + - *example 2*: if you run multiple process, logs are mixed to stdout + + - *example 3*: you're process is dying but you're init process is not + + => the container is running for nothing + +--- +## Don't use init-systems, but ... + +- In UNIX, a dead child process still use a PID till it's parent read it's status + +- In the meantime of being read by it's parent, + + those process are called `Zombie` or `defunct` process + +- If not being ripped off, zombie processes could crash a server (PID exhaution) + +- If the parent also dies before reading it's child container the zombie are attach to the PID 1 in some cases. + +- On a VM or real system, one of the role of the PID 1(Init-systems) is to rip zombies. + + *This also apply to containers* + +--- +## Use an init + +- You're application is running as PID 1 in the docker container + +- You're application is surely not designed to read status of random attaching child + +- Then everything is blowing up due to PID exhaution + + => Docker now has a built-in init you can enable `docker run --init` + +- This is a small init-system([tini](https://github.com/krallin/tini)) that takes the role of PID 1 + +- Only rips zombies, completly transparent otherwise + + (forwards signals, exit when child exit, etc). + +- Orchestrators like kubernetes has no option to turn `--init` when running container, + + so you might want to add explicitly to you're docker image, and use it as entrypoint + +--- +## Use it or not ? + +- Sometimes it's also handy to run a full init-system like *systemd*: + + - In CI when you're goal is exactly to test an init-script or a unit-file. + +- You might think, if it's ok for *systemd*, this is surely ok for *supervisord* + + especially running multiple times the same process (then, mixed logs is not a big deal) + + => I would strongly *NOT* recommand to do so. + +- It's often design to restart unhealthy process automatically + + and thus masquerade things to the operator or to the orchestrator (whose role is identical) diff --git a/slides/intro-fullday.yml b/slides/intro-fullday.yml index e5d32e8a..65b6beb6 100644 --- a/slides/intro-fullday.yml +++ b/slides/intro-fullday.yml @@ -60,6 +60,7 @@ chapters: - - containers/Docker_Machine.md - containers/Advanced_Dockerfiles.md + - containers/Init_systems.md - containers/Application_Configuration.md - containers/Logging.md - From 34a17aa0974101422ec58505e24070bbdbd55dd0 Mon Sep 17 00:00:00 2001 From: Julien Girardin Date: Fri, 6 Dec 2019 16:40:00 +0100 Subject: [PATCH 04/12] Add a Pod anatomy set of slides --- slides/images/kubernetes_pods.drawio | 1 + slides/images/kubernetes_pods.svg | 3 +++ slides/intro-fullday.yml | 1 + slides/k8s/Pods_anatomy.md | 27 +++++++++++++++++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 slides/images/kubernetes_pods.drawio create mode 100644 slides/images/kubernetes_pods.svg create mode 100644 slides/k8s/Pods_anatomy.md diff --git a/slides/images/kubernetes_pods.drawio b/slides/images/kubernetes_pods.drawio new file mode 100644 index 00000000..05573b10 --- /dev/null +++ b/slides/images/kubernetes_pods.drawio @@ -0,0 +1 @@ +3VhLU9swEP41nmkPzcR2EpIjCaHtUEo6HCi9dBRb2BoUy8hyHvz6rmzJD9mBQBJgmoMjrVcr6dtvVytb7mSx/spRHF4yH1PL6fpryz2zHMcZ9Rz4k5JNLrFtd5RLAk58JSsF1+QRK2FXSVPi46SmKBijgsR1oceiCHuiJkOcs1Vd7Y7R+qwxCnBDcO0h2pTeEF+EuXTonJTyb5gEoZ7ZHqj9LZBWVjtJQuSzVUXkTi13whkTeWuxnmAq0dO45OPOt7wtFsZxJHYZ8PfXAwsvwsvLP5duOpn2bx4ufnyx1WqXiKZqx5YzoGBw7JMlNAPZDFkiQOkTGF8iDk9K5vC8T+eYYnhz3ul0Putxc66HaQkoVIwpNMRGQ8xZGvlYrrILr1chEfg6Rp58uwJWyfnFgkLPhiaiJIigzXPMlbUl5gKvtwJjF3ADUTFbYME3oKIGDJWDFEXdruqvSn/3ekoWVn2tPYsUx4LCdOkGaChPvMQrDafMmL8fbiHj5JFFAmmBhIwAz08VoILFR4GztyOaheLB0XQaaMYoTXCeNAQiEeb7YXsA0AoubeogVlBz3RbUjgaa2wAtCki0/nBA2S38elukei0Z1AAJR/6pPIug51GUJMSr4wJ755vf1c6tBLTT192ztQI47210b01EMQzalVHQKwfJTjHGh/NNLQ3TOVtNS4FykFR52j2wO5ZyDz9PIIF4gMVz0dl0d8Wd/RZvahnHFAmyrC+3zcVqhhkjkaiwqWvk/oHBknybalT1cDUN9Q1DtmEox6FhCGiBNhW1WCok2xfcM7Kr7dYOfWjkFks6F5i+nuHNGiHm0miI00TSZR0ziOiPl0SdlpP8bXOD3TzJd0sOCfBFaHHEIvxBE0a2znMiUcmUd00g7xXwPSNOHbOG2zXgTUNFJjl2wA/eIODtYQttG7eCn1isGL+3JIQDtJDxnD9B8n02yeU7XgkaxiO0wEmWLLKbEydRsON1AvKHaL8zeMBBSFPN2ndBfD+jM8cJeUTzzJSks/IO2O2Prf6ZnM4dUwTXnjHy7oMswU0YZTyb2r3LftIOE8BSJm2PyrBoSW7q2qqmtAo6VgPmicyyNRV2O1Bl92rM0XXwvkfm0AigugF2d5dgYVD0MKRslqQN3wNTYpxlTIGfP3LmhQ+vUkGJTLKZ3Ef8/gpGEZHlwE5XJsgk/zThHOmscp3mWTVoyYPDox1VB6hjP3r2t/XnKBP0F5d7hiF7aITBlux/sFgY/E+x4JhV+LvHwsn+saBLLV1P3VZrK7lxe1QWXtX6bIY5gW3Ig+pFJdUOd7KcNu8VfeaHoZNXBp9jlvlm+f7q4INu+T02Vy8/a7vTfw== \ No newline at end of file diff --git a/slides/images/kubernetes_pods.svg b/slides/images/kubernetes_pods.svg new file mode 100644 index 00000000..b878be95 --- /dev/null +++ b/slides/images/kubernetes_pods.svg @@ -0,0 +1,3 @@ + + +
host (/var/lib/kubelet/...)
<div>host (/var/lib/kubelet/...)<br></div>
Pod
Pod
pause container
pause container
nginx
nginx
prometheus exporter
prometheus exporter
Network & IPC
namespace sharing
[Not supported by viewer]
:80
:80
private IP
private IP
\ No newline at end of file diff --git a/slides/intro-fullday.yml b/slides/intro-fullday.yml index e5d32e8a..8628bba5 100644 --- a/slides/intro-fullday.yml +++ b/slides/intro-fullday.yml @@ -68,6 +68,7 @@ chapters: #- containers/Containers_From_Scratch.md - - containers/Container_Engines.md + - k8s/Pods_anatomy.md #- containers/Ecosystem.md - containers/Orchestration_Overview.md - shared/thankyou.md diff --git a/slides/k8s/Pods_anatomy.md b/slides/k8s/Pods_anatomy.md new file mode 100644 index 00000000..6c4db842 --- /dev/null +++ b/slides/k8s/Pods_anatomy.md @@ -0,0 +1,27 @@ +# container super-structure (Pods) + +A container super-structure supported by many container engine seems to emerge, +we will see how it maps in the docker worlds + + + +--- +class: pic + +## Pod + +![Pods](images/kubernetes_pods.svg) +--- +# Anatomy of a Pod + +- The containers inside a pod share the network namespace (`--net=container:`) + + => the one of the "pause" containers + +- This means that if the container "pause" is killed all other container are killed + +- This is the reason for this container to do nothing but being alive + +- Containers can contact other container port via `localhost` + +- Containers don't share filesystem except the volumes you want to mount on each of them From 7281ca3ca013762413703a48a276807ac64a4a58 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 6 Dec 2019 14:16:48 -0600 Subject: [PATCH 05/12] Tweak content for inclusion in master branch --- slides/containers/Init_Systems.md | 137 ++++++++++++++++++++++++++++++ slides/containers/Init_systems.md | 79 ----------------- slides/intro-fullday.yml | 2 +- slides/intro-selfpaced.yml | 1 + 4 files changed, 139 insertions(+), 80 deletions(-) create mode 100644 slides/containers/Init_Systems.md delete mode 100644 slides/containers/Init_systems.md diff --git a/slides/containers/Init_Systems.md b/slides/containers/Init_Systems.md new file mode 100644 index 00000000..510cdbe8 --- /dev/null +++ b/slides/containers/Init_Systems.md @@ -0,0 +1,137 @@ +# Init systems and PID 1 + +In this chapter, we will consider: + +- the role of PID 1 in the world of Docker, + +- how to avoid some common pitfalls due to the misuse of init systems. + +--- + +## What's an init system? + +- On UNIX, the "init system" (or "init" in short) is PID 1. + +- It is the first process started by the kernel when the system starts. + +- It has multiple responsibilities: + + - start every other process on the machine, + + - reap orphaned zombie processes. + +--- + +class: extra-details + +## Orphaned zombie processes ?!? + +- When a process exits (or "dies"), it becomes a "zombie". + + (Zombie processes show up in `ps` or `top` with the status code `Z`.) + +- Its parent process must *reap* the zombie process. + + (This is done by calling `waitpid()` to retrieve the process' exit status.) + +- When a process exits, if it has child processes, these processes are "orphaned." + +- They are then re-parented to PID 1, init. + +- Init therefore needs to take care of these orphaned processes when they exit. + +--- + +## Don't use init systems in containers + +- It's often tempting to use an init system or a process manager. + + (Examples: *systemd*, *supervisord*...) + +- Our containers are then called "system containers". + + (By contrast with "application containers".) + +- "System containers" are similar to lightweight virtual machines. + +- They have multiple downsides: + + - when starting multiple processes, their logs get mixed on stdout, + + - if the application process dies, the container engine doesn't see it. + +- Overall, they make it harder to operate troubleshoot containerized apps. + +--- + +## Exceptions and workarounds + +- Sometimes, it's convenient to run a real init system like *systemd*. + + (Example: a CI system whose goal is precisely to test an init script or unit file.) + +- If we need to run multiple processes: can we use multiple containers? + + (Example: [this Compose file](https://github.com/jpetazzo/container.training/blob/master/compose/simple-k8s-control-plane/docker-compose.yaml) runs multiple processes together.) + +- When deploying with Kubernetes: + + - a container belong to a pod, + + - a pod can have multiple containers. + +--- + +## What about these zombie processes? + +- Our application runs as PID 1 in the container. + +- Our application may or may not be designed to reap zombie processes. + +- If our application uses subprocesses and doesn't reap them ... + + ... this can lead to PID exhaustion! + + (Or, more realistically, to a confusing herd of zombie processes.) + +- How can we solve this? + +--- + +## Tini to the rescue + +- Docker can automatically provide a minimal `init` process. + +- This is enabled with `docker run --init ...` + +- It uses a small init system ([tini](https://github.com/krallin/tini)) as PID 1: + + - it reaps zombies, + + - it forwards signals, + + - it exits when the child exits. + +- It is totally transparent to our application. + +- We should use it if our application creates subprocess but doesn't reap them. + +--- + +class: extra-details + +## What about Kubernetes? + +- Kubernetes does not expose that `--init` option. + +- However, we can achieve the same result with [Process Namespace Sharing](https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/). + +- When Process Namespace Sharing is enabled, PID 1 will be `pause`. + +- That `pause` process takes care of reaping zombies. + +- Process Namespace Sharing is available since Kubernetes 1.16. + +- If you're using an older version of Kubernetes ... + + ... you might have to add `tini` explicitly to your Docker image. diff --git a/slides/containers/Init_systems.md b/slides/containers/Init_systems.md deleted file mode 100644 index 60c9da22..00000000 --- a/slides/containers/Init_systems.md +++ /dev/null @@ -1,79 +0,0 @@ -# Init-systems and PID 1 - -In this chapter, we will consider the role of PID 1 in the world of Docker, - -and how to avoid some common pitfalls due to the misuse of init-systems. - ---- -## Don't use init-systems - -- It's often tempting to use init-systems (*systemd*, *supervisord*) - - and use docker as a "lightweight VM" - -- This often a bad idea, as it make things harder to debug: - - - *example 1*: if you start a container changing it's entrypoint to a shell, - - how to easily start the original process ? - - - *example 2*: if you run multiple process, logs are mixed to stdout - - - *example 3*: you're process is dying but you're init process is not - - => the container is running for nothing - ---- -## Don't use init-systems, but ... - -- In UNIX, a dead child process still use a PID till it's parent read it's status - -- In the meantime of being read by it's parent, - - those process are called `Zombie` or `defunct` process - -- If not being ripped off, zombie processes could crash a server (PID exhaution) - -- If the parent also dies before reading it's child container the zombie are attach to the PID 1 in some cases. - -- On a VM or real system, one of the role of the PID 1(Init-systems) is to rip zombies. - - *This also apply to containers* - ---- -## Use an init - -- You're application is running as PID 1 in the docker container - -- You're application is surely not designed to read status of random attaching child - -- Then everything is blowing up due to PID exhaution - - => Docker now has a built-in init you can enable `docker run --init` - -- This is a small init-system([tini](https://github.com/krallin/tini)) that takes the role of PID 1 - -- Only rips zombies, completly transparent otherwise - - (forwards signals, exit when child exit, etc). - -- Orchestrators like kubernetes has no option to turn `--init` when running container, - - so you might want to add explicitly to you're docker image, and use it as entrypoint - ---- -## Use it or not ? - -- Sometimes it's also handy to run a full init-system like *systemd*: - - - In CI when you're goal is exactly to test an init-script or a unit-file. - -- You might think, if it's ok for *systemd*, this is surely ok for *supervisord* - - especially running multiple times the same process (then, mixed logs is not a big deal) - - => I would strongly *NOT* recommand to do so. - -- It's often design to restart unhealthy process automatically - - and thus masquerade things to the operator or to the orchestrator (whose role is identical) diff --git a/slides/intro-fullday.yml b/slides/intro-fullday.yml index 65b6beb6..7daec807 100644 --- a/slides/intro-fullday.yml +++ b/slides/intro-fullday.yml @@ -60,7 +60,7 @@ chapters: - - containers/Docker_Machine.md - containers/Advanced_Dockerfiles.md - - containers/Init_systems.md + - containers/Init_Systems.md - containers/Application_Configuration.md - containers/Logging.md - diff --git a/slides/intro-selfpaced.yml b/slides/intro-selfpaced.yml index 14c494b3..07a5bca6 100644 --- a/slides/intro-selfpaced.yml +++ b/slides/intro-selfpaced.yml @@ -52,6 +52,7 @@ chapters: - containers/Exercise_Composefile.md - containers/Docker_Machine.md - - containers/Advanced_Dockerfiles.md + - containers/Init_Systems.md - containers/Application_Configuration.md - containers/Logging.md - containers/Resource_Limits.md From e8eb11e257e5c93e7de5e3e6708efd0d1dc1e392 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 6 Dec 2019 14:43:57 -0600 Subject: [PATCH 06/12] Tweak Pods Anatomy slides for inclusion in master --- slides/containers/Pods_Anatomy.md | 47 +++++++++++++++++++++++++++++++ slides/intro-fullday.yml | 2 +- slides/intro-selfpaced.yml | 1 + slides/k8s/Pods_anatomy.md | 27 ------------------ 4 files changed, 49 insertions(+), 28 deletions(-) create mode 100644 slides/containers/Pods_Anatomy.md delete mode 100644 slides/k8s/Pods_anatomy.md diff --git a/slides/containers/Pods_Anatomy.md b/slides/containers/Pods_Anatomy.md new file mode 100644 index 00000000..e5272970 --- /dev/null +++ b/slides/containers/Pods_Anatomy.md @@ -0,0 +1,47 @@ +# Container Super-structure + +- Multiple orchestration platforms support some kind of container super-structure. + + (i.e., a construct or abstraction bigger than a single container.) + +- For instance, on Kubernetes, this super-structure is called a *pod*. + +- A pod is a group of containers (it could be a single container, too). + +- These containers run together, on the same host. + + (A pod cannot straddle multiple hosts.) + +- All the containers in a pod have the same IP address. + +- How does that map to the Docker world? + +--- + +class: pic + +## Anatomy of a Pod + +![Pods](images/kubernetes_pods.svg) + +--- + +## Pods in Docker + +- The containers inside a pod share the same network namespace. + + (Just like when using `docker run --net=container:` with the CLI.) + +- As a result, they can communicate together over `localhost`. + +- In addition to "our" containers, the pod has a special container, the *sandbox*. + +- That container uses a special image: `k8s.gcr.io/pause`. + + (This is visible when listing containers running on a Kubernetes node.) + +- Containers within a pod have independent filesystems. + +- They can share directories by using a mechanism called *volumes.* + + (Which is similar to the concept of volumes in Docker.) diff --git a/slides/intro-fullday.yml b/slides/intro-fullday.yml index 8628bba5..19014fc3 100644 --- a/slides/intro-fullday.yml +++ b/slides/intro-fullday.yml @@ -68,7 +68,7 @@ chapters: #- containers/Containers_From_Scratch.md - - containers/Container_Engines.md - - k8s/Pods_anatomy.md + - containers/Pods_Anatomy.md #- containers/Ecosystem.md - containers/Orchestration_Overview.md - shared/thankyou.md diff --git a/slides/intro-selfpaced.yml b/slides/intro-selfpaced.yml index 14c494b3..26b036ac 100644 --- a/slides/intro-selfpaced.yml +++ b/slides/intro-selfpaced.yml @@ -59,6 +59,7 @@ chapters: - containers/Copy_On_Write.md #- containers/Containers_From_Scratch.md - - containers/Container_Engines.md + - containers/Pods_Anatomy.md - containers/Ecosystem.md - containers/Orchestration_Overview.md - shared/thankyou.md diff --git a/slides/k8s/Pods_anatomy.md b/slides/k8s/Pods_anatomy.md deleted file mode 100644 index 6c4db842..00000000 --- a/slides/k8s/Pods_anatomy.md +++ /dev/null @@ -1,27 +0,0 @@ -# container super-structure (Pods) - -A container super-structure supported by many container engine seems to emerge, -we will see how it maps in the docker worlds - - - ---- -class: pic - -## Pod - -![Pods](images/kubernetes_pods.svg) ---- -# Anatomy of a Pod - -- The containers inside a pod share the network namespace (`--net=container:`) - - => the one of the "pause" containers - -- This means that if the container "pause" is killed all other container are killed - -- This is the reason for this container to do nothing but being alive - -- Containers can contact other container port via `localhost` - -- Containers don't share filesystem except the volumes you want to mount on each of them From 97e68ae18556b1295f3a0c0e334eb7fdeb6b36ca Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 6 Dec 2019 16:25:16 -0600 Subject: [PATCH 07/12] Support : in titles --- slides/markmaker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slides/markmaker.py b/slides/markmaker.py index 37cbf6bc..5d5ed65d 100755 --- a/slides/markmaker.py +++ b/slides/markmaker.py @@ -54,7 +54,7 @@ class: pic name: {anchor} class: title -{title} + {title} .nav[ [Previous section](#{previouslink}) From 6e8ac173e09fbaaff927c750fc14492acfdf282e Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 10 Dec 2019 14:19:56 -0600 Subject: [PATCH 08/12] Add kube adm content to self-paced deck /cc @bretfisher --- slides/kube-selfpaced.yml | 40 +++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/slides/kube-selfpaced.yml b/slides/kube-selfpaced.yml index 3cf05c7f..eb752241 100644 --- a/slides/kube-selfpaced.yml +++ b/slides/kube-selfpaced.yml @@ -31,21 +31,22 @@ chapters: #- shared/hastyconclusions.md - shared/composedown.md - k8s/concepts-k8s.md - - k8s/kubectlget.md - + - k8s/kubectlget.md - k8s/kubectlrun.md - k8s/logs-cli.md - shared/declarative.md - k8s/declarative.md - k8s/deploymentslideshow.md +- - k8s/kubenet.md - k8s/kubectlexpose.md - k8s/shippingimages.md - k8s/buildshiprun-selfhosted.md - k8s/buildshiprun-dockerhub.md - k8s/ourapponkube.md -- - k8s/yamldeploy.md +- - k8s/setup-k8s.md - k8s/dashboard.md #- k8s/kubectlscale.md @@ -53,9 +54,6 @@ chapters: - shared/hastyconclusions.md - k8s/daemonset.md - k8s/dryrun.md - - k8s/kubectlproxy.md - - k8s/localkubeconfig.md - - k8s/accessinternal.md - - k8s/rollout.md - k8s/healthchecks.md @@ -63,35 +61,53 @@ chapters: - k8s/record.md - - k8s/namespaces.md + - k8s/kubectlproxy.md + - k8s/localkubeconfig.md + - k8s/accessinternal.md +- - k8s/ingress.md - k8s/kustomize.md - k8s/helm.md - k8s/create-chart.md + - k8s/create-more-charts.md - - k8s/netpol.md - k8s/authn-authz.md -- + - k8s/podsecuritypolicy.md - k8s/csr-api.md - k8s/openid-connect.md - - k8s/podsecuritypolicy.md + - k8s/control-plane-auth.md - - k8s/volumes.md - k8s/build-with-docker.md - k8s/build-with-kaniko.md +- - k8s/configuration.md -- - - k8s/logs-centralized.md - - k8s/prometheus.md -- - k8s/statefulsets.md - k8s/local-persistent-volumes.md - k8s/portworx.md +- + - k8s/logs-centralized.md + - k8s/prometheus.md + - k8s/resource-limits.md + - k8s/metrics-server.md + - k8s/cluster-sizing.md + - k8s/horizontal-pod-autoscaler.md - - k8s/extending-api.md - k8s/operators.md - k8s/operators-design.md - - k8s/staticpods.md - k8s/owners-and-dependents.md +- + - k8s/dmuc.md + - k8s/multinode.md + - k8s/cni.md + - k8s/apilb.md + - k8s/staticpods.md +- + - k8s/cluster-upgrade.md + - k8s/cluster-backup.md + - k8s/cloud-controller-manager.md - k8s/gitworkflows.md - - k8s/whatsnext.md From 8a2ca450eef2add01da59013eb608d93bd81b0f9 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Tue, 10 Dec 2019 14:21:09 -0600 Subject: [PATCH 09/12] Add extended Helm content --- slides/kube-fullday.yml | 1 + slides/kube-halfday.yml | 1 + slides/kube-twodays.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/slides/kube-fullday.yml b/slides/kube-fullday.yml index 9687dc1e..7f75beeb 100644 --- a/slides/kube-fullday.yml +++ b/slides/kube-fullday.yml @@ -66,6 +66,7 @@ chapters: #- k8s/kustomize.md #- k8s/helm.md #- k8s/create-chart.md + #- k8s/create-more-charts.md #- k8s/netpol.md #- k8s/authn-authz.md #- k8s/csr-api.md diff --git a/slides/kube-halfday.yml b/slides/kube-halfday.yml index 1cbc5337..c49e2470 100644 --- a/slides/kube-halfday.yml +++ b/slides/kube-halfday.yml @@ -61,6 +61,7 @@ chapters: - k8s/namespaces.md - k8s/helm.md - k8s/create-chart.md + #- k8s/create-more-charts.md #- k8s/kustomize.md #- k8s/netpol.md - k8s/whatsnext.md diff --git a/slides/kube-twodays.yml b/slides/kube-twodays.yml index 992c7d68..be76af4b 100644 --- a/slides/kube-twodays.yml +++ b/slides/kube-twodays.yml @@ -67,6 +67,7 @@ chapters: - k8s/kustomize.md - k8s/helm.md - k8s/create-chart.md + #- k8s/create-more-charts.md - - k8s/netpol.md - k8s/authn-authz.md From 68a6546276d2aff67218436aa9e248f2f848e394 Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 20 Dec 2019 11:41:37 -0600 Subject: [PATCH 10/12] Fun with flags Add flags in front of 'coming soon' workshops. --- slides/index.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/slides/index.py b/slides/index.py index 37527699..edd7553e 100755 --- a/slides/index.py +++ b/slides/index.py @@ -1,5 +1,14 @@ #!/usr/bin/env python2 # coding: utf-8 + +FLAGS=dict( + cz=u"🇨🇿", + de=u"🇩🇪", + fr=u"🇫🇷", + uk=u"🇬🇧", + us=u"🇺🇸", +) + TEMPLATE=""" {{ title }} @@ -34,7 +43,7 @@ TEMPLATE=""" {% for item in coming_soon %} - {{ item.title }} + {{ item.flag }} {{ item.title }} {% if item.slides %}{% endif %} {% if item.attend %} {% else %} @@ -160,6 +169,7 @@ for item in items: item["prettydate"] = date_begin.strftime("%B %d{}, %Y").format(suffix) item["begin"] = date_begin item["end"] = date_end + item["flag"] = FLAGS.get(item.get("country"),"") today = datetime.date.today() coming_soon = [i for i in items if i.get("date") and i["end"] >= today] From 1385a1bae212ec89124b98cf96739ca28ac3f68d Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Fri, 20 Dec 2019 11:41:46 -0600 Subject: [PATCH 11/12] Add QCON and Enix High-Five --- slides/index.yaml | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/slides/index.yaml b/slides/index.yaml index 788d3b1f..747c14cd 100644 --- a/slides/index.yaml +++ b/slides/index.yaml @@ -1,3 +1,66 @@ +- date: 2020-03-06 + country: uk + city: London + event: QCON + speaker: jpetazzo + title: Kubernetes Intensive Course + attend: https://qconlondon.com/london2020/workshop/kubernetes-intro + #slides: https://qconuk2019.container.training/ + +- date: 2020-03-05 + country: uk + city: London + event: QCON + speaker: jpetazzo + title: Docker Intensive Course + attend: https://qconlondon.com/london2020/workshop/docker-intensive-course + #slides: https://qconuk2019.container.training/ + +- date: 2020-02-03 + country: fr + city: Paris + event: ENIX SAS + speaker: jpetazzo + title: Fondamentaux Conteneurs et Docker (in French) + lang: fr + attend: https://enix.io/fr/services/formation/ + +- date: 2020-02-04 + country: fr + city: Paris + event: ENIX SAS + speaker: jpetazzo + title: Fondamentaux Orchestration et Kubernetes (in French) + lang: fr + attend: https://enix.io/fr/services/formation/ + +- date: 2020-02-05 + country: fr + city: Paris + event: ENIX SAS + speaker: jpetazzo + title: Kubernetes et Méthodologies DevOps (in French) + lang: fr + attend: https://enix.io/fr/services/formation/ + +- date: 2020-02-06 + country: fr + city: Paris + event: ENIX SAS + speaker: jpetazzo + title: Kubernetes Avancé (in French) + lang: fr + attend: https://enix.io/fr/services/formation/ + +- date: 2020-02-07 + country: fr + city: Paris + event: ENIX SAS + speaker: jpetazzo + title: Opérer Kubernetes (in French) + lang: fr + attend: https://enix.io/fr/services/formation/ + - date: [2019-11-04, 2019-11-05] country: de city: Berlin From 6a814cf039506cec9092afff49c98544a79521cd Mon Sep 17 00:00:00 2001 From: Jerome Petazzoni Date: Sun, 12 Jan 2020 13:28:48 -0600 Subject: [PATCH 12/12] Upgrade slide generator to python3; generate a zip file too --- .gitignore | 1 + slides/Dockerfile | 6 +++--- slides/build.sh | 1 + slides/index.py | 10 +++++----- slides/markmaker.py | 33 +++++++++++++++++++-------------- slides/runtime.txt | 1 + 6 files changed, 30 insertions(+), 22 deletions(-) create mode 100644 slides/runtime.txt diff --git a/.gitignore b/.gitignore index 29ad9ad8..30e28e8c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ slides/*.yml.html slides/autopilot/state.yaml slides/index.html slides/past.html +slides/slides.zip node_modules ### macOS ### diff --git a/slides/Dockerfile b/slides/Dockerfile index 491b015f..d66413ec 100644 --- a/slides/Dockerfile +++ b/slides/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.9 -RUN apk add --no-cache entr py-pip git +FROM alpine:3.11 +RUN apk add --no-cache entr py3-pip git zip COPY requirements.txt . -RUN pip install -r requirements.txt +RUN pip3 install -r requirements.txt diff --git a/slides/build.sh b/slides/build.sh index ca08e19f..9f18a169 100755 --- a/slides/build.sh +++ b/slides/build.sh @@ -14,6 +14,7 @@ once) ./appendcheck.py $YAML.html done fi + zip -qr slides.zip . && echo "Created slides.zip archive." ;; forever) diff --git a/slides/index.py b/slides/index.py index edd7553e..c13b5747 100755 --- a/slides/index.py +++ b/slides/index.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # coding: utf-8 FLAGS=dict( @@ -132,13 +132,13 @@ TEMPLATE=""" -""".decode("utf-8") +""" import datetime import jinja2 import yaml -items = yaml.load(open("index.yaml")) +items = yaml.safe_load(open("index.yaml")) # Items with a date correspond to scheduled sessions. # Items without a date correspond to self-paced content. @@ -187,10 +187,10 @@ with open("index.html", "w") as f: past_workshops=past_workshops, self_paced=self_paced, recorded_workshops=recorded_workshops - ).encode("utf-8")) + )) with open("past.html", "w") as f: f.write(template.render( title="Container Training", all_past_workshops=past_workshops - ).encode("utf-8")) + )) diff --git a/slides/markmaker.py b/slides/markmaker.py index 5d5ed65d..c0eb15b8 100755 --- a/slides/markmaker.py +++ b/slides/markmaker.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # transforms a YAML manifest into a HTML workshop file import glob @@ -20,12 +20,19 @@ def anchor(title): return "toc-" + title -def interstitials_generator(): - images = [url.strip() for url in open("interstitials.txt") if url.strip()] - while True: - for image in images: - yield image -interstitials = interstitials_generator() +class Interstitials(object): + + def __init__(self): + self.index = 0 + self.images = [url.strip() for url in open("interstitials.txt") if url.strip()] + + def next(self): + index = self.index % len(self.images) + index += 1 + return self.images[index] + + +interstitials = Interstitials() def insertslide(markdown, title): @@ -154,8 +161,6 @@ def gentoc(tree, path=()): # Returns: (epxandedmarkdown,[list of titles]) # The list of titles can be nested. def processchapter(chapter, filename): - if isinstance(chapter, unicode): - return processchapter(chapter.encode("utf-8"), filename) if isinstance(chapter, str): if "\n" in chapter: titles = re.findall("^# (.*)", chapter, re.MULTILINE) @@ -179,14 +184,14 @@ try: if "REPOSITORY_URL" in os.environ: repo = os.environ["REPOSITORY_URL"] else: - repo = subprocess.check_output(["git", "config", "remote.origin.url"]) + repo = subprocess.check_output(["git", "config", "remote.origin.url"]).decode("ascii") repo = repo.strip().replace("git@github.com:", "https://github.com/") if "BRANCH" in os.environ: branch = os.environ["BRANCH"] else: - branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]) + branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("ascii") branch = branch.strip() - base = subprocess.check_output(["git", "rev-parse", "--show-prefix"]) + base = subprocess.check_output(["git", "rev-parse", "--show-prefix"]).decode("ascii") base = base.strip().strip("/") urltemplate = ("{repo}/tree/{branch}/{base}/{filename}" .format(repo=repo, branch=branch, base=base, filename="{}")) @@ -194,12 +199,12 @@ except: logging.exception("Could not generate repository URL; generating local URLs instead.") urltemplate = "file://{pwd}/{filename}".format(pwd=os.environ["PWD"], filename="{}") try: - commit = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]) + commit = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).decode("ascii") except: logging.exception("Could not figure out HEAD commit.") commit = "??????" try: - dirtyfiles = subprocess.check_output(["git", "status", "--porcelain"]) + dirtyfiles = subprocess.check_output(["git", "status", "--porcelain"]).decode("ascii") except: logging.exception("Could not figure out repository cleanliness.") dirtyfiles = "?? git status --porcelain failed" diff --git a/slides/runtime.txt b/slides/runtime.txt new file mode 100644 index 00000000..475ba515 --- /dev/null +++ b/slides/runtime.txt @@ -0,0 +1 @@ +3.7