Compare commits

..

10 Commits

Author SHA1 Message Date
Jérôme Petazzoni
c2a41993f7 🚧 WIP Adyen 2026-03-19 18:53:05 -05:00
Jérôme Petazzoni
477bc28f66 🔧 Use 'create' instead of 'apply' to install ArgoCD
Some resources are too big to work with apply.
2026-02-16 16:31:02 +01:00
Jérôme Petazzoni
fb9e531c63 🔧 Fix Mermaid invocation
It look like commit f9d73c0 introduced a very subtle regression
by removing what seemed to be an extraneous space in a selector...
But the space was there on purpose, so it had actually broken
Mermaid integration. This fixes it, hopefully in a way that won't
be affected the same way!
2026-02-16 16:29:28 +01:00
Jérôme Petazzoni
ae776d71ba ️ Add a couple of new-style Kyverno policies
Eventually, we should rewrite all Kyverno policies to replace
the old-style ones (ClusterPolicy) with the new ones and use CEL.
2026-02-16 15:59:43 +01:00
Hadrien DEVALLEZ
3e14209060 fix(prepare-labs): change cdn.dl.k8s.io to dl.k8s.io 2026-02-16 13:23:15 +01:00
Hadrien DEVALLEZ
8a331246f9 prepare-labs: bump kustomize to v5.8.1 2026-02-16 12:28:47 +01:00
Jérôme Petazzoni
8ba96380b7 🔧 Disable threading in flask debug server
For educational purposes, the RNG service is meant to
process only one request at a time (without concurrency).
But the flask server now defaults to a multi-threaded
implementation, which defeats our original purpose.
So here we disable threading to restore the original
behavior.
2026-01-30 13:00:01 +01:00
Olivier Delhomme
4311a09ccd 🔧 updates documentation links that changed 2026-01-28 15:31:00 +01:00
Jérôme Petazzoni
feb0a8cdb9 Use multiple # in included files' comments
...otherwise that causes side effects with the TOC generator 🙈
2026-01-27 08:50:23 +01:00
Jérôme Petazzoni
302924db40 🔧 Bump up vcluster version to work around weird bug
(Probably due to K8S version mismatch; vcluster was on 1.33 and the
host cluster was on 1.35. Symptoms: some pods start, all their
containers are ready, the pod shows up as ready, and yet, it's not
considered ready so the deployment says 0/1 and Helm never completes.)
2026-01-27 08:49:04 +01:00
16 changed files with 186 additions and 222 deletions

View File

@@ -3,5 +3,5 @@ WORKDIR /app
RUN pip install Flask
COPY rng.py .
ENV FLASK_APP=rng FLASK_RUN_HOST=:: FLASK_RUN_PORT=80
CMD ["flask", "run"]
CMD ["flask", "run", "--without-threads"]
EXPOSE 80

View File

@@ -12,5 +12,5 @@ listen very-basic-load-balancer
server blue color.blue.svc:80
server green color.green.svc:80
# Note: the services above must exist,
# otherwise HAproxy won't start.
### Note: the services above must exist,
### otherwise HAproxy won't start.

View File

@@ -0,0 +1,56 @@
# This is a Kyverno policy to automatically generate an Ingress resource,
# similar to the other ones in this directory; but instead of using the
# "old-style" policies (ClusterPolicy with spec.rules.generate), it is
# using the new CR GeneratingPolicy and CEL.
apiVersion: policies.kyverno.io/v1
kind: GeneratingPolicy
metadata:
name: generate-ingress-for-service
spec:
matchConstraints:
resourceRules:
- apiGroups: ['']
apiVersions: ['v1']
operations: ['CREATE']
resources: ['services']
variables:
- name: host
expression: |
object.metadata.name + "." + object.metadata.namespace + ".example.com"
- name: ingress
expression: >-
[
{
"kind": dyn("Ingress"),
"apiVersion": dyn("networking.k8s.io/v1"),
"metadata": dyn({
"name": object.metadata.name,
"namespace": object.metadata.namespace,
}),
"spec": dyn({
"rules": [
{
"host": dyn(variables.host),
"http": dyn({
"paths": [
{
"path": dyn("/"),
"pathType": dyn("Prefix"),
"backend": dyn({
"service": {
"name": dyn(object.metadata.name),
"port": dyn({
"number": 80
})
}
})
}
]
})
}
]
})
}
]
generate:
- expression: generator.Apply(object.metadata.namespace, variables.ingress)

37
k8s/kyverno-vap.yaml Normal file
View File

@@ -0,0 +1,37 @@
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: ensure-security-label
spec:
# What to do if an error happens when evaluating that policy? (Fail or Ignore)
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
scope: Namespaced # "Cluster", "Namespaced", or "*"
validations:
- expression: |
'security' in object.metadata.labels
&&
object.metadata.labels.security in [ "public", "private", "namespace" ]
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: ensure-security-label
spec:
policyName: ensure-security-label
# What to do when a policy doesn't validate: Deny, Warn, Audit.
# (Note: it doesn't make sense to put Deny and Warn together.)
validationActions: [ Deny ]
matchResources:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values: [ kube-system, local-path-storage, kyverno ]

View File

@@ -5,6 +5,9 @@
# 10% CPU
# (See https://docs.google.com/document/d/1n0lwp6rQKQUIuo_A5LQ1dgCzrmjkDjmDtNj1Jn92UrI)
# PRO2-XS = 4 core, 16 gb
# Note that we also need 2 volumes per vcluster (one for vcluster itself, one for shpod),
# so we might hit the maximum number of volumes per node!
# (TODO: check what that limit is on Scaleway and Linode)
#
# With vspod:
# 800 MB RAM
@@ -15,7 +18,7 @@ set -e
KONKTAG=konk
PROVIDER=linode
STUDENTS=5
STUDENTS=2
case "$PROVIDER" in
linode)

View File

@@ -479,7 +479,7 @@ _cmd_kubebins() {
need_tag
if [ "$KUBEVERSION" = "" ]; then
KUBEVERSION="$(curl -fsSL https://cdn.dl.k8s.io/release/stable.txt | sed s/^v//)"
KUBEVERSION="$(curl -fsSL https://dl.k8s.io/release/stable.txt | sed s/^v//)"
fi
##VERSION##
@@ -531,7 +531,7 @@ _cmd_kubepkgs() {
# minor version, so we need to figure out what minor version we are
# installing to add the corresponding repo.
if [ "$KUBEVERSION" = "" ]; then
KUBEVERSION="$(curl -fsSL https://cdn.dl.k8s.io/release/stable.txt | sed s/^v//)"
KUBEVERSION="$(curl -fsSL https://dl.k8s.io/release/stable.txt | sed s/^v//)"
fi
KUBEREPOVERSION="$(echo $KUBEVERSION | cut -d. -f1-2)"
@@ -819,7 +819,7 @@ EOF
# Install kustomize
##VERSION## https://github.com/kubernetes-sigs/kustomize/releases
KUSTOMIZE_VERSION=v5.4.1
KUSTOMIZE_VERSION=v5.8.1
URL=\$GITHUB/kubernetes-sigs/kustomize/releases/download/kustomize/${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz
pssh "
if [ ! -x /usr/local/bin/kustomize ]; then

View File

@@ -4,7 +4,7 @@ resource "helm_release" "_" {
create_namespace = true
repository = "https://charts.loft.sh"
chart = "vcluster"
version = "0.27.1"
version = "0.30.4"
values = [
yamlencode({
controlPlane = {

View File

@@ -2,6 +2,7 @@
#/ /kube-halfday.yml.html 200!
#/ /kube-fullday.yml.html 200!
#/ /kube-twodays.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

View File

@@ -1,42 +0,0 @@
title: "Kubernetes Academy"
exclude:
- self-paced
content:
- shared/toc.md
-
- shared/codespaces.md
- k8s/concepts-k8s.md
- k8s/kubectlget.md
- k8s/kubectl-run.md
- k8s/deploymentslideshow.md
- k8s/kubectlexpose.md
- k8s/service-types.md
- k8s/accessinternal.md
- k8s/kubenet.md
- exercises/k8sfundamentals-details.md
-
- k8s/declarative.md
- k8s/namespaces.md
- shared/yaml.md
- k8s/yamldeploy.md
- exercises/yaml-dockercoins-details.md
-
- k8s/setup-devel.md
- k8s/k9s.md
- k8s/labels-annotations.md
- k8s/kubectl-logs.md
- k8s/logs-cli.md
- k8s/rollout.md
- k8s/healthchecks.md
- k8s/healthchecks-more.md
- k8s/volumes.md
- k8s/configuration.md
- k8s/secrets.md
- k8s/resource-limits.md
- k8s/batch-jobs.md
- k8s/ingress.md
- k8s/ingress-advanced.md
- k8s/gateway-api.md

View File

@@ -1,54 +0,0 @@
title: |
Exposing HTTP apps
on Kubernetes:
Services, Ingress Controllers,
and Gateway API
gitrepo: github.com/jpetazzo/container.training
slides: https://container.training/
content:
- |
## What are we going to learn?
- Exposing HTTP apps on Kubernetes
- Recap on Kubernetes Services and networking model
- Ingress resources and controllers
- Gateway API
- Things that make Ingress and Gateway API better:
- ExternalDNS
- cert-manager
- Kyverno
#- shared/about-slides.md
- k8s/prereqs-advanced.md
- shared/handson.md
#- k8s/labs-live.md
#- shared/connecting.md
- k8s/labs-async.md
- |
class: title
Let's get started!
- shared/toc.md
-
- k8s/demo-apps.md
- k8s/kubectlexpose.md
- k8s/service-types.md
- k8s/kubenet.md
- k8s/ingress.md
- k8s/ingress-setup.md
- k8s/ingress-advanced.md
- k8s/externaldns.md
- k8s/kyverno.md
- k8s/cert-manager.md
- k8s/gateway-api.md
- k8s/taints-and-tolerations.md

View File

@@ -61,7 +61,7 @@ ArgoCD manages **applications** by **syncing** their **live state** with their *
- Create a namespace for ArgoCD and install it there:
```bash
kubectl create namespace argocd
kubectl apply --namespace argocd -f \
kubectl create --namespace argocd -f \
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

View File

@@ -729,8 +729,8 @@ class: extra-details
- Relevant documentation:
[Service spec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#servicespec-v1-core),
[LabelSelector spec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#labelselector-v1-meta),
[Service spec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec),
[LabelSelector spec](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/label-selector/),
[label selector doc](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors)
---

75
slides/kube.yml Normal file
View File

@@ -0,0 +1,75 @@
title: |
Kubernetes
#chat: "[Mattermost](https://training.enix.io/mattermost)"
gitrepo: github.com/jpetazzo/container.training
slides: https://2026-05-adyen.container.training/
#slidenumberprefix: "#SomeHashTag — "
exclude:
- self-paced
content:
- shared/title.md
- logistics.md
- shared/about-slides.md
#- shared/chat-room-im.md
- k8s/prereqs-advanced.md
- shared/handson.md
- k8s/labs-live.md
- shared/connecting.md
- k8s/labs-async.md
- shared/toc.md
- # 1A
- k8s/demo-apps.md
- k8s/yamldeploy.md
- k8s/volumes.md
- k8s/configuration.md
- k8s/helm-intro.md
- k8s/helm-chart-format.md
- k8s/helm-create-basic-chart.md
- exercises/helm-generic-chart-details.md
-
- k8s/helm-create-better-chart.md
- k8s/helm-dependencies.md
- k8s/gitworkflows.md
- k8s/argocd.md
- # 2A
- k8s/resource-limits.md
- k8s/cluster-sizing.md
- k8s/horizontal-pod-autoscaler.md
- k8s/disruptions.md
- k8s/admission.md
- k8s/kyverno.md
- exercises/kyverno-ingress-domain-name-details.md
-
- k8s/operators.md
- k8s/operators-design.md
- k8s/kubebuilder.md
- # 3A
- k8s/architecture.md
- k8s/dmuc-easy.md
- k8s/cni-internals.md
- k8s/staticpods.md
- k8s/dmuc-medium.md
- k8s/kubenet.md
- k8s/service-types.md
- k8s/localkubeconfig.md
- k8s/accessinternal.md
- k8s/dmuc-hard.md
- exercises/dmuc-networking-details.md
-
- k8s/TODO-coredns.md
- |
# TODO CoreDNS
- k8s/TODO-haproxy.md
- |
# TODO HAProxy Ingress
- shared/thankyou.md
- # EXTRA
- |
# (Extra stuff...)

View File

@@ -1,63 +1,13 @@
## Introductions
⚠️ This slide should be customized by the tutorial instructor(s).
- Hello! I'm Jérôme ([@jpetazzo], [@jpetazzo@hachyderm.io], Ardan Labs)
<!--
- Hello! We are:
- 👷🏻‍♀️ AJ ([@s0ulshake], [EphemeraSearch], [Quantgene])
- 🚁 Alexandre ([@alexbuisine], Enix SAS)
- 🐳 Jérôme ([@jpetazzo], [@jpetazzo@hachyderm.io], Ardan Labs)
- 🐳 Jérôme ([@jpetazzo], [@jpetazzo@hachyderm.io], Enix SAS)
- 🐳 Jérôme ([@jpetazzo], [@jpetazzo@hachyderm.io], Tiny Shell Script LLC)
-->
<!--
- The training will run for 4 hours, with a 10 minutes break every hour
(the middle break will be a bit longer)
-->
<!--
- The workshop will run from XXX to YYY
- The training will run from XXX to YYY
- There will be a lunch break at ZZZ
(And coffee breaks!)
-->
<!--
- Feel free to interrupt for questions at any time
- *Especially when you see full screen container pictures!*
- Live feedback, questions, help: @@CHAT@@
-->
<!--
- You ~~should~~ must ask questions! Lots of questions!
(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
@@ -65,18 +15,3 @@
[@s0ulshake]: https://twitter.com/s0ulshake
[Quantgene]: https://www.quantgene.com/
---
## Exercises
- At the end 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 recommend to take at least one hour to work on the exercises
(if you understood the content of the day, it will be much faster)
- Each day will start with a quick review of the exercises of the previous day

View File

@@ -1,47 +0,0 @@
title: |
Asynchronous Architecture Patterns To Scale ML and Other High Latency Workloads on 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: https://FIXME.container.training/
#slidenumberprefix: "#SomeHashTag &mdash; "
exclude:
- self-paced
content:
- shared/title.md
- logistics.md
- shared/about-slides.md
#- shared/chat-room-im.md
#- shared/chat-room-slack.md
#- shared/chat-room-zoom-meeting.md
#- shared/chat-room-zoom-webinar.md
- k8s/prereqs-advanced.md
# Note: if we work on this later, we should refactor it
# to follow the same pattern as the other classes
# (i.e. use the k8s/labs-*.md files)
- k8s/handson-mlops.md
- shared/connecting.md
- k8s/mlops-headsup.md
- shared/toc.md
-
- k8s/ollama-intro.md
- k8s/ollama-metrics.md
- k8s/queue-architecture.md
- k8s/bento-intro.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
- k8s/helmfile.md
- shared/thankyou.md
- shared/contact.md

View File

@@ -54,7 +54,7 @@
mermaid.initialize({ startOnLoad: false });
slideshow.on('afterShowSlide', function (slide) {
mermaid.run({
nodes: document.querySelectorAll('div.remark-visible.mermaid'),
nodes: document.querySelectorAll('div.remark-visible pre.mermaid'),
});
});
// Reminder, if you want to tinker with mermaid,