Compare commits

..

13 Commits

Author SHA1 Message Date
Jerome Petazzoni
08fa37dace fix-redirects.sh: adding forced redirect 2020-04-07 16:57:19 -05:00
Jerome Petazzoni
807028cbf3 Remove WiFi warning 2019-06-13 10:51:44 -05:00
Jerome Petazzoni
dfde597cb9 Merge branch 'master' into sfsf-2019-06 2019-06-13 10:51:22 -05:00
Jerome Petazzoni
96419c6baf test→node 2019-06-12 21:35:12 -05:00
Jerome Petazzoni
12da011f21 Customize logistics etc 2019-06-12 21:13:00 -05:00
Jerome Petazzoni
fa1637fb7e Add Helm charts and reorg content 2019-06-12 21:07:55 -05:00
Jerome Petazzoni
fbe2251e21 Merge remote-tracking branch 'origin/make-chart' into sfsf-2019-06 2019-06-12 21:07:12 -05:00
Jerome Petazzoni
b4faf10581 merge 2019-06-12 16:43:24 -05:00
Jerome Petazzoni
0ef9c87f97 Merge branch 'master' into sfsf-2019-06 2019-06-12 16:04:36 -05:00
Jerome Petazzoni
addd14582a merge 2019-06-09 18:41:04 -05:00
Jerome Petazzoni
5299fbaab5 merge 2019-06-02 19:32:20 -05:00
Jerome Petazzoni
398ff5ee4f merge 2019-06-02 16:48:30 -05:00
Jerome Petazzoni
b883e6d557 Prepare SFSF training 2019-06-02 16:47:53 -05:00
46 changed files with 202 additions and 1327 deletions

View File

@@ -229,7 +229,7 @@ EOF"
pssh "
if [ ! -x /usr/local/bin/stern ]; then
##VERSION##
sudo curl -L -o /usr/local/bin/stern https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64 &&
sudo curl -L -o /usr/local/bin/stern https://github.com/wercker/stern/releases/download/1.10.0/stern_linux_amd64 &&
sudo chmod +x /usr/local/bin/stern &&
stern --completion bash | sudo tee /etc/bash_completion.d/stern
fi"
@@ -318,14 +318,6 @@ _cmd_listall() {
done
}
_cmd ping "Ping VMs in a given tag, to check that they have network access"
_cmd_ping() {
TAG=$1
need_tag
fping < tags/$TAG/ips.txt
}
_cmd netfix "Disable GRO and run a pinger job on the VMs"
_cmd_netfix () {
TAG=$1

View File

@@ -31,7 +31,6 @@ infra_start() {
die "I could not find which AMI to use in this region. Try another region?"
fi
AWS_KEY_NAME=$(make_key_name)
AWS_INSTANCE_TYPE=${AWS_INSTANCE_TYPE-t3a.medium}
sep "Starting instances"
info " Count: $COUNT"
@@ -39,11 +38,10 @@ infra_start() {
info " Token/tag: $TAG"
info " AMI: $AMI"
info " Key name: $AWS_KEY_NAME"
info " Instance type: $AWS_INSTANCE_TYPE"
result=$(aws ec2 run-instances \
--key-name $AWS_KEY_NAME \
--count $COUNT \
--instance-type $AWS_INSTANCE_TYPE \
--instance-type ${AWS_INSTANCE_TYPE-t2.medium} \
--client-token $TAG \
--block-device-mapping 'DeviceName=/dev/sda1,Ebs={VolumeSize=20}' \
--image-id $AMI)
@@ -99,7 +97,7 @@ infra_disableaddrchecks() {
}
wait_until_tag_is_running() {
max_retry=100
max_retry=50
i=0
done_count=0
while [[ $done_count -lt $COUNT ]]; do

View File

@@ -21,7 +21,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.21.1
machine_version: 0.14.0
# Password used to connect with the "docker user"

View File

@@ -21,7 +21,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.21.1
machine_version: 0.14.0
# Password used to connect with the "docker user"

View File

@@ -21,7 +21,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.21.1
machine_version: 0.14.0
# Password used to connect with the "docker user"

View File

@@ -21,7 +21,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.21.1
machine_version: 0.14.0
# Password used to connect with the "docker user"

View File

@@ -23,7 +23,7 @@ paper_margin: 0.2in
engine_version: test
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.18.0
machine_version: 0.13.0
# Password used to connect with the "docker user"

View File

@@ -23,7 +23,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.22.0
machine_version: 0.15.0
# Password used to connect with the "docker user"

View File

@@ -21,7 +21,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.21.1
machine_version: 0.14.0
# Password used to connect with the "docker user"

View File

@@ -23,7 +23,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.21.1
machine_version: 0.14.0
# Password used to connect with the "docker user"

View File

@@ -23,7 +23,7 @@ paper_margin: 0.2in
engine_version: stable
# These correspond to the version numbers visible on their respective GitHub release pages
compose_version: 1.24.1
compose_version: 1.22.0
machine_version: 0.15.0
# Password used to connect with the "docker user"

View File

@@ -30,9 +30,9 @@ TAG=$PREFIX-$SETTINGS
--settings settings/$SETTINGS.yaml \
--count $((3*$STUDENTS))
./workshopctl disableaddrchecks $TAG
./workshopctl deploy $TAG
./workshopctl kubebins $TAG
./workshopctl disableaddrchecks $TAG
./workshopctl cards $TAG
SETTINGS=admin-kuberouter
@@ -43,15 +43,11 @@ TAG=$PREFIX-$SETTINGS
--settings settings/$SETTINGS.yaml \
--count $((3*$STUDENTS))
./workshopctl disableaddrchecks $TAG
./workshopctl deploy $TAG
./workshopctl kubebins $TAG
./workshopctl disableaddrchecks $TAG
./workshopctl cards $TAG
#INFRA=infra/aws-us-west-1
export AWS_INSTANCE_TYPE=t3a.medium
SETTINGS=admin-test
TAG=$PREFIX-$SETTINGS
./workshopctl start \
@@ -63,4 +59,3 @@ TAG=$PREFIX-$SETTINGS
./workshopctl deploy $TAG
./workshopctl kube $TAG 1.13.5
./workshopctl cards $TAG

View File

@@ -1,5 +1,5 @@
# Uncomment and/or edit one of the the following lines if necessary.
#/ /kube-halfday.yml.html 200
#/ /kube-fullday.yml.html 200
/ /maersk.html 200!
#/ /kube-twodays.yml.html 200
/ /sfsf.yml.html 200!

View File

@@ -76,78 +76,6 @@ CMD ["python", "app.py"]
---
## Be careful with `chown`, `chmod`, `mv`
* Layers cannot store efficiently changes in permissions or ownership.
* Layers cannot represent efficiently when a file is moved either.
* As a result, operations like `chown`, `chown`, `mv` can be expensive.
* For instance, in the Dockerfile snippet below, each `RUN` line
creates a layer with an entire copy of `some-file`.
```dockerfile
COPY some-file .
RUN chown www-data:www-data some-file
RUN chmod 644 some-file
RUN mv some-file /var/www
```
* How can we avoid that?
---
## Put files on the right place
* Instead of using `mv`, directly put files at the right place.
* When extracting archives (tar, zip...), merge operations in a single layer.
Example:
```dockerfile
...
RUN wget http://.../foo.tar.gz \
&& tar -zxf foo.tar.gz \
&& mv foo/fooctl /usr/local/bin \
&& rm -rf foo
...
```
---
## Use `COPY --chown`
* The Dockerfile instruction `COPY` can take a `--chown` parameter.
Examples:
```dockerfile
...
COPY --chown=1000 some-file .
COPY --chown=1000:1000 some-file .
COPY --chown=www-data:www-data some-file .
```
* The `--chown` flag can specify a user, or a user:group pair.
* The user and group can be specified as names or numbers.
* When using names, the names must exist in `/etc/passwd` or `/etc/group`.
*(In the container, not on the host!)*
---
## Set correct permissions locally
* Instead of using `chmod`, set the right file permissions locally.
* When files are copied with `COPY`, permissions are preserved.
---
## Embedding unit tests in the build process
```dockerfile

View File

@@ -1,11 +1,3 @@
- date: [2019-11-04, 2019-11-05]
country: de
city: Berlin
event: Velocity
speaker: jpetazzo
title: Deploying and scaling applications with Kubernetes
attend: https://conferences.oreilly.com/velocity/vl-eu/public/schedule/detail/79109
- date: 2019-11-13
country: fr
city: Marseille
@@ -24,14 +16,6 @@
lang: fr
attend: https://enix.io/fr/services/formation/deployer-ses-applications-avec-kubernetes/
- date: 2019-07-16
country: us
city: Portland, OR
event: OSCON
speaker: bridgetkromhout
title: "Kubernetes 201: Production tooling"
attend: https://conferences.oreilly.com/oscon/oscon-or/public/schedule/detail/76390
- date: 2019-06-17
country: ca
city: Montréal

View File

@@ -1,63 +0,0 @@
title: |
Introduction
to Containers
chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
#chat: "[Gitter](https://gitter.im/jpetazzo/workshop-yyyymmdd-city)"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
exclude:
- self-paced
chapters:
- shared/title.md
- logistics.md
- containers/intro.md
- shared/about-slides.md
- shared/toc.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/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
- containers/Multi_Stage_Builds.md
- containers/Publishing_To_Docker_Hub.md
- containers/Dockerfile_Tips.md
- containers/Exercise_Dockerfile_Advanced.md
- - containers/Naming_And_Inspecting.md
- containers/Labels.md
- containers/Getting_Inside.md
- containers/Resource_Limits.md
- - containers/Container_Networking_Basics.md
- containers/Network_Drivers.md
- containers/Container_Network_Model.md
#- containers/Connecting_Containers_With_Links.md
- containers/Ambassadors.md
- - containers/Local_Development_Workflow.md
- containers/Windows_Containers.md
- containers/Working_With_Volumes.md
- containers/Compose_For_Dev_Stacks.md
- containers/Exercise_Composefile.md
- - containers/Docker_Machine.md
- containers/Advanced_Dockerfiles.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/Ecosystem.md
- containers/Orchestration_Overview.md
- shared/thankyou.md
- containers/links.md

View File

@@ -1,63 +0,0 @@
title: |
Introduction
to Containers
chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
#chat: "[Gitter](https://gitter.im/jpetazzo/workshop-yyyymmdd-city)"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
exclude:
- in-person
chapters:
- shared/title.md
# - shared/logistics.md
- containers/intro.md
- shared/about-slides.md
- shared/toc.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/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
- - containers/Multi_Stage_Builds.md
- containers/Publishing_To_Docker_Hub.md
- containers/Dockerfile_Tips.md
- containers/Exercise_Dockerfile_Advanced.md
- - containers/Naming_And_Inspecting.md
- containers/Labels.md
- containers/Getting_Inside.md
- - containers/Container_Networking_Basics.md
- containers/Network_Drivers.md
- containers/Container_Network_Model.md
#- containers/Connecting_Containers_With_Links.md
- containers/Ambassadors.md
- - containers/Local_Development_Workflow.md
- containers/Windows_Containers.md
- containers/Working_With_Volumes.md
- containers/Compose_For_Dev_Stacks.md
- containers/Exercise_Composefile.md
- containers/Docker_Machine.md
- - containers/Advanced_Dockerfiles.md
- containers/Application_Configuration.md
- containers/Logging.md
- containers/Resource_Limits.md
- - containers/Namespaces_Cgroups.md
- containers/Copy_On_Write.md
#- containers/Containers_From_Scratch.md
- - containers/Container_Engines.md
- containers/Ecosystem.md
- containers/Orchestration_Overview.md
- shared/thankyou.md
- containers/links.md

View File

@@ -167,11 +167,13 @@ What does that mean?
## Let's experiment a bit!
- For the exercises in this section, connect to the first node of the `test` cluster
- For this section, we will use a cluster with 4 nodes
(named node1, node2, node3, node4)
.exercise[
- SSH to the first node of the test cluster
- SSH to the first node of the cluster
- Check that the cluster is operational:
```bash

View File

@@ -18,7 +18,7 @@
(it gives us replication primitives)
- Kubernetes helps us clone / replicate environments
- Kubernetes helps us to clone/replicate environments
(all resources can be described with manifests)

View File

@@ -66,8 +66,6 @@ Look in each plugin's directory for its documentation.
---
class: extra-details
## Conf vs conflist
- There are two slightly different configuration formats

View File

@@ -38,7 +38,7 @@
<!-- ##VERSION## -->
- Unfortunately, as of Kubernetes 1.15, the CLI cannot create daemon sets
- Unfortunately, as of Kubernetes 1.14, the CLI cannot create daemon sets
--

View File

@@ -175,7 +175,7 @@ Success!
]
We should get `No resources found.` and the `kubernetes` service, respectively.
So far, so good.
Note: the API server automatically created the `kubernetes` service entry.
@@ -225,7 +225,7 @@ Success?
]
Our Deployment is in bad shape:
Our Deployment is in a bad shape:
```
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/web 0/1 0 0 2m26s

View File

@@ -123,12 +123,12 @@
- Create the yellow namespace:
```bash
kubectl create namespace probes
kubectl create namespace yellow
```
- Switch to that namespace:
```bash
kns probes
kns yellow
```
]
@@ -143,7 +143,7 @@
.exercise[
- Clone that repository, if we haven't done it yet:
- Clone that repository:
```bash
cd ~
git clone https://github.com/jpetazzo/kubercoins
@@ -192,9 +192,9 @@ It will use the default success threshold (1 successful attempt = alive).
.exercise[
- Edit `rng-deployment.yaml` and add the liveness probe
- Edit `rng-daemonset.yaml` and add the liveness probe
```bash
vim rng-deployment.yaml
vim rng-daemonset.yaml
```
- Load the YAML for all the resources of DockerCoins:
@@ -304,15 +304,15 @@ It will use the default success threshold (1 successful attempt = alive).
- We need to make sure that the healthcheck doesn't trip when
performance degrades due to external pressure
- Using a readiness check would have fewer effects
- Using a readiness check would have lesser effects
(but it would still be an imperfect solution)
(but it still would be an imperfect solution)
- A possible combination:
- readiness check with a short timeout / low failure threshold
- liveness check with a longer timeout / higher failure threshold
- liveness check with a longer timeout / higher failure treshold
---
@@ -344,7 +344,7 @@ class: extra-details
- When a process is killed, its children are *orphaned* and attached to PID 1
- PID 1 has the responsibility of *reaping* these processes when they terminate
- PID 1 has the responsibility if *reaping* these processes when they terminate
- OK, but how does that affect us?
@@ -378,11 +378,11 @@ class: extra-details
(because worker isn't a backend for a service)
- Liveness may help us restart a broken worker, but how can we check it?
- Liveness may help us to restart a broken worker, but how can we check it?
- Embedding an HTTP server is an option
(but it has a high potential for unwanted side effects and false positives)
(but it has a high potential for unwanted side-effects and false positives)
- Using a "lease" file can be relatively easy:

View File

@@ -1,8 +1,8 @@
# Controlling a Kubernetes cluster remotely
# Controlling the cluster remotely
- `kubectl` can be used either on cluster instances or outside the cluster
- All the operations that we do with `kubectl` can be done remotely
- Here, we are going to use `kubectl` from our local machine
- In this section, we are going to use `kubectl` from our local machine
---
@@ -34,11 +34,11 @@
- Download the `kubectl` binary from one of these links:
[Linux](https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/linux/amd64/kubectl)
[Linux](https://storage.googleapis.com/kubernetes-release/release/v1.14.2/bin/linux/amd64/kubectl)
|
[macOS](https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/darwin/amd64/kubectl)
[macOS](https://storage.googleapis.com/kubernetes-release/release/v1.14.2/bin/darwin/amd64/kubectl)
|
[Windows](https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/windows/amd64/kubectl.exe)
[Windows](https://storage.googleapis.com/kubernetes-release/release/v1.14.2/bin/windows/amd64/kubectl.exe)
- On Linux and macOS, make the binary executable with `chmod +x kubectl`
@@ -67,10 +67,10 @@ Note: if you are following along with a different platform (e.g. Linux on an arc
The output should look like this:
```
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.0",
GitCommit:"e8462b5b5dc2584fdcd18e6bcfe9f1e4d970a529", GitTreeState:"clean",
BuildDate:"2019-06-19T16:40:16Z", GoVersion:"go1.12.5", Compiler:"gc",
Platform:"darwin/amd64"}
Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.0",
GitCommit:"641856db18352033a0d96dbc99153fa3b27298e5", GitTreeState:"clean",
BuildDate:"2019-03-25T15:53:57Z", GoVersion:"go1.12.1", Compiler:"gc",
Platform:"linux/amd64"}
```
---
@@ -192,4 +192,4 @@ class: extra-details
]
We can now utilize the cluster exactly as if we're logged into a node, except that it's remote.
We can now utilize the cluster exactly as we did before, except that it's remote.

View File

@@ -62,7 +62,7 @@ Exactly what we need!
- The following commands will install Stern on a Linux Intel 64 bit machine:
```bash
sudo curl -L -o /usr/local/bin/stern \
https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64
https://github.com/wercker/stern/releases/download/1.10.0/stern_linux_amd64
sudo chmod +x /usr/local/bin/stern
```

View File

@@ -1,8 +1,8 @@
# Checking pod and node resource usage
- Since Kubernetes 1.8, metrics are collected by the [resource metrics pipeline](https://kubernetes.io/docs/tasks/debug-application-cluster/resource-metrics-pipeline/)
- Since Kubernetes 1.8, metrics are collected by the [core metrics pipeline](https://v1-13.docs.kubernetes.io/docs/tasks/debug-application-cluster/core-metrics-pipeline/)
- The resource metrics pipeline is:
- The core metrics pipeline is:
- optional (Kubernetes can function without it)
@@ -37,7 +37,7 @@ If it shows our nodes and their CPU and memory load, we're good!
(it doesn't need persistence, as it doesn't *store* metrics)
- It has its own repository, [kubernetes-incubator/metrics-server](https://github.com/kubernetes-incubator/metrics-server)
- It has its own repository, [kubernetes-incubator/metrics-server](https://github.com/kubernetes-incubator/metrics-server])
- The repository comes with [YAML files for deployment](https://github.com/kubernetes-incubator/metrics-server/tree/master/deploy/1.8%2B)
@@ -59,7 +59,7 @@ If it shows our nodes and their CPU and memory load, we're good!
- Show resource usage across all containers:
```bash
kubectl top pods --containers --all-namespaces
kuebectl top pods --containers --all-namespaces
```
]

View File

@@ -195,7 +195,7 @@ class: extra-details
## Check our pods
- The pods will be scheduled on the nodes
- The pods will be scheduled to the nodes
- The nodes will pull the `nginx` image, and start the pods
@@ -325,7 +325,7 @@ class: extra-details
- We will add the `--network-plugin` and `--pod-cidr` flags
- We all have a "cluster number" (let's call that `C`) printed on your VM info card
- We all have a "cluster number" (let's call that `C`)
- We will use pod CIDR `10.C.N.0/24` (where `N` is the node number: 1, 2, 3)
@@ -480,23 +480,6 @@ Sometimes it works, sometimes it doesn't. Why?
```bash
kubectl get nodes -o wide
```
---
## Firewalling
- By default, Docker prevents containers from using arbitrary IP addresses
(by setting up iptables rules)
- We need to allow our containers to use our pod CIDR
- For simplicity, we will insert a blanket iptables rule allowing all traffic:
`iptables -I FORWARD -j ACCEPT`
- This has to be done on every node
---
## Setting up routing
@@ -505,8 +488,6 @@ Sometimes it works, sometimes it doesn't. Why?
- Create all the routes on all the nodes
- Insert the iptables rule allowing traffic
- Check that you can ping all the pods from one of the nodes
- Check that you can `curl` the ClusterIP of the Service successfully

View File

@@ -1,379 +0,0 @@
# OpenID Connect
- The Kubernetes API server can perform authentication with OpenID connect
- This requires an *OpenID provider*
(external authorization server using the OAuth 2.0 protocol)
- We can use a third-party provider (e.g. Google) or run our own (e.g. Dex)
- We are going to give an overview of the protocol
- We will show it in action (in a simplified scenario)
---
## Workflow overview
- We want to access our resources (a Kubernetes cluster)
- We authenticate with the OpenID provider
- we can do this directly (e.g. by going to https://accounts.google.com)
- or maybe a kubectl plugin can open a browser page on our behalf
- After authenticating us, the OpenID provider gives us:
- an *id token* (a short-lived signed JSON Web Token, see next slide)
- a *refresh token* (to renew the *id token* when needed)
- We can now issue requests to the Kubernetes API with the *id token*
- The API server will verify that token's content to authenticate us
---
## JSON Web Tokens
- A JSON Web Token (JWT) has three parts:
- a header specifying algorithms and token type
- a payload (indicating who issued the token, for whom, which purposes...)
- a signature generated by the issuer (the issuer = the OpenID provider)
- Anyone can verify a JWT without contacting the issuer
(except to obtain the issuer's public key)
- Pro tip: we can inspect a JWT with https://jwt.io/
---
## How the Kubernetes API uses JWT
- Server side
- enable OIDC authentication
- indicate which issuer (provider) should be allowed
- indicate which audience (or "client id") should be allowed
- optionally, map or prefix user and group names
- Client side
- obtain JWT as described earlier
- pass JWT as authentication token
- renew JWT when needed (using the refresh token)
---
## Demo time!
- We will use [Google Accounts](https://accounts.google.com) as our OpenID provider
- We will use the [Google OAuth Playground](https://developers.google.com/oauthplayground) as the "audience" or "client id"
- We will obtain a JWT through Google Accounts and the OAuth Playground
- We will enable OIDC in the Kubernetes API server
- We will use the JWT to authenticate
.footnote[If you can't or won't use a Google account, you can try to adapt this to another provider.]
---
## Checking the API server logs
- The API server logs will be particularly useful in this section
(they will indicate e.g. why a specific token is rejected)
- Let's keep an eye on the API server output!
.exercise[
- Tail the logs of the API server:
```bash
kubectl logs kube-apiserver-node1 --follow --namespace=kube-system
```
]
---
## Authenticate with the OpenID provider
- We will use the Google OAuth Playground for convenience
- In a real scenario, we would need our own OAuth client instead of the playground
(even if we were still using Google as the OpenID provider)
.exercise[
- Open the Google OAuth Playground:
```
https://developers.google.com/oauthplayground/
```
- Enter our own custom scope in the text field:
```
https://www.googleapis.com/auth/userinfo.email
```
- Click on "Authorize APIs" and allow the playground to access our email address
]
---
## Obtain our JSON Web Token
- The previous step gave us an "authorization code"
- We will use it to obtain tokens
.exercise[
- Click on "Exchange authorization code for tokens"
]
- The JWT is the very long `id_token` that shows up on the right hand side
(it is a base64-encoded JSON object, and should therefore start with `eyJ`)
---
## Using our JSON Web Token
- We need to create a context (in kubeconfig) for our token
(if we just add the token or use `kubectl --token`, our certificate will still be used)
.exercise[
- Create a new authentication section in kubeconfig:
```bash
kubectl config set-credentials myjwt --token=eyJ...
```
- Try to use it:
```bash
kubectl --user=myjwt get nodes
```
]
We should get an `Unauthorized` response, since we haven't enabled OpenID Connect in the API server yet. We should also see `invalid bearer token` in the API server log output.
---
## Enabling OpenID Connect
- We need to add a few flags to the API server configuration
- These two are mandatory:
`--oidc-issuer-url` → URL of the OpenID provider
`--oidc-client-id` → app requesting the authentication
<br/>(in our case, that's the ID for the Google OAuth Playground)
- This one is optional:
`--oidc-username-claim` → which field should be used as user name
<br/>(we will use the user's email address instead of an opaque ID)
- See the [API server documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#configuring-the-api-server
) for more details about all available flags
---
## Updating the API server configuration
- The instructions below will work for clusters deployed with kubeadm
(or where the control plane is deployed in static pods)
- If your cluster is deployed differently, you will need to adapt them
.exercise[
- Edit `/etc/kubernetes/manifests/kube-apiserver.yaml`
- Add the following lines to the list of command-line flags:
```yaml
- --oidc-issuer-url=https://accounts.google.com
- --oidc-client-id=407408718192.apps.googleusercontent.com
- --oidc-username-claim=email
```
]
---
## Restarting the API server
- The kubelet monitors the files in `/etc/kubernetes/manifests`
- When we save the pod manifest, kubelet will restart the corresponding pod
(using the updated command line flags)
.exercise[
- After making the changes described on the previous slide, save the file
- Issue a simple command (like `kubectl version`) until the API server is back up
(it might take between a few seconds and one minute for the API server to restart)
- Restart the `kubectl logs` command to view the logs of the API server
]
---
## Using our JSON Web Token
- Now that the API server is set up to recognize our token, try again!
.exercise[
- Try an API command with our token:
```bash
kubectl --user=myjwt get nodes
kubectl --user=myjwt get pods
```
]
We should see a message like:
```
Error from server (Forbidden): nodes is forbidden: User "jean.doe@gmail.com"
cannot list resource "nodes" in API group "" at the cluster scope
```
→ We were successfully *authenticated*, but not *authorized*.
---
## Authorizing our user
- As an extra step, let's grant read access to our user
- We will use the pre-defined ClusterRole `view`
.exercise[
- Create a ClusterRoleBinding allowing us to view resources:
```bash
kubectl create clusterrolebinding i-can-view \
--user=`jean.doe@gmail.com` --clusterrole=view
```
(make sure to put *your* Google email address there)
- Confirm that we can now list pods with our token:
```bash
kubectl --user=myjwt get pods
```
]
---
## From demo to production
.warning[This was a very simplified demo! In a real deployment...]
- We wouldn't use the Google OAuth Playground
- We *probably* wouldn't even use Google at all
(it doesn't seem to provide a way to include groups!)
- Some popular alternatives:
- [Dex](https://github.com/dexidp/dex),
[Keycloak](https://www.keycloak.org/)
(self-hosted)
- [Okta](https://developer.okta.com/docs/how-to/creating-token-with-groups-claim/#step-five-decode-the-jwt-to-verify)
(SaaS)
- We would use a helper (like the [kubelogin](https://github.com/int128/kubelogin) plugin) to automatically obtain tokens
---
class: extra-details
## Service Account tokens
- The tokens used by Service Accounts are JWT tokens as well
- They are signed and verified using a special service account key pair
.exercise[
- Extract the token of a service account in the current namespace:
```bash
kubectl get secrets -o jsonpath={..token} | base64 -d
```
- Copy-paste the token to a verification service like https://jwt.io
- Notice that it says "Invalid Signature"
]
---
class: extra-details
## Verifying Service Account tokens
- JSON Web Tokens embed the URL of the "issuer" (=OpenID provider)
- The issuer provides its public key through a well-known discovery endpoint
(similar to https://accounts.google.com/.well-known/openid-configuration)
- There is no such endpoint for the Service Account key pair
- But we can provide the public key ourselves for verification
---
class: extra-details
## Verifying a Service Account token
- On clusters provisioned with kubeadm, the Service Account key pair is:
`/etc/kubernetes/pki/sa.key` (used by the controller manager to generate tokens)
`/etc/kubernetes/pki/sa.pub` (used by the API server to validate the same tokens)
.exercise[
- Display the public key used to sign Service Account tokens:
```bash
sudo cat /etc/kubernetes/pki/sa.pub
```
- Copy-paste the key in the "verify signature" area on https://jwt.io
- It should now say "Signature Verified"
]

View File

@@ -86,7 +86,7 @@ class: extra-details
## What can we store via the Kubernetes API?
- The API server stores most Kubernetes resources in etcd
- The API server stores most Kubernetes resources into etcd
- Etcd is designed for reliability, not for performance

View File

@@ -1,4 +1,4 @@
# Highly available Persistent Volumes
# Highly available Persistent Volumes (extra material)
- How can we achieve true durability?

View File

@@ -1,169 +0,0 @@
# Recording deployment actions
- Some commands that modify a Deployment accept an optional `--record` flag
(Example: `kubectl set image deployment worker worker=alpine --record`)
- That flag will store the command line in the Deployment
(Technically, using the annotation `kubernetes.io/change-cause`)
- It gets copied to the corresponding ReplicaSet
(Allowing to keep track of which command created or promoted this ReplicaSet)
- We can view this information with `kubectl rollout history`
---
## Using `--record`
- Let's make a couple of changes to a Deployment and record them
.exercise[
- Roll back `worker` to image version 0.1:
```bash
kubectl set image deployment worker worker=dockercoins/worker:v0.1 --record
```
- Promote it to version 0.2 again:
```bash
kubectl set image deployment worker worker=dockercoins/worker:v0.2 --record
```
- View the change history:
```bash
kubectl rollout history deployment worker
```
]
---
## Pitfall #1: forgetting `--record`
- What happens if we don't specify `--record`?
.exercise[
- Promote `worker` to image version 0.3:
```bash
kubectl set image deployment worker worker=dockercoins/worker:v0.3
```
- View the change history:
```bash
kubectl rollout history deployment worker
```
]
--
It recorded version 0.2 instead of 0.3! Why?
---
## How `--record` really works
- `kubectl` adds the annotation `kubernetes.io/change-cause` to the Deployment
- The Deployment controller copies that annotation to the ReplicaSet
- `kubectl rollout history` shows the ReplicaSets' annotations
- If we don't specify `--record`, the annotation is not updated
- The previous value of that annotation is copied to the new ReplicaSet
- In that case, the ReplicaSet annotation does not reflect reality!
---
## Pitfall #2: recording `scale` commands
- What happens if we use `kubectl scale --record`?
.exercise[
- Check the current history:
```bash
kubectl rollout history deployment worker
```
- Scale the deployment:
```bash
kubectl scale deployment worker --replicas=3 --record
```
- Check the change history again:
```bash
kubectl rollout history deployment worker
```
]
--
The last entry in the history was overwritten by the `scale` command! Why?
---
## Actions that don't create a new ReplicaSet
- The `scale` command updates the Deployment definition
- But it doesn't create a new ReplicaSet
- Using the `--record` flag sets the annotation like before
- The annotation gets copied to the existing ReplicaSet
- This overwrites the previous annotation that was there
- In that case, we lose the previous change cause!
---
## Updating the annotation directly
- Let's see what happens if we set the annotation manually
.exercise[
- Annotate the Deployment:
```bash
kubectl annotate deployment worker kubernetes.io/change-cause="Just for fun"
```
- Check that our annotation shows up in the change history:
```bash
kubectl rollout history deployment worker
```
]
--
Our annotation shows up (and overwrote whatever was there before).
---
## Using change cause
- It sounds like a good idea to use `--record`, but:
*"Incorrect documentation is often worse than no documentation."*
<br/>
(Bertrand Meyer)
- If we use `--record` once, we need to either:
- use it every single time after that
- or clear the Deployment annotation after using `--record`
<br/>
(subsequent changes will show up with a `<none>` change cause)
- A safer way is to set it through our tooling

View File

@@ -404,7 +404,7 @@ These quotas will apply to the namespace where the ResourceQuota is created.
- Example:
```bash
kubectl create quota my-resource-quota --hard=pods=300,limits.memory=300Gi
kubectl create quota sparta --hard=pods=300,limits.memory=300Gi
```
- With both YAML and CLI form, the values are always under the `hard` section

View File

@@ -265,8 +265,6 @@ Note the `3xxxx` port.
---
class: extra-details
## Changing rollout parameters
- We want to:
@@ -296,8 +294,6 @@ spec:
---
class: extra-details
## Applying changes through a YAML patch
- We could use `kubectl edit deployment worker`

View File

@@ -144,7 +144,7 @@ with a cloud provider
az login
```
- Select a [region](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=kubernetes-service&regions=all
- Select a [region](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=kubernetes-service\&regions=all
)
- Create a "resource group":
@@ -168,7 +168,7 @@ with a cloud provider
az aks get-credentials --resource-group my-aks-group --name my-aks-cluster
```
- The cluster has useful components pre-installed, such as the metrics server
- The cluster has a lot of goodies pre-installed
---
@@ -224,7 +224,7 @@ with a cloud provider
kubectl config use-context do-xxx1-my-do-cluster
```
- The cluster comes with some components (like Cilium) but no metrics server
- The cluster comes with some goodies (like Cilium) but no metrics server
---

View File

@@ -80,8 +80,6 @@
- Docker Enterprise Edition
- [AKS Engine](https://github.com/Azure/aks-engine)
- Pivotal Container Service (PKS)
- Tectonic by CoreOS

View File

@@ -1,8 +1,8 @@
## Versions installed
- Kubernetes 1.15.0
- Docker Engine 18.09.7
- Docker Compose 1.24.1
- Kubernetes 1.14.2
- Docker Engine 18.09.6
- Docker Compose 1.21.1
<!-- ##VERSION## -->
@@ -23,7 +23,7 @@ class: extra-details
## Kubernetes and Docker compatibility
- Kubernetes 1.15 validates Docker Engine versions [up to 18.09](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.15.md#dependencies)
- Kubernetes 1.14 validates Docker Engine versions [up to 18.09](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md#external-dependencies)
<br/>
(the latest version when Kubernetes 1.14 was released)

View File

@@ -136,6 +136,77 @@ And *then* it is time to look at orchestration!
---
## HTTP traffic handling
- *Services* are layer 4 constructs
- HTTP is a layer 7 protocol
- It is handled by *ingresses* (a different resource kind)
- *Ingresses* allow:
- virtual host routing
- session stickiness
- URI mapping
- and much more!
- [This section](kube-selfpaced.yml.html#toc-exposing-http-services-with-ingress-resources) shows how to expose multiple HTTP apps using [Træfik](https://docs.traefik.io/user-guide/kubernetes/)
---
## Logging
- Logging is delegated to the container engine
- Logs are exposed through the API
- Logs are also accessible through local files (`/var/log/containers`)
- Log shipping to a central platform is usually done through these files
(e.g. with an agent bind-mounting the log directory)
- [This section](kube-selfpaced.yml.html#toc-centralized-logging) shows how to do that with [Fluentd](https://docs.fluentd.org/v0.12/articles/kubernetes-fluentd) and the EFK stack
---
## Metrics
- The kubelet embeds [cAdvisor](https://github.com/google/cadvisor), which exposes container metrics
(cAdvisor might be separated in the future for more flexibility)
- It is a good idea to start with [Prometheus](https://prometheus.io/)
(even if you end up using something else)
- Starting from Kubernetes 1.8, we can use the [Metrics API](https://kubernetes.io/docs/tasks/debug-application-cluster/core-metrics-pipeline/)
- [Heapster](https://github.com/kubernetes/heapster) was a popular add-on
(but is being [deprecated](https://github.com/kubernetes/heapster/blob/master/docs/deprecation.md) starting with Kubernetes 1.11)
---
## Managing the configuration of our applications
- Two constructs are particularly useful: secrets and config maps
- They allow to expose arbitrary information to our containers
- **Avoid** storing configuration in container images
(There are some exceptions to that rule, but it's generally a Bad Idea)
- **Never** store sensitive information in container images
(It's the container equivalent of the password on a post-it note on your screen)
- [This section](kube-selfpaced.yml.html#toc-managing-configuration) shows how to manage app config with config maps (among others)
---
## Managing stack deployments
- The best deployment tool will vary, depending on:

View File

@@ -1,82 +0,0 @@
title: |
Deploying and Scaling Microservices
with Kubernetes
#chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
#chat: "[Gitter](https://gitter.im/jpetazzo/workshop-yyyymmdd-city)"
chat: "In person!"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
exclude:
- self-paced
chapters:
- shared/title.md
- logistics.md
- k8s/intro.md
- shared/about-slides.md
- shared/toc.md
- - shared/prereqs.md
- shared/connecting.md
- k8s/versions-k8s.md
- shared/sampleapp.md
#- shared/composescale.md
#- shared/hastyconclusions.md
- shared/composedown.md
- k8s/concepts-k8s.md
- shared/declarative.md
- k8s/declarative.md
- k8s/kubenet.md
- - k8s/kubectlget.md
- k8s/setup-k8s.md
- k8s/kubectlrun.md
- k8s/deploymentslideshow.md
- k8s/kubectlexpose.md
- - k8s/shippingimages.md
#- k8s/buildshiprun-selfhosted.md
- k8s/buildshiprun-dockerhub.md
- k8s/ourapponkube.md
#- k8s/kubectlproxy.md
#- k8s/localkubeconfig.md
#- k8s/accessinternal.md
- k8s/dashboard.md
#- k8s/kubectlscale.md
- k8s/scalingdockercoins.md
- shared/hastyconclusions.md
- k8s/daemonset.md
- - k8s/rollout.md
#- k8s/record.md
- k8s/namespaces.md
#- k8s/kustomize.md
#- k8s/helm.md
#- k8s/create-chart.md
# - k8s/healthchecks.md
# - k8s/healthchecks-more.md
- k8s/logs-cli.md
- k8s/logs-centralized.md
#- k8s/netpol.md
#- k8s/authn-authz.md
#- k8s/csr-api.md
#- k8s/openid-connect.md
#- k8s/podsecuritypolicy.md
#- k8s/ingress.md
#- k8s/gitworkflows.md
- k8s/prometheus.md
#- - k8s/volumes.md
# - k8s/build-with-docker.md
# - k8s/build-with-kaniko.md
# - k8s/configuration.md
#- - k8s/owners-and-dependents.md
# - k8s/extending-api.md
# - k8s/operators.md
# - k8s/operators-design.md
# - k8s/statefulsets.md
#- k8s/local-persistent-volumes.md
#- k8s/staticpods.md
# - k8s/portworx.md
- - k8s/whatsnext.md
- k8s/links.md
- shared/thankyou.md

View File

@@ -1,67 +0,0 @@
title: |
Kubernetes 101
#chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
#chat: "[Gitter](https://gitter.im/jpetazzo/training-20180413-paris)"
chat: "In person!"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
exclude:
- self-paced
chapters:
- shared/title.md
#- logistics.md
# Bridget-specific; others use logistics.md
- logistics-bridget.md
- k8s/intro.md
- shared/about-slides.md
- shared/toc.md
- - shared/prereqs.md
- shared/connecting.md
- k8s/versions-k8s.md
- shared/sampleapp.md
# Bridget doesn't go into as much depth with compose
#- shared/composescale.md
#- shared/hastyconclusions.md
- shared/composedown.md
- k8s/concepts-k8s.md
- shared/declarative.md
- k8s/declarative.md
- k8s/kubenet.md
- k8s/kubectlget.md
- k8s/setup-k8s.md
- - k8s/kubectlrun.md
- k8s/deploymentslideshow.md
- k8s/kubectlexpose.md
- k8s/shippingimages.md
#- k8s/buildshiprun-selfhosted.md
- k8s/buildshiprun-dockerhub.md
- k8s/ourapponkube.md
#- k8s/kubectlproxy.md
#- k8s/localkubeconfig.md
#- k8s/accessinternal.md
- - k8s/dashboard.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.md
- k8s/create-chart.md
#- k8s/kustomize.md
#- k8s/netpol.md
- k8s/whatsnext.md
# - k8s/links.md
# Bridget-specific
- k8s/links-bridget.md
- shared/thankyou.md

View File

@@ -1,82 +0,0 @@
title: |
Deploying and Scaling Microservices
with Docker and Kubernetes
chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
#chat: "[Gitter](https://gitter.im/jpetazzo/workshop-yyyymmdd-city)"
gitrepo: github.com/jpetazzo/container.training
slides: http://container.training/
exclude:
- in-person
chapters:
- shared/title.md
#- logistics.md
- k8s/intro.md
- shared/about-slides.md
- shared/toc.md
- - shared/prereqs.md
- shared/connecting.md
- k8s/versions-k8s.md
- shared/sampleapp.md
- shared/composescale.md
- shared/hastyconclusions.md
- shared/composedown.md
- k8s/concepts-k8s.md
- shared/declarative.md
- k8s/declarative.md
- - k8s/kubenet.md
- k8s/kubectlget.md
- k8s/setup-k8s.md
- k8s/kubectlrun.md
- k8s/deploymentslideshow.md
- - k8s/kubectlexpose.md
- k8s/shippingimages.md
- k8s/buildshiprun-selfhosted.md
- k8s/buildshiprun-dockerhub.md
- k8s/ourapponkube.md
- k8s/kubectlproxy.md
- k8s/localkubeconfig.md
- k8s/accessinternal.md
- k8s/dashboard.md
- - k8s/kubectlscale.md
# - k8s/scalingdockercoins.md
# - shared/hastyconclusions.md
- k8s/daemonset.md
- k8s/rollout.md
- k8s/record.md
- k8s/namespaces.md
- - k8s/kustomize.md
- k8s/helm.md
- k8s/create-chart.md
- k8s/healthchecks.md
- k8s/healthchecks-more.md
- k8s/logs-cli.md
- k8s/logs-centralized.md
- - k8s/netpol.md
- k8s/authn-authz.md
- k8s/csr-api.md
- k8s/openid-connect.md
- k8s/podsecuritypolicy.md
- - k8s/ingress.md
- k8s/gitworkflows.md
- k8s/prometheus.md
- - k8s/volumes.md
- k8s/build-with-docker.md
- k8s/build-with-kaniko.md
- k8s/configuration.md
- - k8s/owners-and-dependents.md
- k8s/extending-api.md
- k8s/operators.md
- k8s/operators-design.md
- - k8s/statefulsets.md
- k8s/local-persistent-volumes.md
- k8s/portworx.md
- k8s/staticpods.md
- - k8s/whatsnext.md
- k8s/links.md
- shared/thankyou.md

View File

@@ -2,13 +2,15 @@
- Hello! We are:
- .emoji[👷🏻‍♀️] AJ ([@s0ulshake](https://twitter.com/s0ulshake), Tiny Shell Script)
- .emoji[👷🏻‍♀️] AJ ([@s0ulshake](https://twitter.com/s0ulshake), Tiny Shell Script LLC)
- .emoji[🐳] Jérôme ([@jpetazzo](https://twitter.com/jpetazzo), Ardan Labs)
- .emoji[🐳] Jérôme ([@jpetazzo](https://twitter.com/jpetazzo), Ardan Labs LLC)
- The workshop will run from 9am to 5pm
- The training will run from 9am to 5pm
- There will be a lunch break (and coffee breaks!)
- There will be a lunch break
(And coffee breaks!)
- Feel free to interrupt for questions at any time

View File

@@ -1,6 +0,0 @@
<p><a href="two.yml.html">Monday / Tuesday (Kubernetes Developer Training)</a></p>
<p><a href="three.yml.html">Wednesday / Thursday / Friday (Containers, Docker, Kubernetes)</a></p>

61
slides/sfsf.yml Normal file
View File

@@ -0,0 +1,61 @@
title: |
Kubernetes
Advanced
Training
#chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
chat: "[Gitter](https://gitter.im/jpetazzo/training-20190613-sanfrancisco)"
#chat: "In person!"
gitrepo: github.com/jpetazzo/container.training
slides: http://sfsf-2019-06.container.training/
exclude:
- self-paced
chapters:
- shared/title.md
- logistics.md
- k8s/intro.md
- shared/about-slides.md
- shared/toc.md
# DAY 1
- - k8s/prereqs-admin.md
- k8s/architecture.md
- k8s/deploymentslideshow.md
- k8s/dmuc.md
- - k8s/multinode.md
- k8s/cni.md
- k8s/apilb.md
- - k8s/kubercoins.md
- k8s/logs-cli.md
- k8s/logs-centralized.md
- k8s/healthchecks.md
- k8s/healthchecks-more.md
- - k8s/volumes.md
- k8s/configuration.md
- k8s/statefulsets.md
- k8s/local-persistent-volumes.md
- k8s/portworx.md
# DAY 2
- - k8s/namespaces.md
- k8s/kustomize.md
- k8s/helm.md
- k8s/create-chart.md
- k8s/create-more-charts.md
- - k8s/extending-api.md
- k8s/operators.md
- k8s/operators-design.md
- k8s/owners-and-dependents.md
- - k8s/authn-authz.md
- k8s/control-plane-auth.md
- k8s/prometheus.md
- - k8s/resource-limits.md
- k8s/metrics-server.md
- k8s/cluster-sizing.md
- k8s/horizontal-pod-autoscaler.md
# CONCLUSION
- - k8s/lastwords-admin.md
- k8s/links.md
- shared/thankyou.md

View File

@@ -11,6 +11,5 @@ class: title, in-person
@@TITLE@@<br/></br>
.footnote[
**Slides[:](https://www.youtube.com/watch?v=h16zyxiwDLY)
@@SLIDES@@**
**Slides: @@SLIDES@@**
]

View File

@@ -1,135 +0,0 @@
title: |
Containers,
Docker,
Kubernetes
chat: "[Gitter](https://gitter.im/jpetazzo/training-20190717-copenhagen)"
gitrepo: github.com/jpetazzo/container.training
slides: http://maersk-2019-07.container.training/
exclude:
- self-paced
chapters:
- shared/title.md
- logistics.md
- k8s/intro.md
- shared/about-slides.md
- shared/toc.md
# DAY 1
- - containers/Training_Environment.md
- containers/First_Containers.md
- containers/Background_Containers.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
- - containers/Multi_Stage_Builds.md
- containers/Dockerfile_Tips.md
- containers/Exercise_Dockerfile_Advanced.md
- containers/Naming_And_Inspecting.md
- containers/Getting_Inside.md
- - containers/Container_Networking_Basics.md
- containers/Network_Drivers.md
- containers/Container_Network_Model.md
- containers/Ambassadors.md
# DAY 2
- - containers/Local_Development_Workflow.md
- containers/Working_With_Volumes.md
- containers/Compose_For_Dev_Stacks.md
- containers/Exercise_Composefile.md
- - containers/Application_Configuration.md
- containers/Orchestration_Overview.md
- |
# From Docker to Kubernetes
- We are now going to run a demo app made of multiple containers
- We will start by running it on one node, with Compose
- Then we will deploy that application on a Kubernetes cluster
- We will identify performance bottlenecks and scale out that app
(and learn Kubernetes in the process)
---
## Our new environment
- Since a 1-node cluster isn't fun, we will switch to a new environment!
- This environment is a 4-node Kubernetes cluster
- Also, from now on, demos and labs are identified with these gray boxes
.exercise[
- You should run this command:
```bash
echo Hello world
```
]
- shared/connecting.md
- k8s/versions-k8s.md
- - shared/sampleapp.md
- shared/composedown.md
- k8s/concepts-k8s.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-dockerhub.md
- k8s/ourapponkube.md
- k8s/scalingdockercoins.md
- shared/hastyconclusions.md
# DAY 3
- - k8s/namespaces.md
- k8s/daemonset.md
- |
# Exercise — from Compose to Kubernetes
Let's run the wordsmith app on Kubernetes!
The code is at: https://github.com/jpetazzo/wordsmith
- - k8s/rollout.md
- k8s/healthchecks.md
- k8s/healthchecks-more.md
- k8s/ingress.md
- |
# Exercise — creating an Ingress
Add an Ingress resource for the wordsmith app.
- - k8s/setup-k8s.md
- k8s/dashboard.md
- k8s/volumes.md
- k8s/configuration.md
- - k8s/statefulsets.md
- k8s/local-persistent-volumes.md
- k8s/portworx.md
- - k8s/whatsnext.md
- k8s/links.md
- shared/thankyou.md
# EXTRA
- - |
# (Extra material)
- k8s/localkubeconfig.md
- k8s/accessinternal.md
- k8s/kustomize.md
- k8s/helm.md
- k8s/create-chart.md
- k8s/create-more-charts.md
- k8s/authn-authz.md
- k8s/netpol.md

View File

@@ -1,84 +0,0 @@
title: |
Kubernetes Developer Training
chat: "[Gitter](https://gitter.im/jpetazzo/training-20190715-copenhagen)"
gitrepo: github.com/jpetazzo/container.training
slides: http://maersk-2019-07.container.training/
exclude:
- self-paced
chapters:
- shared/title.md
- logistics.md
- k8s/intro.md
- shared/about-slides.md
- shared/toc.md
# DAY 1
- - shared/prereqs.md
- shared/connecting.md
- k8s/versions-k8s.md
- shared/sampleapp.md
#- shared/composescale.md
#- shared/hastyconclusions.md
- shared/composedown.md
- k8s/concepts-k8s.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/setup-k8s.md
- k8s/dashboard.md
#- k8s/kubectlscale.md
- k8s/scalingdockercoins.md
- shared/hastyconclusions.md
- k8s/daemonset.md
- - k8s/rollout.md
- k8s/record.md
- k8s/logs-centralized.md
- k8s/ingress.md
# DAY 2
- - k8s/namespaces.md
- k8s/volumes.md
#- k8s/build-with-docker.md
#- k8s/build-with-kaniko.md
- k8s/configuration.md
- k8s/kustomize.md
- - k8s/helm.md
- k8s/create-chart.md
- k8s/create-more-charts.md
- k8s/authn-authz.md
- - k8s/netpol.md
- k8s/prometheus.md
- k8s/statefulsets.md
- - k8s/local-persistent-volumes.md
- k8s/portworx.md
- - k8s/whatsnext.md
- k8s/links.md
- shared/thankyou.md
- - |
# (Extra material)
- k8s/healthchecks.md
- k8s/healthchecks-more.md
- k8s/kubectlproxy.md
- k8s/localkubeconfig.md
- k8s/accessinternal.md
- k8s/extending-api.md
- k8s/operators.md
- k8s/operators-design.md
- k8s/owners-and-dependents.md
#- k8s/staticpods.md
#- k8s/gitworkflows.md
#- k8s/csr-api.md
#- k8s/openid-connect.md
- k8s/podsecuritypolicy.md