merge master

This commit is contained in:
Jerome Petazzoni
2019-08-14 04:30:49 -05:00
27 changed files with 820 additions and 308 deletions

View File

@@ -76,6 +76,78 @@ 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

@@ -24,6 +24,33 @@
lang: fr
attend: https://enix.io/fr/services/formation/deployer-ses-applications-avec-kubernetes/
- date: 2019-08-27
country: tr
city: Izmir
event: HacknBreak
speaker: gurayyildirim
title: Deploying and scaling applications with Kubernetes (in Turkish)
lang: tr
attend: https://hacknbreak.com
- date: 2019-08-26
country: tr
city: Izmir
event: HacknBreak
speaker: gurayyildirim
title: Container Orchestration with Docker and Swarm (in Turkish)
lang: tr
attend: https://hacknbreak.com
- date: 2019-08-25
country: tr
city: Izmir
event: HackBreak
speaker: gurayyildirim
title: Introduction to Docker and Containers (in Turkish)
lang: tr
attend: https://hacknbreak.com
- date: 2019-07-16
country: us
city: Portland, OR
@@ -31,6 +58,7 @@
speaker: bridgetkromhout
title: "Kubernetes 201: Production tooling"
attend: https://conferences.oreilly.com/oscon/oscon-or/public/schedule/detail/76390
slides: https://oscon2019.container.training
- date: 2019-06-17
country: ca

View File

@@ -4,15 +4,29 @@
- We want one (and exactly one) instance of `rng` per node
- What if we just scale up `deploy/rng` to the number of nodes?
- We *do not want* two instances of `rng` on the same node
- nothing guarantees that the `rng` containers will be distributed evenly
- We will do that with a *daemon set*
- if we add nodes later, they will not automatically run a copy of `rng`
---
- if we remove (or reboot) a node, one `rng` container will restart elsewhere
## Why not a deployment?
- Instead of a `deployment`, we will use a `daemonset`
- Can't we just do `kubectl scale deployment rng --replicas=...`?
--
- Nothing guarantees that the `rng` containers will be distributed evenly
- If we add nodes later, they will not automatically run a copy of `rng`
- If we remove (or reboot) a node, one `rng` container will restart elsewhere
(and we will end up with two instances `rng` on the same node)
- By contrast, a daemon set will start one pod per node and keep it that way
(as nodes are added or removed)
---

View File

@@ -87,7 +87,7 @@
- Clone the Flux repository:
```
git clone https://github.com/weaveworks/flux
git clone https://github.com/fluxcd/flux
```
- Edit `deploy/flux-deployment.yaml`

View File

@@ -415,7 +415,7 @@ This is normal: we haven't provided any ingress rule yet.
Here is a minimal host-based ingress resource:
```yaml
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: cheddar
@@ -523,4 +523,4 @@ spec:
- This should eventually stabilize
(remember that ingresses are currently `apiVersion: extensions/v1beta1`)
(remember that ingresses are currently `apiVersion: networking.k8s.io/v1beta1`)

View File

@@ -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.15.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.15.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.15.2/bin/windows/amd64/kubectl.exe)
- On Linux and macOS, make the binary executable with `chmod +x kubectl`

View File

@@ -32,7 +32,7 @@
- must be able to anticipate all the events that might happen
- design will be better only to the extend of what we anticipated
- design will be better only to the extent of what we anticipated
- hard to anticipate if we don't have production experience
@@ -187,6 +187,8 @@ class: extra-details
[Intro talk](https://www.youtube.com/watch?v=8k_ayO1VRXE)
|
[Deep dive talk](https://www.youtube.com/watch?v=fu7ecA2rXmc)
|
[Simple example](https://medium.com/faun/writing-your-first-kubernetes-operator-8f3df4453234)
- Zalando Kubernetes Operator Pythonic Framework (KOPF)

View File

@@ -302,7 +302,7 @@ Now, the StorageClass should have `(default)` next to its name.
- Retrieve the NodePort that was allocated:
```bash
kubectl get svc cerebreo-es
kubectl get svc cerebro-es
```
- Connect to that port with a browser
@@ -386,4 +386,6 @@ We should see at least one index being created in cerebro.
- What if we want different images or parameters for the different nodes?
*Operators can be very powerful, iff we know exactly the scenarios that they can handle.*
*Operators can be very powerful.
<br/>
But we need to know exactly the scenarios that they can handle.*

169
slides/k8s/record.md Normal file
View File

@@ -0,0 +1,169 @@
# 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

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

View File

@@ -345,7 +345,7 @@ spec:
we figure out the minimal command-line to run our Consul cluster.*
```
consul agent -data=dir=/consul/data -client=0.0.0.0 -server -ui \
consul agent -data-dir=/consul/data -client=0.0.0.0 -server -ui \
-bootstrap-expect=3 \
-retry-join=`X.X.X.X` \
-retry-join=`Y.Y.Y.Y`

View File

@@ -1,7 +1,7 @@
## Versions installed
- Kubernetes 1.15.0
- Docker Engine 18.09.7
- Kubernetes 1.15.2
- Docker Engine 19.03.1
- Docker Compose 1.24.1
<!-- ##VERSION## -->

View File

@@ -1,5 +1,6 @@
title: |
Kubernetes Training
Deploying and Scaling Microservices
with Kubernetes
#chat: "[Slack](https://dockercommunity.slack.com/messages/C7GKACWDV)"
#chat: "[Gitter](https://gitter.im/jpetazzo/workshop-yyyymmdd-city)"
@@ -7,7 +8,7 @@ chat: "In person!"
gitrepo: github.com/jpetazzo/container.training
slides: http://kube-2019-08.container.training/
slides: http://container.training/
exclude:
- self-paced
@@ -18,8 +19,8 @@ chapters:
- k8s/intro.md
- shared/about-slides.md
- shared/toc.md
# DAY 1
- - shared/prereqs.md
-
- shared/prereqs.md
- shared/connecting.md
- k8s/versions-k8s.md
- shared/sampleapp.md
@@ -28,7 +29,8 @@ chapters:
- shared/composedown.md
- k8s/concepts-k8s.md
- k8s/kubectlget.md
- - k8s/kubectlrun.md
-
- k8s/kubectlrun.md
- k8s/logs-cli.md
- shared/declarative.md
- k8s/declarative.md
@@ -39,50 +41,51 @@ chapters:
#- k8s/buildshiprun-selfhosted.md
- k8s/buildshiprun-dockerhub.md
- k8s/ourapponkube.md
- - k8s/setup-k8s.md
-
- k8s/kubectlproxy.md
- k8s/localkubeconfig.md
- k8s/accessinternal.md
- k8s/setup-k8s.md
- k8s/dashboard.md
#- k8s/kubectlscale.md
- k8s/scalingdockercoins.md
- shared/hastyconclusions.md
- k8s/daemonset.md
- - k8s/rollout.md
-
- k8s/rollout.md
- k8s/healthchecks.md
- k8s/healthchecks-more.md
- k8s/record.md
-
- k8s/namespaces.md
- k8s/ingress.md
# DAY 2
- - k8s/namespaces.md
- k8s/netpol.md
- k8s/authn-authz.md
- - k8s/logs-centralized.md
- k8s/prometheus.md
- - k8s/volumes.md
#- k8s/build-with-docker.md
#- k8s/build-with-kaniko.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/kubectlproxy.md
- k8s/localkubeconfig.md
- k8s/accessinternal.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
- - |
# (Extra material)
- k8s/csr-api.md
- k8s/openid-connect.md
- k8s/podsecuritypolicy.md
#- k8s/gitworkflows.md
-
- k8s/netpol.md
- k8s/authn-authz.md
#- k8s/csr-api.md
#- k8s/openid-connect.md
#- k8s/podsecuritypolicy.md
-
- k8s/volumes.md
#- k8s/build-with-docker.md
#- k8s/build-with-kaniko.md
- k8s/configuration.md
- k8s/logs-centralized.md
- k8s/prometheus.md
-
- k8s/statefulsets.md
- k8s/local-persistent-volumes.md
- k8s/portworx.md
#- k8s/extending-api.md
#- k8s/operators.md
#- k8s/operators-design.md
#- k8s/staticpods.md
#- k8s/owners-and-dependents.md
- k8s/staticpods.md
#- k8s/gitworkflows.md
-
- k8s/whatsnext.md
- k8s/links.md
- shared/thankyou.md