This commit is contained in:
@@ -12,8 +12,9 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
|
||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||
- name: List files in the repository
|
||||
- name: Execute a shell script
|
||||
run: |
|
||||
set -x
|
||||
ls ${{ github.workspace }}
|
||||
df
|
||||
env | sort
|
||||
|
||||
1
shpod
Submodule
1
shpod
Submodule
Submodule shpod added at 61e2aabbd7
@@ -1,18 +0,0 @@
|
||||
name: Gitea Actions Demo
|
||||
run-name: ${{ github.actor }} is testing out Gitea Actions 🚀
|
||||
on: [push]
|
||||
jobs:
|
||||
Explore-Gitea-Actions:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
|
||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
||||
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
|
||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
ls ${{ github.workspace }}
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
@@ -29,29 +29,31 @@ Introduction to Kubernetes<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
M slides/index.yaml
|
||||
M slides/intro-bd-k8s.yml
|
||||
?? k8s/
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/marco/
|
||||
?? slides/secure-containers/
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ff70d3a
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
@@ -80,17 +82,9 @@ Password: **Something**
|
||||
---
|
||||
## Introductions
|
||||
|
||||
<!--
|
||||
⚠️ This slide should be customized by the tutorial instructor(s).
|
||||
-->
|
||||
|
||||
- Hello! I am:
|
||||
|
||||
- 👴 Marco Verleun (marco.verleun@i-share.nl)
|
||||
|
||||
- This training is based on the excellent work of Jérôme Petazzo.
|
||||
|
||||
<!--
|
||||
<!--
|
||||
|
||||
- Hello! We are:
|
||||
|
||||
@@ -124,20 +118,28 @@ Password: **Something**
|
||||
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
||||
- Feel free to interrupt for questions at any time
|
||||
|
||||
- *Especially when you see full screen container pictures!*
|
||||
|
||||
<!--
|
||||
|
||||
- Live feedback, questions, help:
|
||||
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
||||
- You ~~should~~ must ask questions! Lots of questions!
|
||||
|
||||
(especially when you see full screen container pictures)
|
||||
|
||||
- Use to ask questions, get help, etc.
|
||||
|
||||
-->
|
||||
|
||||
<!-- -->
|
||||
|
||||
[@alexbuisine]: https://twitter.com/alexbuisine
|
||||
[EphemeraSearch]: https://ephemerasearch.com/
|
||||
[@jpetazzo]: https://twitter.com/jpetazzo
|
||||
@@ -149,13 +151,17 @@ Password: **Something**
|
||||
|
||||
## Exercises
|
||||
|
||||
- At the end of each topic, there is a series of 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 chapter).
|
||||
(it will help to practice and memorize the content of the day)
|
||||
|
||||
You can also do them later if you have your own machine(s).
|
||||
- We recommend to take at least one hour to work on the exercises
|
||||
|
||||
(if you understood the content of the day, it will be much faster)
|
||||
|
||||
- Each day will start with a quick review of the exercises of the previous day
|
||||
|
||||
.debug[[logistics-v2.md](file:///repo/slides/logistics-v2.md)]
|
||||
---
|
||||
@@ -181,8 +187,7 @@ class: in-person
|
||||
|
||||
- They'll remain up for the duration of the workshop
|
||||
|
||||
- You should have a (virtual) little card with login+password+IP addresses
|
||||
(https://training.verleun.org/ips.html)
|
||||
- You should have a little card with login+password+IP addresses
|
||||
|
||||
- You can automatically SSH from one VM to another
|
||||
|
||||
@@ -507,7 +512,6 @@ class: extra-details
|
||||
- you want only the most essential information
|
||||
|
||||
- You can review these slides another time if you want, they'll be waiting for you ☺
|
||||
|
||||
.debug[[shared/about-slides-v2.md](file:///repo/slides/shared/about-slides-v2.md)]
|
||||
---
|
||||
|
||||
@@ -515,8 +519,6 @@ name: toc-part-1
|
||||
|
||||
## Part 1
|
||||
|
||||
- [Kubernetes concepts](#toc-kubernetes-concepts)
|
||||
|
||||
- [Declarative vs imperative](#toc-declarative-vs-imperative)
|
||||
|
||||
- [Kubernetes network model](#toc-kubernetes-network-model)
|
||||
@@ -592,6 +594,11 @@ Invalid content: None
|
||||
]
|
||||
|
||||
.debug[[shared/composedown.md](file:///repo/slides/shared/composedown.md)]
|
||||
---
|
||||
```
|
||||
Invalid content: k8s/concepts-k8s-v2.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
class: pic
|
||||
@@ -600,509 +607,13 @@ class: pic
|
||||
|
||||
---
|
||||
|
||||
name: toc-kubernetes-concepts
|
||||
class: title
|
||||
|
||||
Kubernetes concepts
|
||||
|
||||
.nav[
|
||||
[Previous part](#toc-)
|
||||
|
|
||||
[Back to table of contents](#toc-part-1)
|
||||
|
|
||||
[Next part](#toc-declarative-vs-imperative)
|
||||
]
|
||||
|
||||
.debug[(automatically generated title slide)]
|
||||
|
||||
---
|
||||
# Kubernetes concepts
|
||||
|
||||
- Kubernetes is a container management system
|
||||
|
||||
- It runs and manages containerized applications on a cluster
|
||||
|
||||
--
|
||||
|
||||
- What does that really mean?
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## What can we do with Kubernetes?
|
||||
|
||||
- Let's imagine that we have a 3-tier e-commerce app:
|
||||
|
||||
- web frontend
|
||||
|
||||
- API backend
|
||||
|
||||
- database (that we will keep out of Kubernetes for now)
|
||||
|
||||
- We have built images for our frontend and backend components
|
||||
|
||||
(e.g. with Dockerfiles and `docker build`)
|
||||
|
||||
- We are running them successfully with a local environment
|
||||
|
||||
(e.g. with Docker Compose)
|
||||
|
||||
- Let's see how we would deploy our app on Kubernetes!
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
|
||||
## Basic things we can ask Kubernetes to do
|
||||
|
||||
--
|
||||
|
||||
- Start 5 containers using image `atseashop/api:v1.3`
|
||||
|
||||
--
|
||||
|
||||
- Place an internal load balancer in front of these containers
|
||||
|
||||
--
|
||||
|
||||
- Start 10 containers using image `atseashop/webfront:v1.3`
|
||||
|
||||
--
|
||||
|
||||
- Place a public load balancer in front of these containers
|
||||
|
||||
--
|
||||
|
||||
- It's Black Friday (or Christmas), traffic spikes, grow our cluster and add containers
|
||||
|
||||
--
|
||||
|
||||
- New release! Replace my containers with the new image `atseashop/webfront:v1.4`
|
||||
|
||||
--
|
||||
|
||||
- Keep processing requests during the upgrade; update my containers one at a time
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Other things that Kubernetes can do for us
|
||||
|
||||
- Autoscaling
|
||||
|
||||
(straightforward on CPU; more complex on other metrics)
|
||||
|
||||
- Resource management and scheduling
|
||||
|
||||
(reserve CPU/RAM for containers; placement constraints)
|
||||
|
||||
- Advanced rollout patterns
|
||||
|
||||
(blue/green deployment, canary deployment)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## More things that Kubernetes can do for us
|
||||
|
||||
- Batch jobs
|
||||
|
||||
(one-off; parallel; also cron-style periodic execution)
|
||||
|
||||
- Fine-grained access control
|
||||
|
||||
(defining *what* can be done by *whom* on *which* resources)
|
||||
|
||||
- Stateful services
|
||||
|
||||
(databases, message queues, etc.)
|
||||
|
||||
- Automating complex tasks with *operators*
|
||||
|
||||
(e.g. database replication, failover, etc.)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Kubernetes architecture
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Kubernetes architecture
|
||||
|
||||
- Ha ha ha ha
|
||||
|
||||
- OK, I was trying to scare you, it's much simpler than that ❤️
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Credits
|
||||
|
||||
- The first schema is a Kubernetes cluster with storage backed by multi-path iSCSI
|
||||
|
||||
(Courtesy of [Yongbok Kim](https://www.yongbok.net/blog/))
|
||||
|
||||
- The second one is a simplified representation of a Kubernetes cluster
|
||||
|
||||
(Courtesy of [Imesh Gunaratne](https://medium.com/containermind/a-reference-architecture-for-deploying-wso2-middleware-on-kubernetes-d4dee7601e8e))
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Kubernetes architecture: the nodes
|
||||
|
||||
- The nodes executing our containers run a collection of services:
|
||||
|
||||
- a container Engine (containerd, cri-o, ...)
|
||||
|
||||
- kubelet (the "node agent")
|
||||
|
||||
- kube-proxy (a necessary but not sufficient network component)
|
||||
|
||||
- Nodes were formerly called "minions"
|
||||
|
||||
(You might see that word in older articles or documentation)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Kubernetes architecture: the control plane
|
||||
|
||||
- The Kubernetes logic (its "brains") is a collection of services:
|
||||
|
||||
- the API server (our point of entry to everything!)
|
||||
|
||||
- core services like the scheduler and controller manager
|
||||
|
||||
- `etcd` (a highly available key/value store; the "database" of Kubernetes)
|
||||
|
||||
- Together, these services form the control plane of our cluster
|
||||
|
||||
- The control plane was also called the "master"
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Running the control plane on special nodes
|
||||
|
||||
- It is common to reserve a dedicated node for the control plane
|
||||
|
||||
(Except for single-node development clusters, like when using minikube)
|
||||
|
||||
- This node used to be called a "master"
|
||||
|
||||
(Yes, this is ambiguous: is the "master" a node, or the whole control plane?)
|
||||
|
||||
- Normal applications are restricted from running on this node
|
||||
|
||||
(By using a mechanism called ["taints"](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/))
|
||||
|
||||
- When high availability is required, each service of the control plane must be resilient
|
||||
|
||||
- The control plane is then replicated on multiple nodes
|
||||
|
||||
(This is sometimes called a "multi-master" setup)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Running the control plane outside containers
|
||||
|
||||
- The services of the control plane can run in or out of containers
|
||||
|
||||
- For instance: since `etcd` is a critical service, some people
|
||||
deploy it directly on a dedicated cluster (without containers)
|
||||
|
||||
(This is illustrated on the first "super complicated" schema)
|
||||
|
||||
- In some hosted Kubernetes offerings (e.g. AKS, GKE, EKS), the control plane is invisible
|
||||
|
||||
(We only "see" a Kubernetes API endpoint)
|
||||
|
||||
- In that case, there is no "master node"
|
||||
|
||||
*For this reason, it is more accurate to say "control plane" rather than "master."*
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## How many nodes should a cluster have?
|
||||
|
||||
- There is no particular constraint
|
||||
|
||||
(no need to have an odd number of nodes for quorum)
|
||||
|
||||
- A cluster can have zero node
|
||||
|
||||
(but then it won't be able to start any pods)
|
||||
|
||||
- For testing and development, having a single node is fine
|
||||
|
||||
- For production, make sure that you have extra capacity
|
||||
|
||||
(so that your workload still fits if you lose a node or a group of nodes)
|
||||
|
||||
- Kubernetes is tested with [up to 5000 nodes](https://kubernetes.io/docs/setup/best-practices/cluster-large/)
|
||||
|
||||
(however, running a cluster of that size requires a lot of tuning)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Do we need to run Docker at all?
|
||||
|
||||
No!
|
||||
|
||||
--
|
||||
|
||||
- The Docker Engine used to be the default option to run containers with Kubernetes
|
||||
|
||||
- Support for Docker (specifically: dockershim) was removed in Kubernetes 1.24
|
||||
|
||||
- We can leverage other pluggable runtimes through the *Container Runtime Interface*
|
||||
|
||||
- <del>We could also use `rkt` ("Rocket") from CoreOS</del> (deprecated)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Some runtimes available through CRI
|
||||
|
||||
- [containerd](https://github.com/containerd/containerd/blob/master/README.md)
|
||||
|
||||
- maintained by Docker, IBM, and community
|
||||
- used by Docker Engine, microk8s, k3s, GKE; also standalone
|
||||
- comes with its own CLI, `ctr`
|
||||
|
||||
- [CRI-O](https://github.com/cri-o/cri-o/blob/master/README.md):
|
||||
|
||||
- maintained by Red Hat, SUSE, and community
|
||||
- used by OpenShift and Kubic
|
||||
- designed specifically as a minimal runtime for Kubernetes
|
||||
|
||||
- [And more](https://kubernetes.io/docs/setup/production-environment/container-runtimes/)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Do we need to run Docker at all?
|
||||
|
||||
Yes!
|
||||
|
||||
--
|
||||
|
||||
- In this workshop, we run our app on a single node first
|
||||
|
||||
- We will need to build images and ship them around
|
||||
|
||||
- We can do these things without Docker
|
||||
<br/>
|
||||
(but with some languages/frameworks, it might be much harder)
|
||||
|
||||
- Docker is still the most stable container engine today
|
||||
<br/>
|
||||
(but other options are maturing very quickly)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Do we need to run Docker at all?
|
||||
|
||||
- On our Kubernetes clusters:
|
||||
|
||||
*Not anymore*
|
||||
|
||||
- On our development environments, CI pipelines ... :
|
||||
|
||||
*Yes, almost certainly*
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Interacting with Kubernetes
|
||||
|
||||
- We will interact with our Kubernetes cluster through the Kubernetes API
|
||||
|
||||
- The Kubernetes API is (mostly) RESTful
|
||||
|
||||
- It allows us to create, read, update, delete *resources*
|
||||
|
||||
- A few common resource types are:
|
||||
|
||||
- node (a machine — physical or virtual — in our cluster)
|
||||
|
||||
- pod (group of containers running together on a node)
|
||||
|
||||
- service (stable network endpoint to connect to one or multiple containers)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||

|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Scaling
|
||||
|
||||
- How would we scale the pod shown on the previous slide?
|
||||
|
||||
- **Do** create additional pods
|
||||
|
||||
- each pod can be on a different node
|
||||
|
||||
- each pod will have its own IP address
|
||||
|
||||
- **Do not** add more NGINX containers in the pod
|
||||
|
||||
- all the NGINX containers would be on the same node
|
||||
|
||||
- they would all have the same IP address
|
||||
<br/>(resulting in `Address alreading in use` errors)
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Together or separate
|
||||
|
||||
- Should we put e.g. a web application server and a cache together?
|
||||
<br/>
|
||||
("cache" being something like e.g. Memcached or Redis)
|
||||
|
||||
- Putting them **in the same pod** means:
|
||||
|
||||
- they have to be scaled together
|
||||
|
||||
- they can communicate very efficiently over `localhost`
|
||||
|
||||
- Putting them **in different pods** means:
|
||||
|
||||
- they can be scaled separately
|
||||
|
||||
- they must communicate over remote IP addresses
|
||||
<br/>(incurring more latency, lower performance)
|
||||
|
||||
- Both scenarios can make sense, depending on our goals
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
## Credits
|
||||
|
||||
- The first diagram is courtesy of Lucas Käldström, in [this presentation](https://speakerdeck.com/luxas/kubeadm-cluster-creation-internals-from-self-hosting-to-upgradability-and-ha)
|
||||
|
||||
- it's one of the best Kubernetes architecture diagrams available!
|
||||
|
||||
- The second diagram is courtesy of Weave Works
|
||||
|
||||
- a *pod* can have multiple containers working together
|
||||
|
||||
- IP addresses are associated with *pods*, not with individual containers
|
||||
|
||||
Both diagrams used with permission.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Kubernetes concepts
|
||||
:FR:- Kubernetes en théorie
|
||||
|
||||
.debug[[k8s/concepts-k8s-v2.md](file:///repo/slides/k8s/concepts-k8s-v2.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
name: toc-declarative-vs-imperative
|
||||
class: title
|
||||
|
||||
Declarative vs imperative
|
||||
|
||||
.nav[
|
||||
[Previous part](#toc-kubernetes-concepts)
|
||||
[Previous part](#toc-)
|
||||
|
|
||||
[Back to table of contents](#toc-part-1)
|
||||
|
|
||||
@@ -1220,7 +731,7 @@ specifying how to brew tea?]
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -1439,7 +950,7 @@ class: extra-details
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -2077,7 +1588,7 @@ $ curl -k https://10.96.0.1
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -2340,7 +1851,7 @@ class: title
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -2504,7 +2015,7 @@ class: title
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -3065,7 +2576,7 @@ class: extra-details
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -3323,7 +2834,7 @@ Note: this is a fiction! We have enough entropy. But we need a pretext to scale
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -3642,7 +3153,7 @@ The master node has [taints](https://kubernetes.io/docs/concepts/configuration/t
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -4198,7 +3709,7 @@ class: extra-details
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -4697,7 +4208,7 @@ class: extra-details
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -4893,7 +4404,7 @@ Exactly what we need!
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -5309,7 +4820,7 @@ Note: we could have used `--namespace=default` for the same result.
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -5629,7 +5140,7 @@ Sorry Star Trek fans, this is not the federation you're looking for!
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ title: |
|
||||
slides: https://training.verleun.org/
|
||||
|
||||
#slidenumberprefix: "#SomeHashTag — "
|
||||
slidenumberprefix: "📜 "
|
||||
|
||||
exclude:
|
||||
- self-paced
|
||||
@@ -19,114 +20,5 @@ content:
|
||||
- shared/toc.md
|
||||
|
||||
- secure-containers/sampleapp.md
|
||||
- shared/about-slides-v2.md
|
||||
|
||||
# - containers/Docker_Overview.md
|
||||
# #- containers/Docker_History.md
|
||||
# #- containers/Training_Environment.md
|
||||
# #- containers/Installing_Docker.md
|
||||
# - containers/First_Containers.md
|
||||
# - containers/Background_Containers.md
|
||||
# #- containers/Start_And_Attach.md
|
||||
# #- containers/Naming_And_Inspecting.md
|
||||
# #- containers/Labels.md
|
||||
# - containers/Getting_Inside-v2.md
|
||||
# - containers/Initial_Images.md
|
||||
# -
|
||||
# - containers/Building_Images_Interactively.md
|
||||
# - containers/Building_Images_With_Dockerfiles.md
|
||||
# - containers/Cmd_And_Entrypoint.md
|
||||
# - containers/Copying_Files_During_Build.md
|
||||
# #- containers/Exercise_Dockerfile_Basic.md
|
||||
# - custom/Exercise_Dockerfile.md
|
||||
# # -
|
||||
# - containers/Container_Networking_Basics.md
|
||||
# #- containers/Network_Drivers.md
|
||||
# - containers/Local_Development_Workflow.md
|
||||
# #- containers/Container_Network_Model.md
|
||||
# - containers/Compose_For_Dev_Stacks.md
|
||||
# #- containers/Exercise_Composefile.md
|
||||
# -
|
||||
# #- containers/Multi_Stage_Builds.md
|
||||
# #- containers/Publishing_To_Docker_Hub.md
|
||||
# #- containers/Dockerfile_Tips.md
|
||||
# #- containers/Exercise_Dockerfile_Advanced.md
|
||||
# #- containers/Docker_Machine.md
|
||||
# #- containers/Advanced_Dockerfiles.md
|
||||
# #- containers/Buildkit.md
|
||||
# #- containers/Init_Systems.md
|
||||
# #- containers/Application_Configuration.md
|
||||
# #- containers/Logging.md
|
||||
# #- containers/Namespaces_Cgroups.md
|
||||
# #- 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
|
||||
# - shared/sampleapp.md
|
||||
# - containers/links.md
|
||||
-
|
||||
#- shared/webssh.md
|
||||
#- k8s/versions-k8s.md
|
||||
|
||||
# Bridget doesn't go into as much depth with compose
|
||||
#- shared/composescale.md
|
||||
#- shared/hastyconclusions.md
|
||||
# - shared/composedown.md
|
||||
# - k8s/concepts-k8s-v2.md
|
||||
# - shared/declarative.md
|
||||
# - k8s/declarative.md
|
||||
# - k8s/kubenet.md
|
||||
# - k8s/kubectlget.md
|
||||
# - k8s/setup-overview.md
|
||||
#- k8s/setup-devel.md
|
||||
#- k8s/setup-managed.md
|
||||
# - k8s/setup-selfhosted.md
|
||||
# - - k8s/kubectl-run.md
|
||||
#- k8s/batch-jobs.md
|
||||
#- k8s/labels-annotations.md
|
||||
# - k8s/kubectl-logs.md
|
||||
# - k8s/deploymentslideshow.md
|
||||
# - k8s/kubectlexpose.md
|
||||
# - k8s/shippingimages.md
|
||||
#- k8s/buildshiprun-selfhosted.md
|
||||
# - k8s/buildshiprun-dockerhub.md
|
||||
# - k8s/ourapponkube.md
|
||||
#- k8s/localkubeconfig.md
|
||||
#- k8s/access-eks-cluster.md
|
||||
#- k8s/accessinternal.md
|
||||
#- k8s/kubectlproxy.md
|
||||
- #- k8s/dashboard.md
|
||||
#- k8s/k9s.md
|
||||
#- k8s/tilt.md
|
||||
#- k8s/kubectlscale.md
|
||||
# - k8s/scalingdockercoins.md
|
||||
# - shared/hastyconclusions.md
|
||||
# - k8s/daemonset.md
|
||||
# - k8s/rollout.md
|
||||
#- k8s/record.md
|
||||
# - - k8s/logs-cli.md
|
||||
# Bridget hasn't added EFK yet
|
||||
#- k8s/logs-centralized.md
|
||||
# - k8s/namespaces.md
|
||||
# - k8s/helm-intro.md
|
||||
# - k8s/helm-chart-format.md
|
||||
# - k8s/helm-create-basic-chart.md
|
||||
# - k8s/helm-create-better-chart.md
|
||||
# - k8s/helm-dependencies.md
|
||||
# - k8s/helm-values-schema-validation.md
|
||||
# - k8s/helm-secrets.md
|
||||
# - k8s/kustomize.md
|
||||
# #- k8s/ytt.md
|
||||
# #- k8s/netpol.md
|
||||
# # - k8s/whatsnext.md
|
||||
# # - k8s/links.md
|
||||
# - k8s/pod-security-admission.md
|
||||
# - k8s/operators.md
|
||||
# - k8s/operators-design.md
|
||||
# - k8s/operators-example.md
|
||||
# Bridget-specific
|
||||
# - k8s/links-bridget.md
|
||||
# - shared/thankyou.md
|
||||
- secure-containers/possible-improvements.md
|
||||
- secure-containers/cve.md
|
||||
|
||||
@@ -29,31 +29,31 @@ Introduction Container Security<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
@@ -80,44 +80,451 @@ Password: **Something**
|
||||
|
||||
.debug[[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
---
|
||||
```
|
||||
Invalid content: marco/intro.md
|
||||
```
|
||||
## Introductions
|
||||
|
||||
<!--
|
||||
⚠️ This slide should be customized by the tutorial instructor(s).
|
||||
-->
|
||||
|
||||
- Hello! I am:
|
||||
|
||||
- 👴 Marco Verleun (marco.verleun@i-share.nl)
|
||||
|
||||
- 🏢 Employed by i-share (www.i-share.nl)
|
||||
|
||||
- 👷🏼♂️ Devops/Gitops/Cloud/Container/Cluster/Linux engineer (Pick one)
|
||||
|
||||
- 🎯 Secure clusters (air-gapped) running secure containers
|
||||
|
||||
--
|
||||
|
||||
- This presentation is partially based on the excellent work of Jérôme Petazzo.
|
||||
|
||||
- Feel free to interrupt for questions at any time
|
||||
|
||||
.debug[[marco/intro.md](file:///repo/slides/marco/intro.md)]
|
||||
---
|
||||
|
||||
## Exercises
|
||||
|
||||
- Due to time constraints there are no exercises....
|
||||
|
||||
.debug[[marco/intro.md](file:///repo/slides/marco/intro.md)]
|
||||
---
|
||||
|
||||
name: toc-part-1
|
||||
|
||||
## Part 1
|
||||
|
||||
- [Which application needs to be secured](#toc-which-application-needs-to-be-secured)
|
||||
|
||||
|
||||
.debug[(auto-generated TOC)]
|
||||
---
|
||||
name: toc-part-2
|
||||
|
||||
## Part 2
|
||||
|
||||
- [Possible improvements](#toc-possible-improvements)
|
||||
|
||||
|
||||
.debug[(auto-generated TOC)]
|
||||
---
|
||||
name: toc-part-3
|
||||
|
||||
## Part 3
|
||||
|
||||
- [Other improvements](#toc-other--improvements)
|
||||
|
||||
|
||||
.debug[(auto-generated TOC)]
|
||||
|
||||
|
||||
|
||||
.debug[[shared/toc.md](file:///repo/slides/shared/toc.md)]
|
||||
---
|
||||
```
|
||||
Invalid content: secure-containers/sampleapp.md
|
||||
```
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
```
|
||||
Invalid content: shared/about-slides-v2.md
|
||||
```
|
||||
|
||||
name: toc-which-application-needs-to-be-secured
|
||||
class: title
|
||||
|
||||
Which application needs to be secured
|
||||
|
||||
.nav[
|
||||
[Previous part](#toc-)
|
||||
|
|
||||
[Back to table of contents](#toc-part-1)
|
||||
|
|
||||
[Next part](#toc-possible-improvements)
|
||||
]
|
||||
|
||||
.debug[(automatically generated title slide)]
|
||||
|
||||
---
|
||||
```
|
||||
Invalid content: None
|
||||
# Which application needs to be secured
|
||||
|
||||
- It is a DockerCoin miner! 💰🐳📦🚢
|
||||
|
||||
--
|
||||
|
||||
- No, you can't buy coffee with DockerCoin
|
||||
|
||||
--
|
||||
|
||||
- How dockercoins works:
|
||||
|
||||
- generate a few random bytes
|
||||
|
||||
- hash these bytes
|
||||
|
||||
- increment a counter (to keep track of speed)
|
||||
|
||||
- repeat forever!
|
||||
|
||||
--
|
||||
|
||||
- DockerCoin is *not* a cryptocurrency
|
||||
|
||||
(the only common points are "randomness," "hashing," and "coins" in the name)
|
||||
|
||||
.debug[[secure-containers/sampleapp.md](file:///repo/slides/secure-containers/sampleapp.md)]
|
||||
---
|
||||
|
||||
## DockerCoin in the microservices era
|
||||
|
||||
- The dockercoins app is made of 5 services:
|
||||
|
||||
- `rng` = web service generating random bytes
|
||||
|
||||
- `hasher` = web service computing hash of POSTed data
|
||||
|
||||
- `worker` = background process calling `rng` and `hasher`
|
||||
|
||||
- `webui` = web interface to watch progress
|
||||
|
||||
- `redis` = data store (holds a counter updated by `worker`)
|
||||
|
||||
- These 5 services are visible in the application's Compose file,
|
||||
[docker-compose.yml](
|
||||
https://github.com/jpetazzo/container.training/blob/main/dockercoins/docker-compose.yml)
|
||||
|
||||
.debug[[secure-containers/sampleapp.md](file:///repo/slides/secure-containers/sampleapp.md)]
|
||||
---
|
||||
|
||||
## How dockercoins works
|
||||
|
||||
- `worker` invokes web service `rng` to generate random bytes
|
||||
|
||||
- `worker` invokes web service `hasher` to hash these bytes
|
||||
|
||||
- `worker` does this in an infinite loop
|
||||
|
||||
- every second, `worker` updates `redis` to indicate how many loops were done
|
||||
|
||||
- `webui` queries `redis`, and computes and exposes "hashing speed" in our browser
|
||||
|
||||
*(See diagram on next slide!)*
|
||||
|
||||
.debug[[secure-containers/sampleapp.md](file:///repo/slides/secure-containers/sampleapp.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||

|
||||
|
||||
.debug[[secure-containers/sampleapp.md](file:///repo/slides/secure-containers/sampleapp.md)]
|
||||
---
|
||||
|
||||
## How to improve the `docker-compose.yml` file
|
||||
|
||||
Let's pretend we do not want to modify the original `docker-compose.yml` file
|
||||
|
||||
--
|
||||
|
||||
- Changes here might cause issues with upstream updates.
|
||||
|
||||
- Hard to keep track of differences with merge conflicts
|
||||
|
||||
--
|
||||
|
||||
Let's override values with `docker-compose.override.yml`
|
||||
|
||||
```bash
|
||||
❯ docker-compose ls
|
||||
NAME STATUS CONFIG FILES
|
||||
dockercoins running(5) docker-compose.yml,docker-compose.override.yml
|
||||
```
|
||||
|
||||
.debug[[secure-containers/sampleapp.md](file:///repo/slides/secure-containers/sampleapp.md)]
|
||||
---
|
||||
|
||||
## Two files are merged together
|
||||
|
||||
`docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
rng:
|
||||
build: rng
|
||||
ports:
|
||||
- "8001:80"
|
||||
```
|
||||
Invalid content: None
|
||||
|
||||
`docker-compose.override.yml`
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
```
|
||||
</textarea>
|
||||
|
||||
|
||||
.debug[[secure-containers/sampleapp.md](file:///repo/slides/secure-containers/sampleapp.md)]
|
||||
---
|
||||
|
||||
|
||||
.debug[[secure-containers/sampleapp.md](file:///repo/slides/secure-containers/sampleapp.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
name: toc-possible-improvements
|
||||
class: title
|
||||
|
||||
Possible improvements
|
||||
|
||||
.nav[
|
||||
[Previous part](#toc-which-application-needs-to-be-secured)
|
||||
|
|
||||
[Back to table of contents](#toc-part-2)
|
||||
|
|
||||
[Next part](#toc-other--improvements)
|
||||
]
|
||||
|
||||
.debug[(automatically generated title slide)]
|
||||
|
||||
---
|
||||
# Possible improvements
|
||||
|
||||
The app is running ~~fine~~ (It does what it is supposed to do at least)
|
||||
|
||||
--
|
||||
|
||||
Some improvement areas:
|
||||
|
||||
- All containers are running with root privileges
|
||||
|
||||
- Too many privileges (`man 7 capabilities`)
|
||||
|
||||
- Root filesystem is writeable
|
||||
|
||||
--
|
||||
|
||||
- Quite a few CVE's (As a result of the build)
|
||||
|
||||
.debug[[secure-containers/possible-improvements.md](file:///repo/slides/secure-containers/possible-improvements.md)]
|
||||
---
|
||||
|
||||
## Starting scenario
|
||||
|
||||
- Default without `docker-compose.override.yml`
|
||||
|
||||
- Containers run with `root` identity
|
||||
|
||||
- `/tmp` is writeable
|
||||
|
||||
- 'chown' is possible
|
||||
|
||||
.debug[[secure-containers/possible-improvements.md](file:///repo/slides/secure-containers/possible-improvements.md)]
|
||||
---
|
||||
|
||||
## Improvement 1
|
||||
|
||||
Change user id to 4242. Redis can no longer write to `/data` so we mount a writeable directory on top of it
|
||||
|
||||
```yaml
|
||||
services:
|
||||
...
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
...
|
||||
redis:
|
||||
user: "4242:4242"
|
||||
tmpfs:
|
||||
- /data
|
||||
...
|
||||
```
|
||||
|
||||
.debug[[secure-containers/possible-improvements.md](file:///repo/slides/secure-containers/possible-improvements.md)]
|
||||
---
|
||||
|
||||
## Improvement 2
|
||||
|
||||
Lets reduce capabilities to make sure no weird things can happen
|
||||
|
||||
```yaml
|
||||
...
|
||||
services:
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
cap_drop:
|
||||
- ALL
|
||||
|
||||
hasher:
|
||||
user: "4242:4242"
|
||||
cap_drop:
|
||||
- ALL
|
||||
...
|
||||
```
|
||||
|
||||
It does not show anything different...
|
||||
|
||||
.debug[[secure-containers/possible-improvements.md](file:///repo/slides/secure-containers/possible-improvements.md)]
|
||||
---
|
||||
|
||||
## Improvement 3
|
||||
|
||||
Make the root filesystem read only
|
||||
|
||||
```yaml
|
||||
...
|
||||
services:
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
cap_drop:
|
||||
- ALL
|
||||
read_only: true
|
||||
```
|
||||
|
||||
.debug[[secure-containers/possible-improvements.md](file:///repo/slides/secure-containers/possible-improvements.md)]
|
||||
---
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
name: toc-other--improvements
|
||||
class: title
|
||||
|
||||
Other improvements
|
||||
|
||||
.nav[
|
||||
[Previous part](#toc-possible-improvements)
|
||||
|
|
||||
[Back to table of contents](#toc-part-3)
|
||||
|
|
||||
[Next part](#toc-)
|
||||
]
|
||||
|
||||
.debug[(automatically generated title slide)]
|
||||
|
||||
---
|
||||
# Other improvements
|
||||
|
||||
What about security of the code / packages?
|
||||
|
||||
Choosing the proper build image might make a big difference:
|
||||
|
||||
Look at the following two `Dockerfiles`:
|
||||
|
||||
```bash
|
||||
FROM python:latest
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
COPY worker.py /
|
||||
CMD ["python", "worker.py"]
|
||||
```
|
||||
|
||||
```bash
|
||||
FROM python:alpine
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
COPY worker.py /
|
||||
CMD ["python", "worker.py"]
|
||||
```
|
||||
|
||||
.debug[[secure-containers/cve.md](file:///repo/slides/secure-containers/cve.md)]
|
||||
---
|
||||
|
||||
The only difference is the base image. But the end result is quite different:
|
||||
|
||||
(Scanning is done with `grype`)
|
||||
|
||||
| Base image | Image size | CVE's |
|
||||
|---|---|---|
|
||||
| python:latest | 888 Mb | 1114 |
|
||||
| python:alpine | 73,5 Mb | 3 |
|
||||
|
||||
--
|
||||
|
||||
The 'full' python image has even `gcc` included....
|
||||
|
||||
```bash
|
||||
docker run --rm --entrypoint gcc -it python-latest:latest
|
||||
gcc: fatal error: no input files
|
||||
compilation terminated.
|
||||
|
||||
docker run --rm --entrypoint gcc python-alpine:latest
|
||||
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "gcc": executable file not found in $PATH: unknown.
|
||||
```
|
||||
|
||||
.debug[[secure-containers/cve.md](file:///repo/slides/secure-containers/cve.md)]
|
||||
---
|
||||
|
||||
Consider a `multistage build`
|
||||
|
||||
```bash
|
||||
FROM python:latest as builder
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
# Do many other heavy things here
|
||||
COPY worker.py /
|
||||
CMD ["python", "worker.py"]
|
||||
|
||||
|
||||
FROM python:alpine as runner
|
||||
# Copy file from previous build container
|
||||
COPY --from=builder /worker.py .
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
# Change UID here
|
||||
USER 1234
|
||||
CMD ["python", "worker.py"]
|
||||
```
|
||||
|
||||
.debug[[secure-containers/cve.md](file:///repo/slides/secure-containers/cve.md)]
|
||||
---
|
||||
|
||||
Result:
|
||||
|
||||
| Base image | Image size | CVE's |
|
||||
|---|---|---|
|
||||
| python:latest | 888 Mb | 1114 |
|
||||
| python:alpine | 73,5 Mb | 3 |
|
||||
| python:mulistage | 73,5 Mb | 3 |
|
||||
.debug[[secure-containers/cve.md](file:///repo/slides/secure-containers/cve.md)]</textarea>
|
||||
<script src="remark.min.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var slideshow = remark.create({
|
||||
ratio: '16:9',
|
||||
highlightSpans: true,
|
||||
slideNumberFormat: '%current%/%total%',
|
||||
slideNumberFormat: '📜 %current%/%total%',
|
||||
excludedClasses: ["self-paced"]
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -29,31 +29,31 @@ Kubernetes<br/>for Admins and Ops<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
|
||||
@@ -29,31 +29,31 @@ Kubernetes<br/>for administrators<br/>and operators<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
|
||||
@@ -29,31 +29,31 @@ Deploying and Scaling Microservices<br/>with Kubernetes<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
|
||||
@@ -29,31 +29,31 @@ Kubernetes 101<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
@@ -7976,7 +7976,7 @@ The `readme` may or may not have (accurate) explanations for the values.
|
||||
|
||||
- Update `my-juice-shop`:
|
||||
```bash
|
||||
helm upgrade my-juice-shop juice/my-juice-shop \
|
||||
helm upgrade my-juice-shop juice/juice-shop \
|
||||
--set service.type=NodePort
|
||||
```
|
||||
|
||||
|
||||
@@ -29,31 +29,31 @@ Deploying and Scaling Microservices<br/>with Docker and Kubernetes<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
@@ -15001,7 +15001,7 @@ The `readme` may or may not have (accurate) explanations for the values.
|
||||
|
||||
- Update `my-juice-shop`:
|
||||
```bash
|
||||
helm upgrade my-juice-shop juice/my-juice-shop \
|
||||
helm upgrade my-juice-shop juice/juice-shop \
|
||||
--set service.type=NodePort
|
||||
```
|
||||
|
||||
|
||||
@@ -29,31 +29,31 @@ Deploying and Scaling Microservices<br/>with Kubernetes<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
@@ -11887,7 +11887,7 @@ The `readme` may or may not have (accurate) explanations for the values.
|
||||
|
||||
- Update `my-juice-shop`:
|
||||
```bash
|
||||
helm upgrade my-juice-shop juice/my-juice-shop \
|
||||
helm upgrade my-juice-shop juice/juice-shop \
|
||||
--set service.type=NodePort
|
||||
```
|
||||
|
||||
|
||||
80
slides/secure-containers/cve.md
Normal file
80
slides/secure-containers/cve.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Other improvements
|
||||
|
||||
What about security of the code / packages?
|
||||
|
||||
Choosing the proper build image might make a big difference:
|
||||
|
||||
Look at the following two `Dockerfiles`:
|
||||
|
||||
```bash
|
||||
FROM python:latest
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
COPY worker.py /
|
||||
CMD ["python", "worker.py"]
|
||||
```
|
||||
|
||||
```bash
|
||||
FROM python:alpine
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
COPY worker.py /
|
||||
CMD ["python", "worker.py"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
The only difference is the base image. But the end result is quite different:
|
||||
|
||||
(Scanning is done with `grype`)
|
||||
|
||||
| Base image | Image size | CVE's |
|
||||
|---|---|---|
|
||||
| python:latest | 888 Mb | 1114 |
|
||||
| python:alpine | 73,5 Mb | 3 |
|
||||
|
||||
--
|
||||
|
||||
The 'full' python image has even `gcc` included....
|
||||
|
||||
```bash
|
||||
docker run --rm --entrypoint gcc -it python-latest:latest
|
||||
gcc: fatal error: no input files
|
||||
compilation terminated.
|
||||
|
||||
docker run --rm --entrypoint gcc python-alpine:latest
|
||||
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "gcc": executable file not found in $PATH: unknown.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Consider a `multistage build`
|
||||
|
||||
```bash
|
||||
FROM python:latest as builder
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
# Do many other heavy things here
|
||||
COPY worker.py /
|
||||
CMD ["python", "worker.py"]
|
||||
|
||||
|
||||
FROM python:alpine as runner
|
||||
# Copy file from previous build container
|
||||
COPY --from=builder /worker.py .
|
||||
RUN pip install redis
|
||||
RUN pip install requests
|
||||
# Change UID here
|
||||
USER 1234
|
||||
CMD ["python", "worker.py"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Result:
|
||||
|
||||
| Base image | Image size | CVE's |
|
||||
|---|---|---|
|
||||
| python:latest | 888 Mb | 1114 |
|
||||
| python:alpine | 73,5 Mb | 3 |
|
||||
| python:mulistage | 73,5 Mb | 3 |
|
||||
87
slides/secure-containers/possible-improvements.md
Normal file
87
slides/secure-containers/possible-improvements.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Possible improvements
|
||||
|
||||
The app is running ~~fine~~ (It does what it is supposed to do at least)
|
||||
|
||||
--
|
||||
|
||||
Some improvement areas:
|
||||
|
||||
- All containers are running with root privileges
|
||||
|
||||
- Too many privileges (`man 7 capabilities`)
|
||||
|
||||
- Root filesystem is writeable
|
||||
|
||||
--
|
||||
|
||||
- Quite a few CVE's (As a result of the build)
|
||||
|
||||
---
|
||||
|
||||
## Starting scenario
|
||||
|
||||
- Default without `docker-compose.override.yml`
|
||||
|
||||
- Containers run with `root` identity
|
||||
|
||||
- `/tmp` is writeable
|
||||
|
||||
- 'chown' is possible
|
||||
|
||||
---
|
||||
|
||||
## Improvement 1
|
||||
|
||||
Change user id to 4242. Redis can no longer write to `/data` so we mount a writeable directory on top of it
|
||||
|
||||
```yaml
|
||||
services:
|
||||
...
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
...
|
||||
redis:
|
||||
user: "4242:4242"
|
||||
tmpfs:
|
||||
- /data
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Improvement 2
|
||||
|
||||
Lets reduce capabilities to make sure no weird things can happen
|
||||
|
||||
```yaml
|
||||
...
|
||||
services:
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
cap_drop:
|
||||
- ALL
|
||||
|
||||
hasher:
|
||||
user: "4242:4242"
|
||||
cap_drop:
|
||||
- ALL
|
||||
...
|
||||
```
|
||||
|
||||
It does not show anything different...
|
||||
|
||||
---
|
||||
|
||||
## Improvement 3
|
||||
|
||||
Make the root filesystem read only
|
||||
|
||||
```yaml
|
||||
...
|
||||
services:
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
cap_drop:
|
||||
- ALL
|
||||
read_only: true
|
||||
```
|
||||
@@ -68,7 +68,7 @@ class: pic
|
||||
|
||||
---
|
||||
|
||||
## How do improve the `docker-compose.yml` file
|
||||
## How to improve the `docker-compose.yml` file
|
||||
|
||||
Let's pretend we do not want to modify the original `docker-compose.yml` file
|
||||
|
||||
@@ -82,217 +82,38 @@ Let's pretend we do not want to modify the original `docker-compose.yml` file
|
||||
|
||||
Let's override values with `docker-compose.override.yml`
|
||||
|
||||
---
|
||||
|
||||
## Example in `worker/worker.py`
|
||||
|
||||
```python
|
||||
redis = Redis("`redis`")
|
||||
|
||||
|
||||
def get_random_bytes():
|
||||
r = requests.get("http://`rng`/32")
|
||||
return r.content
|
||||
|
||||
|
||||
def hash_bytes(data):
|
||||
r = requests.post("http://`hasher`/",
|
||||
data=data,
|
||||
headers={"Content-Type": "application/octet-stream"})
|
||||
```bash
|
||||
❯ docker-compose ls
|
||||
NAME STATUS CONFIG FILES
|
||||
dockercoins running(5) docker-compose.yml,docker-compose.override.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Two files are merged together
|
||||
|
||||
`docker-compose.yml`
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
rng:
|
||||
build: rng
|
||||
ports:
|
||||
- "8001:80"
|
||||
```
|
||||
|
||||
`docker-compose.override.yml`
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
rng:
|
||||
user: "4242:4242"
|
||||
```
|
||||
|
||||
(Full source code available [here](
|
||||
https://@@GITREPO@@/blob/8279a3bce9398f7c1a53bdd95187c53eda4e6435/dockercoins/worker/worker.py#L17
|
||||
))
|
||||
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Links, naming, and service discovery
|
||||
|
||||
- Containers can have network aliases (resolvable through DNS)
|
||||
|
||||
- Compose file version 2+ makes each container reachable through its service name
|
||||
|
||||
- Compose file version 1 required "links" sections to accomplish this
|
||||
|
||||
- Network aliases are automatically namespaced
|
||||
|
||||
- you can have multiple apps declaring and using a service named `database`
|
||||
|
||||
- containers in the blue app will resolve `database` to the IP of the blue database
|
||||
|
||||
- containers in the green app will resolve `database` to the IP of the green database
|
||||
|
||||
---
|
||||
|
||||
## Show me the code!
|
||||
|
||||
- You can check the GitHub repository with all the materials of this workshop:
|
||||
<br/>https://@@GITREPO@@
|
||||
|
||||
- The application is in the [dockercoins](
|
||||
https://@@GITREPO@@/tree/master/dockercoins)
|
||||
subdirectory
|
||||
|
||||
- The Compose file ([docker-compose.yml](
|
||||
https://@@GITREPO@@/blob/master/dockercoins/docker-compose.yml))
|
||||
lists all 5 services
|
||||
|
||||
- `redis` is using an official image from the Docker Hub
|
||||
|
||||
- `hasher`, `rng`, `worker`, `webui` are each built from a Dockerfile
|
||||
|
||||
- Each service's Dockerfile and source code is in its own directory
|
||||
|
||||
(`hasher` is in the [hasher](https://@@GITREPO@@/blob/master/dockercoins/hasher/) directory,
|
||||
`rng` is in the [rng](https://@@GITREPO@@/blob/master/dockercoins/rng/)
|
||||
directory, etc.)
|
||||
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Compose file format version
|
||||
|
||||
*This is relevant only if you have used Compose before 2016...*
|
||||
|
||||
- Compose 1.6 introduced support for a new Compose file format (aka "v2")
|
||||
|
||||
- Services are no longer at the top level, but under a `services` section
|
||||
|
||||
- There has to be a `version` key at the top level, with value `"2"` (as a string, not an integer)
|
||||
|
||||
- Containers are placed on a dedicated network, making links unnecessary
|
||||
|
||||
- There are other minor differences, but upgrade is easy and straightforward
|
||||
|
||||
---
|
||||
|
||||
## Our application at work
|
||||
|
||||
- On the left-hand side, the "rainbow strip" shows the container names
|
||||
|
||||
- On the right-hand side, we see the output of our containers
|
||||
|
||||
- We can see the `worker` service making requests to `rng` and `hasher`
|
||||
|
||||
- For `rng` and `hasher`, we see HTTP access logs
|
||||
|
||||
---
|
||||
|
||||
## Connecting to the web UI
|
||||
|
||||
- "Logs are exciting and fun!" (No-one, ever)
|
||||
|
||||
- The `webui` container exposes a web dashboard; let's view it
|
||||
|
||||
.lab[
|
||||
|
||||
- With a web browser, connect to `node1` on port 8000
|
||||
|
||||
- Remember: the `nodeX` aliases are valid only on the nodes themselves
|
||||
|
||||
- In your browser, you need to enter the IP address of your node
|
||||
|
||||
<!-- ```open http://node1:8000``` -->
|
||||
|
||||
]
|
||||
|
||||
A drawing area should show up, and after a few seconds, a blue
|
||||
graph will appear.
|
||||
|
||||
---
|
||||
|
||||
class: self-paced, extra-details
|
||||
|
||||
## If the graph doesn't load
|
||||
|
||||
If you just see a `Page not found` error, it might be because your
|
||||
Docker Engine is running on a different machine. This can be the case if:
|
||||
|
||||
- you are using the Docker Toolbox
|
||||
|
||||
- you are using a VM (local or remote) created with Docker Machine
|
||||
|
||||
- you are controlling a remote Docker Engine
|
||||
|
||||
When you run DockerCoins in development mode, the web UI static files
|
||||
are mapped to the container using a volume. Alas, volumes can only
|
||||
work on a local environment, or when using Docker Desktop for Mac or Windows.
|
||||
|
||||
How to fix this?
|
||||
|
||||
Stop the app with `^C`, edit `dockercoins.yml`, comment out the `volumes` section, and try again.
|
||||
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Why does the speed seem irregular?
|
||||
|
||||
- It *looks like* the speed is approximately 4 hashes/second
|
||||
|
||||
- Or more precisely: 4 hashes/second, with regular dips down to zero
|
||||
|
||||
- Why?
|
||||
|
||||
--
|
||||
|
||||
class: extra-details
|
||||
|
||||
- The app actually has a constant, steady speed: 3.33 hashes/second
|
||||
<br/>
|
||||
(which corresponds to 1 hash every 0.3 seconds, for *reasons*)
|
||||
|
||||
- Yes, and?
|
||||
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## The reason why this graph is *not awesome*
|
||||
|
||||
- The worker doesn't update the counter after every loop, but up to once per second
|
||||
|
||||
- The speed is computed by the browser, checking the counter about once per second
|
||||
|
||||
- Between two consecutive updates, the counter will increase either by 4, or by 0
|
||||
|
||||
- The perceived speed will therefore be 4 - 4 - 4 - 0 - 4 - 4 - 0 etc.
|
||||
|
||||
- What can we conclude from this?
|
||||
|
||||
--
|
||||
|
||||
class: extra-details
|
||||
|
||||
- "I'm clearly incapable of writing good frontend code!" 😀 — Jérôme
|
||||
|
||||
---
|
||||
|
||||
## Stopping the application
|
||||
|
||||
- If we interrupt Compose (with `^C`), it will politely ask the Docker Engine to stop the app
|
||||
|
||||
- The Docker Engine will send a `TERM` signal to the containers
|
||||
|
||||
- If the containers do not exit in a timely manner, the Engine sends a `KILL` signal
|
||||
|
||||
.lab[
|
||||
|
||||
- Stop the application by hitting `^C`
|
||||
|
||||
<!--
|
||||
```key ^C```
|
||||
-->
|
||||
|
||||
]
|
||||
|
||||
--
|
||||
|
||||
Some containers exit immediately, others take longer.
|
||||
|
||||
The containers that do not handle `SIGTERM` end up being killed after a 10s timeout. If we are very impatient, we can hit `^C` a second time!
|
||||
|
||||
|
||||
73
slides/shared/about-slides-v2.md
Normal file
73
slides/shared/about-slides-v2.md
Normal file
@@ -0,0 +1,73 @@
|
||||
## Accessing these slides now
|
||||
|
||||
- We recommend that you open these slides in your browser:
|
||||
|
||||
@@SLIDES@@
|
||||
|
||||
- Use arrows to move to next/previous slide
|
||||
|
||||
(up, down, left, right, page up, page down)
|
||||
|
||||
- Type a slide number + ENTER to go to that slide
|
||||
|
||||
- The slide number is also visible in the URL bar
|
||||
|
||||
(e.g. .../#123 for slide 123)
|
||||
|
||||
---
|
||||
|
||||
## Accessing these slides later
|
||||
|
||||
- Slides will remain online some time.
|
||||
|
||||
- You can download the slides using that URL:
|
||||
|
||||
@@ZIP@@
|
||||
|
||||
(then open the file `@@HTML@@`)
|
||||
|
||||
- You will find new versions of these slides (and more) on the upstream repo:
|
||||
|
||||
https://container.training/
|
||||
|
||||
---
|
||||
|
||||
## These slides are open source
|
||||
|
||||
- You are welcome to use, re-use, share these slides
|
||||
|
||||
- These slides are written in Markdown
|
||||
|
||||
- The sources of these slides are available in a public GitHub repository:
|
||||
|
||||
https://@@GITREPO@@
|
||||
|
||||
- Typos? Mistakes? Questions? Feel free to hover over the bottom of the slide ...
|
||||
|
||||
.footnote[👇 Try it! The source file will be shown and you can view it on GitHub and fork and edit it.]
|
||||
|
||||
<!--
|
||||
.lab[
|
||||
```open https://@@GITREPO@@/tree/master/slides/common/about-slides.md```
|
||||
]
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
class: extra-details
|
||||
|
||||
## Extra details
|
||||
|
||||
- This slide has a little magnifying glass in the top left corner
|
||||
|
||||
- This magnifying glass indicates slides that provide extra details
|
||||
|
||||
- Feel free to skip them if:
|
||||
|
||||
- you are in a hurry
|
||||
|
||||
- you are new to this and want to avoid cognitive overload
|
||||
|
||||
- you want only the most essential information
|
||||
|
||||
- You can review these slides another time if you want, they'll be waiting for you ☺
|
||||
@@ -29,31 +29,31 @@ Container Orchestration<br/>with Docker and Swarm<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
|
||||
@@ -29,31 +29,31 @@ Container Orchestration<br/>with Docker and Swarm<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
|
||||
@@ -29,31 +29,31 @@ Container Orchestration<br/>with Docker and Swarm<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
|
||||
@@ -29,31 +29,31 @@ Container Orchestration<br/>with Docker and Swarm<br/>
|
||||
|
||||
.debug[
|
||||
```
|
||||
D slides/.gitea/workflows/build.yaml
|
||||
M slides/build.sh
|
||||
?? k8s/
|
||||
M slides/intro-bd-k8s.yml.html
|
||||
M slides/intro-container-security.yml
|
||||
M slides/intro-container-security.yml.html
|
||||
M slides/kadm-fullday.yml.html
|
||||
M slides/kadm-twodays.yml.html
|
||||
M slides/kube-fullday.yml.html
|
||||
M slides/kube-halfday.yml.html
|
||||
M slides/kube-selfpaced.yml.html
|
||||
M slides/kube-twodays.yml.html
|
||||
M slides/secure-containers/sampleapp.md
|
||||
M slides/swarm-fullday.yml.html
|
||||
M slides/swarm-halfday.yml.html
|
||||
M slides/swarm-selfpaced.yml.html
|
||||
M slides/swarm-video.yml.html
|
||||
?? .gitea/
|
||||
?? shpod/
|
||||
?? slides/intro-bd-docker.yml.html
|
||||
?? "slides/intro-bd-helm copy.yml.html"
|
||||
?? slides/intro-bd-helm.yml
|
||||
?? slides/intro-bd-helm.yml.html
|
||||
?? slides/intro-bd-k8s.yml.html
|
||||
?? slides/intro-container-security.yml
|
||||
?? slides/intro-container-security.yml.html
|
||||
?? slides/kadm-fullday.yml.html
|
||||
?? slides/kadm-twodays.yml.html
|
||||
?? slides/kube-adv.yml.html
|
||||
?? slides/kube-fullday.yml.html
|
||||
?? slides/kube-halfday.yml.html
|
||||
?? slides/kube-selfpaced.yml.html
|
||||
?? slides/kube-twodays.yml.html
|
||||
?? slides/swarm-fullday.yml.html
|
||||
?? slides/swarm-halfday.yml.html
|
||||
?? slides/swarm-selfpaced.yml.html
|
||||
?? slides/swarm-video.yml.html
|
||||
?? slides/secure-containers/cve.md
|
||||
?? slides/secure-containers/possible-improvements.md
|
||||
?? slides/shared/about-slides-v2.md
|
||||
|
||||
```
|
||||
|
||||
These slides have been built from commit: ce3849f
|
||||
These slides have been built from commit: 4571b5e
|
||||
|
||||
|
||||
[shared/title.md](file:///repo/slides/shared/title.md)]
|
||||
|
||||
Reference in New Issue
Block a user