mirror of
https://github.com/jpetazzo/container.training.git
synced 2026-07-19 12:59:24 +00:00
Merge branch 'master' into sfsf-2019-06
This commit is contained in:
@@ -86,7 +86,7 @@ like Windows, macOS, Solaris, FreeBSD ...
|
||||
|
||||
* No notion of image (container filesystems have to be managed manually).
|
||||
|
||||
* Networking has to be setup manually.
|
||||
* Networking has to be set up manually.
|
||||
|
||||
---
|
||||
|
||||
@@ -112,7 +112,7 @@ like Windows, macOS, Solaris, FreeBSD ...
|
||||
|
||||
* Strong emphasis on security (through privilege separation).
|
||||
|
||||
* Networking has to be setup separately (e.g. through CNI plugins).
|
||||
* Networking has to be set up separately (e.g. through CNI plugins).
|
||||
|
||||
* Partial image management (pull, but no push).
|
||||
|
||||
@@ -152,7 +152,7 @@ We're not aware of anyone using it directly (i.e. outside of Kubernetes).
|
||||
|
||||
* Basic image support (tar archives and raw disk images).
|
||||
|
||||
* Network has to be setup manually.
|
||||
* Network has to be set up manually.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
|
||||
- Configuring routing tables in the cloud network (specific to GCE)
|
||||
|
||||
- Updating node labels to indicate region, zone, instance type ...
|
||||
- Updating node labels to indicate region, zone, instance type...
|
||||
|
||||
- Obtain node name, internal and external addresses from cloud metadata service
|
||||
|
||||
- Deleting nodes from Kubernetes when they're deleted in the cloud
|
||||
|
||||
- Managing *some* volumes (e.g. ELBs, AzureDisks ...)
|
||||
- Managing *some* volumes (e.g. ELBs, AzureDisks...)
|
||||
|
||||
(Eventually, volumes will be managed by the CSI)
|
||||
(Eventually, volumes will be managed by the Container Storage Interface)
|
||||
|
||||
---
|
||||
|
||||
@@ -83,7 +83,7 @@ The list includes the following providers:
|
||||
|
||||
## Audience questions
|
||||
|
||||
- What kind of clouds are you using / planning to use?
|
||||
- What kind of clouds are you using/planning to use?
|
||||
|
||||
- What kind of details would you like to see in this section?
|
||||
|
||||
@@ -105,7 +105,7 @@ The list includes the following providers:
|
||||
|
||||
- When using managed clusters, this is done automatically
|
||||
|
||||
- There is very little documentation to write the configuration file
|
||||
- There is very little documentation on writing the configuration file
|
||||
|
||||
(except for OpenStack)
|
||||
|
||||
@@ -123,7 +123,7 @@ The list includes the following providers:
|
||||
|
||||
- To get these addresses, the node needs to communicate with the control plane
|
||||
|
||||
- ... Which means joining the cluster
|
||||
- ...Which means joining the cluster
|
||||
|
||||
(The problem didn't occur when cloud-specific code was running in kubelet: kubelet could obtain the required information directly from the cloud provider's metadata service.)
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
- error recovery (human or process has altered or corrupted data)
|
||||
|
||||
- cloning environments (for testing, validation ...)
|
||||
- cloning environments (for testing, validation...)
|
||||
|
||||
- Let's see the strategies and tools available with Kubernetes!
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
(it gives us replication primitives)
|
||||
|
||||
- Kubernetes helps us to clone / replicate environments
|
||||
- Kubernetes helps us to clone/replicate environments
|
||||
|
||||
(all resources can be described with manifests)
|
||||
|
||||
- Kubernetes *does not* help us with error recovery
|
||||
|
||||
- We still need to backup / snapshot our data:
|
||||
- We still need to back up/snapshot our data:
|
||||
|
||||
- with database backups (mysqldump, pgdump, etc.)
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
- If our deployment system isn't fully automated, it should at least be documented
|
||||
|
||||
- Litmus test: how long does it take to deploy a cluster ...
|
||||
- Litmus test: how long does it take to deploy a cluster...
|
||||
|
||||
- for a senior engineer?
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
- Does it require external intervention?
|
||||
|
||||
(e.g. provisioning servers, signing TLS certs ...)
|
||||
(e.g. provisioning servers, signing TLS certs...)
|
||||
|
||||
---
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
|
||||
- For real applications: add resources (as YAML files)
|
||||
|
||||
- For applications deployed multiple times: Helm, Kustomize ...
|
||||
- For applications deployed multiple times: Helm, Kustomize...
|
||||
|
||||
(staging and production count as "multiple times")
|
||||
|
||||
|
||||
@@ -287,8 +287,8 @@
|
||||
- Download the configuration on each node, and upgrade kubelet:
|
||||
```bash
|
||||
for N in 1 2 3; do
|
||||
ssh node$N sudo kubeadm upgrade node config --kubelet-version v1.14.2
|
||||
ssh node $N sudo apt install kubelet=1.14.2-00
|
||||
ssh test$N sudo kubeadm upgrade node config --kubelet-version v1.14.2
|
||||
ssh test$N sudo apt install kubelet=1.14.2-00
|
||||
done
|
||||
```
|
||||
]
|
||||
|
||||
@@ -276,7 +276,7 @@ class: extra-details
|
||||
|
||||
- The address of the API server will be `http://A.B.C.D:8080`
|
||||
|
||||
(where `A.B.C.D` is the address of `kuberouter1`, running the control plane)
|
||||
(where `A.B.C.D` is the public address of `kuberouter1`, running the control plane)
|
||||
|
||||
.exercise[
|
||||
|
||||
@@ -453,7 +453,7 @@ We should see the local pod CIDR connected to `kube-bridge`, and the other nodes
|
||||
|
||||
- Or try to exec into one of the kube-router pods:
|
||||
```bash
|
||||
kubectl -n kube-system exec kuber-router-xxxxx bash
|
||||
kubectl -n kube-system exec kube-router-xxxxx bash
|
||||
```
|
||||
|
||||
]
|
||||
@@ -575,7 +575,7 @@ done
|
||||
|
||||
## Starting the route reflector
|
||||
|
||||
- Only do this if you are doing this on your own
|
||||
- Only do this slide if you are doing this on your own
|
||||
|
||||
- There is a Compose file in the `compose/frr-route-reflector` directory
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ This is what I do if I want to obtain a certificate.
|
||||
|
||||
2. Create a Certificate Signing Request (CSR).
|
||||
|
||||
(The CSR contains the identity that I claim and an expiration date.)
|
||||
(The CSR contains the identity that I claim and a public key.)
|
||||
|
||||
3. Send that CSR to the Certificate Authority (CA).
|
||||
|
||||
@@ -231,7 +231,7 @@ For a user named `jean.doe`, we will have:
|
||||
- Let's use OpenSSL; it's not the best one, but it's installed everywhere
|
||||
|
||||
(many people prefer cfssl, easyrsa, or other tools; that's fine too!)
|
||||
|
||||
|
||||
.exercise[
|
||||
|
||||
- Generate the key and certificate signing request:
|
||||
@@ -244,7 +244,7 @@ For a user named `jean.doe`, we will have:
|
||||
|
||||
The command above generates:
|
||||
|
||||
- a 2048-bit RSA key, without DES encryption, stored in key.pem
|
||||
- a 2048-bit RSA key, without encryption, stored in key.pem
|
||||
- a CSR for the name `jean.doe` in group `devs`
|
||||
|
||||
---
|
||||
@@ -345,7 +345,7 @@ The command above generates:
|
||||
kctx -
|
||||
```
|
||||
|
||||
- Retrieve the certificate from the CSR:
|
||||
- Retrieve the updated CSR object and extract the certificate:
|
||||
```bash
|
||||
kubectl get csr users:jean.doe \
|
||||
-o jsonpath={.status.certificate} \
|
||||
|
||||
@@ -117,7 +117,7 @@ Examples:
|
||||
|
||||
## Admission controllers
|
||||
|
||||
- When a Pod is created, it is associated to a ServiceAccount
|
||||
- When a Pod is created, it is associated with a ServiceAccount
|
||||
|
||||
(even if we did not specify one explicitly)
|
||||
|
||||
@@ -163,7 +163,7 @@ class: pic
|
||||
|
||||
- These webhooks can be *validating* or *mutating*
|
||||
|
||||
- Webhooks can be setup dynamically (without restarting the API server)
|
||||
- Webhooks can be set up dynamically (without restarting the API server)
|
||||
|
||||
- To setup a dynamic admission webhook, we create a special resource:
|
||||
|
||||
@@ -171,7 +171,7 @@ class: pic
|
||||
|
||||
- These resources are created and managed like other resources
|
||||
|
||||
(i.e. `kubectl create`, `kubectl get` ...)
|
||||
(i.e. `kubectl create`, `kubectl get`...)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
|
||||
- Horizontal scaling = changing the number of replicas
|
||||
|
||||
(adding / removing pods)
|
||||
(adding/removing pods)
|
||||
|
||||
- Vertical scaling = changing the size of individual replicas
|
||||
|
||||
(increasing / reducing CPU and RAM per pod)
|
||||
(increasing/reducing CPU and RAM per pod)
|
||||
|
||||
- Cluster scaling = changing the size of the cluster
|
||||
|
||||
(adding / removing nodes)
|
||||
(adding/removing nodes)
|
||||
|
||||
---
|
||||
|
||||
@@ -50,9 +50,9 @@
|
||||
|
||||
- The latter actually makes a lot of sense:
|
||||
|
||||
- if a Pod doesn't have a CPU request, it might be using 10% of CPU ...
|
||||
- if a Pod doesn't have a CPU request, it might be using 10% of CPU...
|
||||
|
||||
- ... but only because there is no CPU time available!
|
||||
- ...but only because there is no CPU time available!
|
||||
|
||||
- this makes sure that we won't add pods to nodes that are already resource-starved
|
||||
|
||||
@@ -238,7 +238,7 @@ This can also be set with `--cpu-percent=`.
|
||||
|
||||
- Kubernetes doesn't implement any of these API groups
|
||||
|
||||
- Using these metrics requires to [register additional APIs](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis)
|
||||
- Using these metrics requires [registering additional APIs](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis)
|
||||
|
||||
- The metrics provided by metrics server are standard; everything else is custom
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
- Acknowledge that a lot of tasks are outsourced
|
||||
|
||||
(e.g. if we add "buy / rack / provision machines" in that list)
|
||||
(e.g. if we add "buy/rack/provision machines" in that list)
|
||||
|
||||
---
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
|
||||
(YAML, Helm charts, Kustomize ...)
|
||||
|
||||
- Team "run" adjusts some parameters and monitors the application
|
||||
- Team "run" adjusts some parameters and monitors the application
|
||||
|
||||
✔️ parity between dev and prod environments
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
|
||||
- do we reward on-call duty without encouraging hero syndrome?
|
||||
|
||||
- do we give resources (time, money) to people to learn?
|
||||
- do we give people resources (time, money) to learn?
|
||||
|
||||
---
|
||||
|
||||
@@ -183,9 +183,9 @@ are a few tools that can help us.*
|
||||
|
||||
- If cloud: public vs. private
|
||||
|
||||
- Which vendor / distribution to pick?
|
||||
- Which vendor/distribution to pick?
|
||||
|
||||
- Which versions / features to enable?
|
||||
- Which versions/features to enable?
|
||||
|
||||
---
|
||||
|
||||
@@ -205,6 +205,6 @@ are a few tools that can help us.*
|
||||
|
||||
- Transfer knowledge
|
||||
|
||||
(make sure everyone is on the same page / same level)
|
||||
(make sure everyone is on the same page/level)
|
||||
|
||||
- Iterate!
|
||||
|
||||
@@ -96,7 +96,7 @@ class: extra-details
|
||||
|
||||
- We need to generate a `kubeconfig` file for kubelet
|
||||
|
||||
- This time, we need to put the IP address of `kubenet1`
|
||||
- This time, we need to put the public IP address of `kubenet1`
|
||||
|
||||
(instead of `localhost` or `127.0.0.1`)
|
||||
|
||||
|
||||
@@ -307,7 +307,7 @@ This policy selects all pods in the current namespace.
|
||||
|
||||
It allows traffic only from pods in the current namespace.
|
||||
|
||||
(An empty `podSelector` means "all pods".)
|
||||
(An empty `podSelector` means "all pods.")
|
||||
|
||||
```yaml
|
||||
kind: NetworkPolicy
|
||||
@@ -329,7 +329,7 @@ This policy selects all pods with label `app=webui`.
|
||||
|
||||
It allows traffic from any source.
|
||||
|
||||
(An empty `from` fields means "all sources".)
|
||||
(An empty `from` field means "all sources.")
|
||||
|
||||
```yaml
|
||||
kind: NetworkPolicy
|
||||
@@ -412,7 +412,7 @@ troubleshoot easily, without having to poke holes in our firewall.
|
||||
|
||||
- If we block access to the control plane, we might disrupt legitimate code
|
||||
|
||||
- ... Without necessarily improving security
|
||||
- ...Without necessarily improving security
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
kubectl create deployment web --image=nginx
|
||||
```
|
||||
|
||||
- Confirm that the Deployment, ReplicaSet, and Pod exist, and Pod is running:
|
||||
- Confirm that the Deployment, ReplicaSet, and Pod exist, and that the Pod is running:
|
||||
```bash
|
||||
kubectl get all
|
||||
```
|
||||
@@ -163,7 +163,7 @@
|
||||
- If we create a Pod directly, it can use a PSP to which *we* have access
|
||||
|
||||
- If the Pod is created by e.g. a ReplicaSet or DaemonSet, it's different:
|
||||
|
||||
|
||||
- the ReplicaSet / DaemonSet controllers don't have access to *our* policies
|
||||
|
||||
- therefore, we need to give access to the PSP to the Pod's ServiceAccount
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
- Then we will create a couple of PodSecurityPolicies
|
||||
|
||||
- ... And associated ClusterRoles (giving `use` access to the policies)
|
||||
- ...And associated ClusterRoles (giving `use` access to the policies)
|
||||
|
||||
- Then we will create RoleBindings to grant these roles to ServiceAccounts
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
|
||||
- Have a look at the static pods:
|
||||
```bash
|
||||
ls -l /etc/kubernetes/manifest
|
||||
ls -l /etc/kubernetes/manifests
|
||||
```
|
||||
|
||||
- Edit the one corresponding to the API server:
|
||||
@@ -236,7 +236,7 @@
|
||||
|
||||
- Add `PodSecurityPolicy`
|
||||
|
||||
(It should read `--enable-admission-plugins=NodeRestriction,PodSecurityPolicy`)
|
||||
It should read: `--enable-admission-plugins=NodeRestriction,PodSecurityPolicy`
|
||||
|
||||
- Save, quit
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
- We don't endorse Prometheus more or less than any other system
|
||||
|
||||
- It's relatively well integrated within the Cloud Native ecosystem
|
||||
- It's relatively well integrated within the cloud-native ecosystem
|
||||
|
||||
- It can be self-hosted (this is useful for tutorials like this)
|
||||
|
||||
@@ -182,7 +182,7 @@ We need to:
|
||||
|
||||
- Run the *node exporter* on each node (with a Daemon Set)
|
||||
|
||||
- Setup a Service Account so that Prometheus can query the Kubernetes API
|
||||
- Set up a Service Account so that Prometheus can query the Kubernetes API
|
||||
|
||||
- Configure the Prometheus server
|
||||
|
||||
@@ -250,7 +250,7 @@ class: extra-details
|
||||
|
||||
## Explaining all the Helm flags
|
||||
|
||||
- `helm upgrade prometheus` → upgrade release "prometheus" to the latest version ...
|
||||
- `helm upgrade prometheus` → upgrade release "prometheus" to the latest version...
|
||||
|
||||
(a "release" is a unique name given to an app deployed with Helm)
|
||||
|
||||
@@ -288,7 +288,7 @@ class: extra-details
|
||||
|
||||
## Querying some metrics
|
||||
|
||||
- This is easy ... if you are familiar with PromQL
|
||||
- This is easy... if you are familiar with PromQL
|
||||
|
||||
.exercise[
|
||||
|
||||
@@ -433,9 +433,9 @@ class: extra-details
|
||||
|
||||
- I/O activity (disk, network), per operation or volume
|
||||
|
||||
- Physical/hardware (when applicable): temperature, fan speed ...
|
||||
- Physical/hardware (when applicable): temperature, fan speed...
|
||||
|
||||
- ... and much more!
|
||||
- ...and much more!
|
||||
|
||||
---
|
||||
|
||||
@@ -448,7 +448,7 @@ class: extra-details
|
||||
- RAM breakdown will be different
|
||||
|
||||
- active vs inactive memory
|
||||
- some memory is *shared* between containers, and accounted specially
|
||||
- some memory is *shared* between containers, and specially accounted for
|
||||
|
||||
- I/O activity is also harder to track
|
||||
|
||||
@@ -467,11 +467,11 @@ class: extra-details
|
||||
|
||||
- Arbitrary metrics related to your application and business
|
||||
|
||||
- System performance: request latency, error rate ...
|
||||
- System performance: request latency, error rate...
|
||||
|
||||
- Volume information: number of rows in database, message queue size ...
|
||||
- Volume information: number of rows in database, message queue size...
|
||||
|
||||
- Business data: inventory, items sold, revenue ...
|
||||
- Business data: inventory, items sold, revenue...
|
||||
|
||||
---
|
||||
|
||||
@@ -541,8 +541,8 @@ class: extra-details
|
||||
|
||||
- That person can set up queries and dashboards for the rest of the team
|
||||
|
||||
- It's a little bit likeknowing how to optimize SQL queries, Dockerfiles ...
|
||||
- It's a little bit like knowing how to optimize SQL queries, Dockerfiles...
|
||||
|
||||
Don't panic if you don't know these tools!
|
||||
|
||||
... But make sure at least one person in your team is on it 💯
|
||||
...But make sure at least one person in your team is on it 💯
|
||||
|
||||
@@ -86,17 +86,17 @@ Each pod is assigned a QoS class (visible in `status.qosClass`).
|
||||
|
||||
- as long as the container uses less than the limit, it won't be affected
|
||||
|
||||
- if all containers in a pod have *(limits=requests)*, QoS is "Guaranteed"
|
||||
- if all containers in a pod have *(limits=requests)*, QoS is considered "Guaranteed"
|
||||
|
||||
- If requests < limits:
|
||||
|
||||
- as long as the container uses less than the request, it won't be affected
|
||||
|
||||
- otherwise, it might be killed / evicted if the node gets overloaded
|
||||
- otherwise, it might be killed/evicted if the node gets overloaded
|
||||
|
||||
- if at least one container has *(requests<limits)*, QoS is "Burstable"
|
||||
- if at least one container has *(requests<limits)*, QoS is considered "Burstable"
|
||||
|
||||
- If a pod doesn't have any request nor limit, QoS is "BestEffort"
|
||||
- If a pod doesn't have any request nor limit, QoS is considered "BestEffort"
|
||||
|
||||
---
|
||||
|
||||
@@ -400,7 +400,7 @@ These quotas will apply to the namespace where the ResourceQuota is created.
|
||||
|
||||
- Quotas can be created with a YAML definition
|
||||
|
||||
- ... Or with the `kubectl create quota` command
|
||||
- ...Or with the `kubectl create quota` command
|
||||
|
||||
- Example:
|
||||
```bash
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
## A possible approach
|
||||
|
||||
- Since each component of the control plane can be replicated ...
|
||||
- Since each component of the control plane can be replicated...
|
||||
|
||||
- We could set up the control plane outside of the cluster
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
- Worst case scenario, we might need to:
|
||||
|
||||
- set up a new control plane (outside of the cluster)
|
||||
|
||||
|
||||
- restore a backup from the old control plane
|
||||
|
||||
|
||||
- move the new control plane to the cluster (again)
|
||||
|
||||
- This doesn't sound like a great experience
|
||||
@@ -57,7 +57,7 @@
|
||||
- The kubelet can also get a list of *static pods* from:
|
||||
|
||||
- a directory containing one (or multiple) *manifests*, and/or
|
||||
|
||||
|
||||
- a URL (serving a *manifest*)
|
||||
|
||||
- These "manifests" are basically YAML definitions
|
||||
@@ -100,11 +100,11 @@
|
||||
|
||||
## Static pods vs normal pods
|
||||
|
||||
- The API only gives us a read-only access to static pods
|
||||
- The API only gives us read-only access to static pods
|
||||
|
||||
- We can `kubectl delete` a static pod ...
|
||||
- We can `kubectl delete` a static pod...
|
||||
|
||||
... But the kubelet will re-mirror it immediately
|
||||
...But the kubelet will re-mirror it immediately
|
||||
|
||||
- Static pods can be selected just like other pods
|
||||
|
||||
|
||||
Reference in New Issue
Block a user