mirror of
https://github.com/jpetazzo/container.training.git
synced 2026-03-06 11:20:48 +00:00
Compare commits
13 Commits
maersk-201
...
sfsf-2019-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08fa37dace | ||
|
|
807028cbf3 | ||
|
|
dfde597cb9 | ||
|
|
96419c6baf | ||
|
|
12da011f21 | ||
|
|
fa1637fb7e | ||
|
|
fbe2251e21 | ||
|
|
b4faf10581 | ||
|
|
0ef9c87f97 | ||
|
|
addd14582a | ||
|
|
5299fbaab5 | ||
|
|
398ff5ee4f | ||
|
|
b883e6d557 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
--
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
]
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
]
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Highly available Persistent Volumes
|
||||
# Highly available Persistent Volumes (extra material)
|
||||
|
||||
- How can we achieve true durability?
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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®ions=all
|
||||
- Select a [region](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=kubernetes-service\®ions=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
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -80,8 +80,6 @@
|
||||
|
||||
- Docker Enterprise Edition
|
||||
|
||||
- [AKS Engine](https://github.com/Azure/aks-engine)
|
||||
|
||||
- Pivotal Container Service (PKS)
|
||||
|
||||
- Tectonic by CoreOS
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
61
slides/sfsf.yml
Normal 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
|
||||
@@ -11,6 +11,5 @@ class: title, in-person
|
||||
@@TITLE@@<br/></br>
|
||||
|
||||
.footnote[
|
||||
**Slides[:](https://www.youtube.com/watch?v=h16zyxiwDLY)
|
||||
@@SLIDES@@**
|
||||
**Slides: @@SLIDES@@**
|
||||
]
|
||||
|
||||
135
slides/three.yml
135
slides/three.yml
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user