Compare commits

..

1 Commits

Author SHA1 Message Date
Jérôme Petazzoni
09e060d1c5 🏦 Prep training Boursorama 2024-12-09 23:36:41 +01:00
19 changed files with 698 additions and 408 deletions

View File

@@ -69,7 +69,7 @@ body {
body {
width: 6.75in; /* two cards wide */
margin-left: 0.875in; /* (8.5in - 6.75in)/2 */
margin-top: 0; /* NOTE: we have to manually specify a top margin of e.g. 0.1875in when printing */
margin-top: 0.1875in; /* (11in - 5 cards)/2 */
}
{% endif %}

View File

@@ -8,11 +8,12 @@ backside: |
Thanks for attending the Asynchronous Architecture Patterns workshop at QCON!
</p>
<p>
If you'd like me to send you a copy of the recording of the workshop
and of the training materials,
please scan that QR code to leave me your
contact information. Thank you!
<b>This QR code will give you my contact info</b> as well as a link to a feedback form.
</p>
qrcode: https://2024-11-qconsf.container.training/q
<p>
If you liked this workshop, I can train your team, in person or online, with custom
courses of any length and any level, on Docker, Kubernetes, and MLops.
</p>
qrcode: https://2024-11-qconsf.container.training/#contact
thing: Kubernetes cluster
image: logo-bento.svg
image: logo-kubernetes.png

View File

@@ -2,7 +2,7 @@
#/ /kube-halfday.yml.html 200!
#/ /kube-fullday.yml.html 200!
#/ /kube-twodays.yml.html 200!
/ /mq.yml.html 200!
/ /kube.yml.html 200!
# And this allows to do "git clone https://container.training".
/info/refs service=git-upload-pack https://github.com/jpetazzo/container.training/info/refs?service=git-upload-pack
@@ -13,7 +13,7 @@
#/kubernetesmastery https://www.udemy.com/course/kubernetesmastery/?couponCode=DOCKERALLDAY
# Shortlink for the QRCode
/q https://docs.google.com/forms/d/e/1FAIpQLScYloWur4uVhKgVNIdUrfHZ8pk_mBmPcQwmbhjK2FlR9KWDCA/viewform
/q /qrcode.html 200
# Shortlinks for next training in English and French
#/next https://www.eventbrite.com/e/livestream-intensive-kubernetes-bootcamp-tickets-103262336428
@@ -22,3 +22,5 @@
/us https://www.ardanlabs.com/live-training-events/deploying-microservices-and-traditional-applications-with-kubernetes-march-28-2022.html
/uk https://skillsmatter.com/workshops/827-deploying-microservices-and-traditional-applications-with-kubernetes-with-jerome-petazzoni
# Survey form
/please https://docs.google.com/forms/d/e/1FAIpQLSfIYSgrV7tpfBNm1hOaprjnBHgWKn5n-k5vtNXYJkOX1sRxng/viewform

View File

@@ -1,3 +1,5 @@
version: "2"
services:
www:
image: nginx

View File

@@ -1,285 +0,0 @@
# Calling APIs from Bento
- We want to ask our LLM who's the mayor of each of these cities
- We'll use a prompt that will usually ensure a short answer
(so that it's faster; we don't want to wait 30 seconds per city!)
- We'll test the prompt with the Ollama CLI
- Then we'll craft a proper HTTP API query
- Finally, we'll configure an [enrichment workflow][enrichment] in Bento
---
## Test our prompt
Assuming that our earlier Ollama Deployment is still running:
```bash
kubectl exec deployment/ollama -- \
ollama run qwen2:1.5b "
Who is the mayor of San Francisco?
Just give the name by itself on a single line.
If you don't know, don't say anything.
"
```
---
## Turn the prompt into an HTTP API query
Note: to install `http` in an Alpine container, run `apk add httpie`.
```bash
http http://ollama.default:11434/api/generate \
model=qwen2:1.5b stream:=false prompt="
Who is the mayor of Paris?
Just give the name by itself on a single line.
If you don't know, don't say anything.
"
```
We get a JSON payload, and we want to use the `response` field.
---
## Configure an enrichment workflow
The [Bento documentation][enrichment] is really good!
We need to set up:
- a `branch` processor
- a `request_map` to transform the city into an Ollama request
- an `http` processor to submit the request to Ollama
- a `result_map` to transform the Ollama response
---
## Without the `branch` processor
<pre class="mermaid">
flowchart LR
CITY["
city: Paris
country: France
population: 1106000
iso2: FR
...
"]
REQ["
model: qwen2:1.5b
stream: false
prompt: Who is the mayor of Paris?
"]
REP["
response: Anne Hidalgo
eval_count: ...
prompt_eval_count: ...
(other ollama fields)
"]
CITY@{ shape: card}
REQ@{ shape: card}
REP@{ shape: card}
style CITY text-align: left
style REQ text-align: left
style REP text-align: left
mapping@{ shape: diam }
http["http processor"]@{ shape: diam }
CITY --> mapping --> REQ --> http --> REP
</pre>
- We transform the `city` into an Ollama request
- The `http` processor submits the request to Ollama
- The final output is the Ollama response
---
## With the `branch` processor
<pre class="mermaid">
flowchart LR
CITY["
city: Paris
country: France
population: 1106000
iso2: FR
...
"]
REQ["
model: qwen2:1.5b
stream: false
prompt: Who is the mayor of Paris?
"]
REP["
response: Anne Hidalgo
eval_count: ...
prompt_eval_count: ...
(other ollama fields)
"]
OUT["
city: Paris
country: France
population: 1106000
iso2: FR
...
mayor: Anne Hidalgo
"]
CITY@{ shape: card}
REQ@{ shape: card}
REP@{ shape: card}
OUT@{ shape: card}
style CITY text-align: left
style REQ text-align: left
style REP text-align: left
style OUT text-align: left
branch@{ shape: diam }
request_map@{ shape: diam }
result_map@{ shape: diam }
http["http processor"]@{ shape: diam }
CITY --> branch
branch --> result_map
branch --> request_map
request_map --> REQ
REQ --> http
http --> REP
REP --> result_map
result_map --> OUT
</pre>
- The `branch` processor allows doing the processing "on the side"
- `request_map` and `result_map` transform the message before/after processing
- Then, the result is combined with the original message (the `city`)
---
```yaml
input:
csv:
paths: ["cities.csv"]
pipeline:
processors:
- branch:
request_map: |
root.model = "qwen2:1.5b"
root.stream = false
root.prompt = (
"Who is the mayor of %s? ".format(this.city) +
"Just give the name by itself on a single line. " +
"If you don't know, don't say anything."
)
processors:
- http:
url: http://ollama:11434/api/generate
verb: POST
result_map: |
root.mayor = this.response
```
---
## Trying it out
- Save the YAML on the previous page into a configuration file
- Run Bento with that configuration file
- What happens?
--
🤔 We're seeing errors due to timeouts
```
ERRO HTTP request to 'http://ollama...' failed: http://ollama...:
Post "http://ollama...": context deadline exceeded
(Client.Timeout exceeded while awaiting headers)
```
---
## 🙋 Choose your own adventure
How should we address errors?
- Option 1: increase the timeout in the [http][bento-http] processor
- Option 2: use a [retry][bento-retry] processor in the pipeline
- Option 3: use a [reject_errored][bento-reject] output
---
## 🏗️ Let's build something!
- We want to process 1000 cities with our LLM
(guessing who the mayor is, or something similar)
- Store the output wherever we want
(Redis, CSV file, JSONL files...)
- Deal correctly with errors
(we'll check that there are, indeed, 1000 cities in the output)
- Scale out to process faster
(scale ollama to e.g. 10 replicas, enable parallelism in Bento)
---
class: title
🍱 Lunch time! 🍱
---
## What happened?
- If your Ollama pods have *resource requests*:
→ your cluster may have auto-scaled
- If your Ollama pods don't have *resource requests*:
→ you probably have a bunch of container restarts, due to out-of-memory errors
🤔 What's that about?
[bento-http]: https://warpstreamlabs.github.io/bento/docs/components/processors/http/
[bento-inputs]: https://warpstreamlabs.github.io/bento/docs/components/inputs/about/
[bento-reject]: https://warpstreamlabs.github.io/bento/docs/components/outputs/reject_errored
[bento-retry]: https://warpstreamlabs.github.io/bento/docs/components/processors/retry
[bento-switch]: https://warpstreamlabs.github.io/bento/docs/components/processors/switch/
[enrichment]: https://warpstreamlabs.github.io/bento/cookbooks/enrichments/
[output-http-server]: https://warpstreamlabs.github.io/bento/docs/components/outputs/http_server
[redpanda-acquires-benthos]: https://www.redpanda.com/press/redpanda-acquires-benthos
[warpstream-forks-benthos]: https://www.warpstream.com/blog/announcing-bento-the-open-source-fork-of-the-project-formerly-known-as-benthos

View File

@@ -244,7 +244,7 @@ spec:
---
# Improving throughput
## Improving throughput
We're going to review multiple techniques:

View File

@@ -280,12 +280,22 @@ pipeline:
---
## 🏗️ Let's generate the Bento configuration!
## Generate the Bento configuration
Option 1: `bento create redis_list//http_server`
Option 2: [read the docs][output-http-server]
---
## 🙋 Choose your own adventure
Do you want to try to write that configuration?
Or shall we see it right away?
--
⚠️ Spoilers on next slide!
---
@@ -323,3 +333,291 @@ It's also possible to batch, stream...
```
- Check what happens after we retrive *all* the cities!
---
## 3⃣ Query our LLM for each city
- We want to ask our LLM who's the mayor of each of these cities
- We'll use a prompt that will usually ensure a short answer
(so that it's faster; we don't want to wait 30 seconds per city!)
- We'll test the prompt with the Ollama CLI
- Then we'll craft a proper HTTP API query
- Finally, we'll configure an [enrichment workflow][enrichment] in Bento
---
## Test our prompt
Assuming that our earlier Ollama Deployment is still running:
```bash
kubectl exec deployment/ollama -- \
ollama run qwen2:1.5b "
Who is the mayor of San Francisco?
Just give the name by itself on a single line.
If you don't know, don't say anything.
"
```
---
## Turn the prompt into an HTTP API query
Note: to install `http` in an Alpine container, run `apk add httpie`.
```bash
http http://ollama.default:11434/api/generate \
model=qwen2:1.5b stream:=false prompt="
Who is the mayor of Paris?
Just give the name by itself on a single line.
If you don't know, don't say anything.
"
```
We get a JSON payload, and we want to use the `response` field.
---
## Configure an enrichment workflow
The [Bento documentation][enrichment] is really good!
We need to set up:
- a `branch` processor
- a `request_map` to transform the city into an Ollama request
- an `http` processor to submit the request to Ollama
- a `result_map` to transform the Ollama response
---
## Without the `branch` processor
<pre class="mermaid">
flowchart LR
CITY["
city: Paris
country: France
population: 1106000
iso2: FR
...
"]
REQ["
model: qwen2:1.5b
stream: false
prompt: Who is the mayor of Paris?
"]
REP["
response: Anne Hidalgo
eval_count: ...
prompt_eval_count: ...
(other ollama fields)
"]
CITY@{ shape: card}
REQ@{ shape: card}
REP@{ shape: card}
style CITY text-align: left
style REQ text-align: left
style REP text-align: left
mapping@{ shape: diam }
http["http processor"]@{ shape: diam }
CITY --> mapping --> REQ --> http --> REP
</pre>
- We transform the `city` into an Ollama request
- The `http` processor submits the request to Ollama
- The final output is the Ollama response
---
## With the `branch` processor
<pre class="mermaid">
flowchart LR
CITY["
city: Paris
country: France
population: 1106000
iso2: FR
...
"]
REQ["
model: qwen2:1.5b
stream: false
prompt: Who is the mayor of Paris?
"]
REP["
response: Anne Hidalgo
eval_count: ...
prompt_eval_count: ...
(other ollama fields)
"]
OUT["
city: Paris
country: France
population: 1106000
iso2: FR
...
mayor: Anne Hidalgo
"]
CITY@{ shape: card}
REQ@{ shape: card}
REP@{ shape: card}
OUT@{ shape: card}
style CITY text-align: left
style REQ text-align: left
style REP text-align: left
style OUT text-align: left
branch@{ shape: diam }
request_map@{ shape: diam }
result_map@{ shape: diam }
http["http processor"]@{ shape: diam }
CITY --> branch
branch --> result_map
branch --> request_map
request_map --> REQ
REQ --> http
http --> REP
REP --> result_map
result_map --> OUT
</pre>
- The `branch` processor allows doing the processing "on the side"
- `request_map` and `result_map` transform the message before/after processing
- Then, the result is combined with the original message (the `city`)
---
```yaml
input:
csv:
paths: ["cities.csv"]
pipeline:
processors:
- branch:
request_map: |
root.model = "qwen2:1.5b"
root.stream = false
root.prompt = (
"Who is the mayor of %s? ".format(this.city) +
"Just give the name by itself on a single line. " +
"If you don't know, don't say anything."
)
processors:
- http:
url: http://ollama:11434/api/generate
verb: POST
result_map: |
root.mayor = this.response
```
---
## Trying it out
- Save the YAML on the previous page into a configuration file
- Run Bento with that configuration file
- What happens?
--
🤔 We're seeing errors due to timeouts
```
ERRO HTTP request to 'http://ollama...' failed: http://ollama...:
Post "http://ollama...": context deadline exceeded
(Client.Timeout exceeded while awaiting headers)
```
---
## 🙋 Choose your own adventure
How should we address errors?
- Option 1: increase the timeout in the [http][bento-http] processor
- Option 2: use a [retry][bento-retry] processor in the pipeline
- Option 3: use a [reject_errored][bento-reject] output
---
## 🏗️ Let's build something!
- We want to process 1000 cities with our LLM
(guessing who the mayor is, or something similar)
- Store the output wherever we want
(Redis, CSV file, JSONL files...)
- Deal correctly with errors
(we'll check that there are, indeed, 1000 cities in the output)
- Scale out to process faster
(scale ollama to e.g. 10 replicas, enable parallelism in Bento)
---
class: title
🍱 Lunch time! 🍱
---
## What happened?
- If your Ollama pods have *resource requests*:
→ your cluster may have auto-scaled
- If your Ollama pods don't have *resource requests*:
→ you probably have a bunch of container restarts, due to out-of-memory errors
🤔 What's that about?
[bento-http]: https://warpstreamlabs.github.io/bento/docs/components/processors/http/
[bento-inputs]: https://warpstreamlabs.github.io/bento/docs/components/inputs/about/
[bento-reject]: https://warpstreamlabs.github.io/bento/docs/components/outputs/reject_errored
[bento-retry]: https://warpstreamlabs.github.io/bento/docs/components/processors/retry
[bento-switch]: https://warpstreamlabs.github.io/bento/docs/components/processors/switch/
[enrichment]: https://warpstreamlabs.github.io/bento/cookbooks/enrichments/
[output-http-server]: https://warpstreamlabs.github.io/bento/docs/components/outputs/http_server
[redpanda-acquires-benthos]: https://www.redpanda.com/press/redpanda-acquires-benthos
[warpstream-forks-benthos]: https://www.warpstream.com/blog/announcing-bento-the-open-source-fork-of-the-project-formerly-known-as-benthos

View File

@@ -1,4 +1,4 @@
# Scaling up the cluster
# Cluster autoscaler
- When the cluster is full, we need to add more nodes
@@ -221,9 +221,7 @@ THEN add a Node.
---
# Scaling down the cluster
*In theory:*
## Scaling down in theory
IF a Node has less than 50% utilization for 10 minutes,

View File

@@ -110,77 +110,6 @@ class: in-person, pic
---
## Our recommendation
- Any managed Kubernetes cluster
- Nodes with 8 GB of RAM (or more)
- At least 1 node (obviously!)
- Ideally, cluster autoscaling
(you can set the maximum number of nodes to 5)
- Alternatively, have a cluster of at least 3 nodes
(ideally a bit more to see the effect of scaling)
- Local tools: kubectl, Helm, Stern, Bento
- You can also use [shpod] to get a shell on the cluster
[shpod]: https://github.com/jpetazzo/shpod
---
## Example with Linode (create cluster)
- Make sure you have a [Linode account][linode-account]
- Install and configure the [Linode CLI][linode-cli]
- Create a cluster:
```bash
lin lke cluster-create --label mlops \
--k8s_version=1.31 \
--node_pools.type g6-standard-4 \
--node_pools.count 1 \
--node_pools.autoscaler.enabled true \
--node_pools.autoscaler.min 1 \
--node_pools.autoscaler.max 5 \
#
```
[linode-account]: https://login.linode.com/signup
[linode-cli]: https://www.linode.com/products/cli/
---
## Example with Linode (retrieve kubeconfig)
- Retrieve the cluster ID:
```bash
CLUSTER_ID=$(lin lke clusters-list --label $CLUSTER_NAME --json | jq .[].id)
```
- Wait until the cluster is provisioned:
```bash
while ! lin lke kubeconfig-view $CLUSTER_ID; do
sleep 10
done
```
- Retrieve the cluster kubeconfig:
```bash
lin lke kubeconfig-view $CLUSTER_ID --json | jq -r .[].kubeconfig |
base64 -d > kubeconfig.$CLUSTER_ID
```
- And set the `KUBECONFIG` environment variable accordingly!
---
class: in-person
## Why don't we run containers locally?

View File

@@ -1,4 +1,4 @@
## Pre-requirements
# Pre-requirements
- Kubernetes concepts

View File

@@ -1,4 +1,4 @@
# Allocating compute resources in theory
# Resource Limits
- We can attach resource indications to our pods
@@ -426,7 +426,7 @@ Each pod is assigned a QoS class (visible in `status.qosClass`).
---
# Allocating compute resources in practice
## Specifying resources
- Resource requests are expressed at the *container* level
@@ -606,6 +606,246 @@ per Pod, but it's not [officially documented yet](https://github.com/kubernetes/
---
# Namespace quotas
- We can also set quotas per namespace
- Quotas apply to the total usage in a namespace
(e.g. total CPU limits of all pods in a given namespace)
- Quotas can apply to resource limits and/or requests
(like the CPU and memory limits that we saw earlier)
- Quotas can also apply to other resources:
- "extended" resources (like GPUs)
- storage size
- number of objects (number of pods, services...)
---
## Creating a quota for a namespace
- Quotas are enforced by creating a ResourceQuota object
- ResourceQuota objects are namespaced, and apply to their namespace only
- We can have multiple ResourceQuota objects in the same namespace
- The most restrictive values are used
---
## Limiting total CPU/memory usage
- The following YAML specifies an upper bound for *limits* and *requests*:
```yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: a-little-bit-of-compute
spec:
hard:
requests.cpu: "10"
requests.memory: 10Gi
limits.cpu: "20"
limits.memory: 20Gi
```
These quotas will apply to the namespace where the ResourceQuota is created.
---
## Limiting number of objects
- The following YAML specifies how many objects of specific types can be created:
```yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-for-objects
spec:
hard:
pods: 100
services: 10
secrets: 10
configmaps: 10
persistentvolumeclaims: 20
services.nodeports: 0
services.loadbalancers: 0
count/roles.rbac.authorization.k8s.io: 10
```
(The `count/` syntax allows limiting arbitrary objects, including CRDs.)
---
## YAML vs CLI
- Quotas can be created with a YAML definition
- ...Or with the `kubectl create quota` command
- Example:
```bash
kubectl create quota my-resource-quota --hard=pods=300,limits.memory=300Gi
```
- With both YAML and CLI form, the values are always under the `hard` section
(there is no `soft` quota)
---
## Viewing current usage
When a ResourceQuota is created, we can see how much of it is used:
```
kubectl describe resourcequota my-resource-quota
Name: my-resource-quota
Namespace: default
Resource Used Hard
-------- ---- ----
pods 12 100
services 1 5
services.loadbalancers 0 0
services.nodeports 0 0
```
---
## Advanced quotas and PriorityClass
- Pods can have a *priority*
- The priority is a number from 0 to 1000000000
(or even higher for system-defined priorities)
- High number = high priority = "more important" Pod
- Pods with a higher priority can *preempt* Pods with lower priority
(= low priority pods will be *evicted* if needed)
- Useful when mixing workloads in resource-constrained environments
---
## Setting the priority of a Pod
- Create a PriorityClass
(or use an existing one)
- When creating the Pod, set the field `spec.priorityClassName`
- If the field is not set:
- if there is a PriorityClass with `globalDefault`, it is used
- otherwise, the default priority will be zero
---
class: extra-details
## PriorityClass and ResourceQuotas
- A ResourceQuota can include a list of *scopes* or a *scope selector*
- In that case, the quota will only apply to the scoped resources
- Example: limit the resources allocated to "high priority" Pods
- In that case, make sure that the quota is created in every Namespace
(or use *admission configuration* to enforce it)
- See the [resource quotas documentation][quotadocs] for details
[quotadocs]: https://kubernetes.io/docs/concepts/policy/resource-quotas/#resource-quota-per-priorityclass
---
# Limiting resources in practice
- We have at least three mechanisms:
- requests and limits per Pod
- LimitRange per namespace
- ResourceQuota per namespace
- Let's see one possible strategy to get started with resource limits
---
## Set a LimitRange
- In each namespace, create a LimitRange object
- Set a small default CPU request and CPU limit
(e.g. "100m")
- Set a default memory request and limit depending on your most common workload
- for Java, Ruby: start with "1G"
- for Go, Python, PHP, Node: start with "250M"
- Set upper bounds slightly below your expected node size
(80-90% of your node size, with at least a 500M memory buffer)
---
## Set a ResourceQuota
- In each namespace, create a ResourceQuota object
- Set generous CPU and memory limits
(e.g. half the cluster size if the cluster hosts multiple apps)
- Set generous objects limits
- these limits should not be here to constrain your users
- they should catch a runaway process creating many resources
- example: a custom controller creating many pods
---
## Observe, refine, iterate
- Observe the resource usage of your pods
(we will see how in the next chapter)
- Adjust individual pod limits
- If you see trends: adjust the LimitRange
(rather than adjusting every individual set of pod limits)
- Observe the resource usage of your namespaces
(with `kubectl describe resourcequota ...`)
- Rinse and repeat regularly
---
## Underutilization
- Remember: when assigning a pod to a node, the scheduler looks at *requests*

View File

@@ -403,7 +403,7 @@ class: extra-details
- Enabled with annotation `service.kubernetes.io/topology-mode=Auto`
- Relies on node label `topology.kubernetes.io/zone`
- Relies on node annotation `topology.kubernetes.io/zone`
- Kubernetes service proxy will try to keep connections within a zone

View File

@@ -77,7 +77,7 @@ This is the flag that we're looking for:
- We only need to transfer the CSR (Certificate Signing Request) to the CA
(we never need to expose the private key)
(we never need to expoes the private key)
.lab[

98
slides/kube.yml Normal file
View File

@@ -0,0 +1,98 @@
title: |
Kubernetes
chat: "[Mattermost](https://training.enix.io/mattermost)"
gitrepo: github.com/jpetazzo/container.training
slides: https://2024-10-boursorama.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
exclude:
- self-paced
content:
- shared/title.md
- logistics.md
- k8s/intro.md
- shared/about-slides.md
- shared/chat-room-im.md
#- shared/chat-room-zoom-meeting.md
#- shared/chat-room-zoom-webinar.md
- shared/prereqs.md
- shared/handson.md
#- shared/webssh.md
- shared/connecting.md
- shared/toc.md
- # 1 Monday morning
- shared/sampleapp.md
- shared/composedown.md
- k8s/concepts-k8s.md
- k8s/kubectlget.md
- k8s/kubectl-run.md
- k8s/kubectlexpose.md
#- k8s/shippingimages.md
#- k8s/buildshiprun-selfhosted.md
- k8s/buildshiprun-dockerhub.md
- exercises/k8sfundamentals-details.md
- k8s/ourapponkube.md
- # 2 Monday afternoon
- k8s/service-types.md
- k8s/kubenet.md
- k8s/labels-annotations.md
- k8s/kubectl-logs.md
- k8s/logs-cli.md
- # 3 Tuesday morning
- shared/yaml.md
- k8s/yamldeploy.md
- k8s/namespaces.md
- shared/declarative.md
- k8s/declarative.md
- k8s/deploymentslideshow.md
- k8s/ingress.md
- k8s/cert-manager.md
- exercises/yaml-details.md
- exercises/ingress-details.md
- # 4 Tuesday afternoon
- k8s/volumes.md
#- k8s/exercise-configmap.md
- k8s/configuration.md
- k8s/secrets.md
- # 5 Wednesday morning
- k8s/scalingdockercoins.md
- shared/hastyconclusions.md
- k8s/daemonset.md
- k8s/rollout.md
- k8s/healthchecks.md
- exercises/healthchecks-details.md
- # 6 Wednesday afternoon
- k8s/resource-limits.md
- k8s/metrics-server.md
- k8s/cluster-sizing.md
#- k8s/horizontal-pod-autoscaler.md
- exercises/reqlim-details.md
- # 7 Thursday morning
- k8s/authn-authz.md
- k8s/admission.md
- k8s/cainjector.md
- k8s/kyverno.md
- exercises/rbac-details.md
- exercises/kyverno-ingress-domain-name-details.md
- # 8 Thursday afternoon
- k8s/statefulsets.md
- k8s/consul.md
- k8s/pv-pvc-sc.md
- k8s/volume-claim-templates.md
- k8s/stateful-failover.md
- # 9 Friday morning
- k8s/helm-intro.md
- k8s/helm-chart-format.md
- k8s/helm-create-basic-chart.md
- exercises/helm-generic-chart-details.md
- # 10 Friday afternoon
- k8s/helm-create-better-chart.md
- k8s/helm-dependencies.md
- k8s/helm-values-schema-validation.md
- k8s/helm-secrets.md
- exercises/helm-umbrella-chart-details.md

View File

@@ -1,44 +1,54 @@
## Introductions
Hello! We are:
- Hello! I'm Jérôme Petazzoni ([@jpetazzo], [@jpetazzo@hachyderm.io], Enix SAS)
- Jérôme Petazzoni ([@jpetazzo@hachyderm.io], [/in/jpetazzo][jp-linkedin])
- Schedule: FIXME
- freelance Docker¹ / Kubernetes / MLops consultant and trainer
- Feel free to interrupt for questions at any time
- AJ Bowen ([GitHub: @soulshake][aj-github], [LinkedIn: AJ Bowen][aj-linkedin])
- *Especially when you see full screen container pictures!*
- freelance k8s/IaC/CI/CD/devOps engineer and consultant
- Live feedback, questions, help: @@CHAT@@
- founder of [EphemeraSearch]
- You ~~should~~ must ask questions! Lots of questions!
.footnote[¹I worked at Docker from 2011 to 2018.
I ran containers in production before it was cool. 😎]
(especially when you see full screen container pictures)
- Use @@CHAT@@ to ask questions, get help, etc.
[@alexbuisine]: https://twitter.com/alexbuisine
[EphemeraSearch]: https://ephemerasearch.com/
[@jpetazzo]: https://twitter.com/jpetazzo
[aj-github]: https://github.com/soulshake
[aj-linkedin]: https://linkedin.com/in/ajbowen
[jp-linkedin]: https://linkedin.com/in/jpetazzo
[@jpetazzo@hachyderm.io]: https://hachyderm.io/@jpetazzo
[@s0ulshake]: https://twitter.com/s0ulshake
[Quantgene]: https://www.quantgene.com/
---
## Context
## Un petit sondage ...
- This content was delivered at QCON SF in November 2024
(in-person workshop)
Sur une échelle de 0 à 5, où vous situez-vous avec Kubernetes ?
- I recorded that workshop, but had technical issues
0⃣ Kuberne-quoi ? 😅
- This is a re-recording of the workshop!
1⃣ J'ai déjà vu quelques présentations, démos ... Mais jamais utilisé
- I may or may not cover everything in this video series
2⃣ J'ai déjà fait quelques tutos mais je ne connais pas bien les concepts
- At the conference, I provided everyone with an individual cluster
3⃣ J'utilise occasionnellement ; j'ai (ou peut avoir) accès à un cluster (local, cloud, n'importe) ; je connais les concepts de Pod, Deployment, Service
- If you want to follow along the demos and labs, you'll need your own
4⃣ Je déploie régulièrement sur un cluster (que ça soit dev en local ou prod) ; je sais écrire / générer et utiliser des manifests YAML
(I'll explain how to provision it)
5⃣ Je connais tout ça et j'ai aussi déjà manipulé au moins un concept avancé comme le RBAC, les Ingress, les requests/limits
---
## Exercises
- In the middle of each day, there is a series of exercises
- To make the most out of the training, please try the exercises!
(it will help to practice and memorize the content of the day)
- We'll run polls to know how much time to spend on reviewing the exercises

View File

@@ -7,16 +7,15 @@ chat: "In person!"
gitrepo: github.com/jpetazzo/container.training
slides: https://2024-12-mq.container.training/
slides: https://FIXME.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
exclude:
- in-person
- self-paced
content:
- shared/title.md
- shared/contact.md
- logistics.md
- shared/about-slides.md
#- shared/chat-room-im.md
@@ -25,7 +24,7 @@ content:
#- shared/chat-room-zoom-webinar.md
- k8s/prereqs-advanced.md
- k8s/handson-mlops.md
#- shared/connecting.md
- shared/connecting.md
- k8s/mlops-headsup.md
- shared/toc.md
-
@@ -34,11 +33,9 @@ content:
- k8s/queue-architecture.md
- k8s/bento-intro.md
-
- k8s/bento-enrichment.md
- k8s/resource-limits.md
- k8s/cluster-autoscaler.md
- k8s/ollama-reqlim.md
-
- k8s/bento-hpa.md
- k8s/bento-rmq.md
- k8s/bento-cnpg.md

View File

@@ -60,7 +60,7 @@ class: in-person
## Doing or re-doing the workshop on your own?
- Use something like
[Play-With-Docker](https://labs.play-with-docker.com/) or
[Play-With-Docker](http://play-with-docker.com/) or
[Play-With-Kubernetes](https://training.play-with-kubernetes.com/)
Zero setup effort; but environment are short-lived and
@@ -103,13 +103,13 @@ class: self-paced
.lab[
- Go to https://labs.play-with-docker.com/
- Go to http://www.play-with-docker.com/
- Log in
- Create your first node
<!-- ```open https://labs.play-with-docker.com/``` -->
<!-- ```open http://www.play-with-docker.com/``` -->
]

View File

@@ -1,4 +1,4 @@
# Pre-requirements
## Pre-requirements
- Be comfortable with the UNIX command line

View File

@@ -1,6 +1,6 @@
## Using Play-With-Docker
- Open a new browser tab to [labs.play-with-docker.com](https://labs.play-with-docker.com/)
- Open a new browser tab to [www.play-with-docker.com](http://www.play-with-docker.com/)
- Confirm that you're not a robot