<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Labs on Eriks training corner</title><link>https://training.caha.cloud/en/kubernetesintro/labs/index.html</link><description>Recent content in Labs on Eriks training corner</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://training.caha.cloud/en/kubernetesintro/labs/index.xml" rel="self" type="application/rss+xml"/><item><title>Lab 01 - Workstation setup</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-01-workstation-setup/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-01-workstation-setup/index.html</guid><description>&lt;h1 id="lab-01---workstation-setup"&gt;Lab 01 - Workstation setup&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; turn support01 into your kubectl workstation.
&lt;strong&gt;Cheat sheet:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/cheatsheets/kubectl/"&gt;kubectl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;support01 has Docker and the NFS exports, but deliberately &lt;strong&gt;no kubectl and no
kubeconfig&lt;/strong&gt;. Building your own client is the first thing you do at any
customer, so you may as well do it here.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - log in to the jump host (from your PC)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh student@192.168.56.101 &lt;span class="c1"&gt;# password: linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - who am I, and can I reach the cluster nodes?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hostname -f
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip -brief address &lt;span class="c1"&gt;# note your 192.168.128.0/24 address&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; n in control01 worker01 worker02 worker03&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; getent hosts &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If a name does not resolve, note its IP now - you will need it in step 6.&lt;/p&gt;</description></item><item><title>Lab 02 - Docker containers</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-02-docker-containers/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-02-docker-containers/index.html</guid><description>&lt;h1 id="lab-02---docker-containers"&gt;Lab 02 - Docker containers&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; the container lifecycle, and why the writable layer matters.
&lt;strong&gt;Cheat sheet:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/cheatsheets/docker/"&gt;Docker&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - the shortest possible container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker run hello-world
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker ps &lt;span class="c1"&gt;# nothing - it already exited&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker ps -a &lt;span class="c1"&gt;# there it is, Exited (0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A container lives exactly as long as its main process. &lt;code&gt;hello-world&lt;/code&gt; prints and
exits, so the container is finished before &lt;code&gt;docker ps&lt;/code&gt; can see it. This is the
same reason a Kubernetes Pod with no long-running process ends up in
&lt;code&gt;CrashLoopBackOff&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Lab 03 - Docker images and Dockerfile</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-03-docker-images/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-03-docker-images/index.html</guid><description>&lt;h1 id="lab-03---docker-images-and-dockerfile"&gt;Lab 03 - Docker images and Dockerfile&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; understand layers by watching the build cache work.
&lt;strong&gt;Cheat sheet:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/cheatsheets/docker/"&gt;Docker&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - pull and inspect&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker pull nginx:1.27
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker &lt;span class="nb"&gt;history&lt;/span&gt; nginx:1.27 &lt;span class="c1"&gt;# one line per layer, with sizes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;history&lt;/code&gt; is the image&amp;rsquo;s build recipe read backwards. Most layers are 0 B -
metadata only. The big one is the base filesystem.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - layer sharing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker pull nginx:1.27-alpine
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker images &lt;span class="p"&gt;|&lt;/span&gt; grep nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Compare the sizes. Alpine images are small because the base is small, not
because nginx is different.&lt;/p&gt;</description></item><item><title>Lab 04 - Docker networking and volumes</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-04-docker-networking-volumes/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-04-docker-networking-volumes/index.html</guid><description>&lt;h1 id="lab-04---docker-networking-and-volumes"&gt;Lab 04 - Docker networking and volumes&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; name resolution between containers, and data that survives.
&lt;strong&gt;Cheat sheet:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/cheatsheets/docker/"&gt;Docker&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="networking"&gt;Networking&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - the default networks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker network ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - on the default bridge, name resolution does NOT work&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker run -d --name db busybox sleep &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker run --rm busybox ping -c1 db &lt;span class="c1"&gt;# bad address &amp;#39;db&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3 - a user-defined network gives you DNS by container name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker network create appnet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker run -d --name db2 --network appnet busybox sleep &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker run --rm --network appnet busybox ping -c1 db2 &lt;span class="c1"&gt;# works&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the single most useful thing Docker networking does, and it is the
concept a Kubernetes Service generalises: reach a moving target by a stable
name. The difference is that Docker&amp;rsquo;s name points at one container, while a
Service&amp;rsquo;s name points at whichever Pods are currently ready.&lt;/p&gt;</description></item><item><title>Lab 05 - First look at the cluster</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-05-first-look-at-the-cluster/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-05-first-look-at-the-cluster/index.html</guid><description>&lt;h1 id="lab-05---first-look-at-the-cluster"&gt;Lab 05 - First look at the cluster&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; see what the cluster is made of, and the difference between imperative
and declarative.
&lt;strong&gt;Cheat sheet:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/cheatsheets/kubectl/"&gt;kubectl&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - where am I connected, and as whom?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl cluster-info
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl config get-contexts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl config view --minify &lt;span class="p"&gt;|&lt;/span&gt; grep server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Get into the habit of &lt;code&gt;config get-contexts&lt;/code&gt; before anything destructive. Most
production accidents are a command typed against the right object in the wrong
cluster.&lt;/p&gt;</description></item><item><title>Lab 06 - Finding your way around kubectl</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-06-finding-your-way/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-06-finding-your-way/index.html</guid><description>&lt;h1 id="lab-06---finding-your-way-around-kubectl"&gt;Lab 06 - Finding your way around kubectl&lt;/h1&gt;
&lt;span class="badge cstyle info badge-with-title"&gt;&lt;span class="badge-title"&gt;&lt;i class="fa-fw fas fa-info-circle"&gt;&lt;/i&gt; Info&lt;/span&gt;&lt;span class="badge-content"&gt;discovery&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; never need the internet to answer a Kubernetes question again.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-01/04-finding-your-way/"&gt;Finding your way&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each task states what you should end up seeing. Try it yourself first; the box
holds one working answer.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Task 1.&lt;/strong&gt; List every kind of object this cluster knows about, and find out
whether &lt;code&gt;ingresses&lt;/code&gt; is namespaced and what its short name is.&lt;/p&gt;</description></item><item><title>Lab 07 - Pods</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-07-pods/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-07-pods/index.html</guid><description>&lt;h1 id="lab-07---pods"&gt;Lab 07 - Pods&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; generate a Pod manifest, add resources, and see what a Pod really is.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-01/05-pods/"&gt;Pods&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - imperative: create and throw away&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl run bbox --image busybox --restart&lt;span class="o"&gt;=&lt;/span&gt;Never -- sleep &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl delete pod bbox
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--restart=Never&lt;/code&gt; is what makes &lt;code&gt;kubectl run&lt;/code&gt; produce a bare Pod instead of
something managed. &lt;code&gt;-- sleep 3600&lt;/code&gt; overrides the image&amp;rsquo;s command, because
busybox would otherwise exit immediately.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - generate the manifest instead&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl run bbox --image busybox --restart&lt;span class="o"&gt;=&lt;/span&gt;Never --dry-run&lt;span class="o"&gt;=&lt;/span&gt;client -o yaml &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -- sleep &lt;span class="m"&gt;3600&lt;/span&gt; &amp;gt; bbox.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat bbox.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Edit &lt;code&gt;bbox.yaml&lt;/code&gt; and add resources to the container:&lt;/p&gt;</description></item><item><title>Lab 08 - Pod troubleshooting</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-08-pod-troubleshooting/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-08-pod-troubleshooting/index.html</guid><description>&lt;h1 id="lab-08---pod-troubleshooting"&gt;Lab 08 - Pod troubleshooting&lt;/h1&gt;
&lt;span class="badge cstyle info badge-with-title"&gt;&lt;span class="badge-title"&gt;&lt;i class="fa-fw fas fa-info-circle"&gt;&lt;/i&gt; Info&lt;/span&gt;&lt;span class="badge-content"&gt;discovery&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; diagnose four broken Pods from cluster output alone.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/01-troubleshooting/"&gt;Troubleshooting routine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For each case: create the mess with the command given, then &lt;strong&gt;answer the
question before you open the box&lt;/strong&gt;. The routine is always
get -&amp;gt; describe -&amp;gt; logs.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="case-1---it-will-not-pull"&gt;Case 1 - it will not pull&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl run broken1 --image&lt;span class="o"&gt;=&lt;/span&gt;nginx:doesnotexist
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pod broken1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Question.&lt;/strong&gt; What state is it in, and where exactly does the cluster tell you
why?&lt;/p&gt;</description></item><item><title>Lab 09 - Namespaces</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-09-namespaces/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-09-namespaces/index.html</guid><description>&lt;h1 id="lab-09---namespaces"&gt;Lab 09 - Namespaces&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; scope your work and stop typing &lt;code&gt;-n&lt;/code&gt;.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/02-namespaces/"&gt;Namespaces&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - what exists now&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get ns
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Four namespaces come with every cluster. &lt;code&gt;kube-system&lt;/code&gt; holds the control plane
Pods - look but do not deploy there.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - declarative (recommended)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; ns-dev.yaml &lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;YAML&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kind: Namespace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: dev
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;YAML&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl apply -f ns-dev.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3 - imperative, for the throwaway one&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl create ns &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4 - the same name in both, with no conflict&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl run web --image nginx:1.27 -n dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl run web --image nginx:1.27 -n &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -n dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -A &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s1"&gt;&amp;#39; web &amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Names are unique &lt;strong&gt;per namespace per kind&lt;/strong&gt;. That is the whole point: dev and
prod can both have a &lt;code&gt;web&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Lab 10 - ReplicaSets</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-10-replicasets/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-10-replicasets/index.html</guid><description>&lt;h1 id="lab-10---replicasets"&gt;Lab 10 - ReplicaSets&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; watch the reconciliation loop, and see the selector do the binding.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/03-replicasets/"&gt;ReplicaSets&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - a ReplicaSet by hand (the only time you will write one)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; web-rs.yaml &lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;YAML&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;apiVersion: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kind: ReplicaSet
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: web-rs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; replicas: 3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; selector:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; matchLabels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; app: web
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; template:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; app: web
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; containers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; - name: web
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; image: nginx:1.27
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; resources:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; requests: { cpu: &amp;#34;20m&amp;#34;, memory: &amp;#34;32Mi&amp;#34; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;YAML&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl apply -f web-rs.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get rs,pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;web -o wide
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note the Pod names: &lt;code&gt;web-rs-&lt;/code&gt; plus a hash of the template plus a random suffix.
The controller owns them, which &lt;code&gt;kubectl get pod &amp;lt;name&amp;gt; -o yaml | grep -A5 ownerReferences&lt;/code&gt; will confirm.&lt;/p&gt;</description></item><item><title>Lab 11 - Deployments and probes</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-11-deployments/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-11-deployments/index.html</guid><description>&lt;h1 id="lab-11---deployments-and-probes"&gt;Lab 11 - Deployments and probes&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; roll forward, break it, roll back - and see why the break was harmless.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/04-deployments/"&gt;Deployments&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - generate, do not hand-write&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl create deploy web --image nginx:1.27 --replicas &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --dry-run&lt;span class="o"&gt;=&lt;/span&gt;client -o yaml &amp;gt; web-deploy.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl apply -f web-deploy.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get deploy,rs,pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;web
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Three objects for one command: the Deployment you asked for, the ReplicaSet it
created, and the Pods that ReplicaSet created.&lt;/p&gt;</description></item><item><title>Lab 12 - DaemonSets</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-12-daemonsets/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-12-daemonsets/index.html</guid><description>&lt;h1 id="lab-12---daemonsets"&gt;Lab 12 - DaemonSets&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; one Pod per node, and the two surprises that come with it.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/05-daemonsets/"&gt;DaemonSets&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - the cluster already runs several&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get ds -A
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -n kube-system -o wide &lt;span class="p"&gt;|&lt;/span&gt; grep -i -E &lt;span class="s1"&gt;&amp;#39;proxy|calico|cilium|flannel&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;kube-proxy and the CNI agent are DaemonSets: they must exist on every node,
including nodes that join tomorrow. There is no &lt;code&gt;replicas&lt;/code&gt; field anywhere - the
node list is the count.&lt;/p&gt;</description></item><item><title>Lab 13 - Taints, tolerations and affinity</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-13-scheduling/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-13-scheduling/index.html</guid><description>&lt;h1 id="lab-13---taints-tolerations-and-affinity"&gt;Lab 13 - Taints, tolerations and affinity&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; control where Pods land - and see the difference between &lt;em&gt;permitted&lt;/em&gt;
and &lt;em&gt;attracted&lt;/em&gt;.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/06-scheduling/"&gt;Scheduling&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="taints-repel"&gt;Taints repel&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - a baseline: 6 pods spread over the three workers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl create deploy filler --image nginx:1.27 --replicas &lt;span class="m"&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -o wide &lt;span class="p"&gt;|&lt;/span&gt; sort -k7
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - taint worker03 and watch new pods avoid it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl taint node worker03 &lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ssd:NoSchedule
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl describe node worker03 &lt;span class="p"&gt;|&lt;/span&gt; grep -i -A2 taint
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl scale deploy filler --replicas &lt;span class="m"&gt;12&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -o wide &lt;span class="p"&gt;|&lt;/span&gt; grep -c worker03 &lt;span class="c1"&gt;# unchanged&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Pods already on worker03 are still there. &lt;code&gt;NoSchedule&lt;/code&gt; only affects
&lt;em&gt;placement&lt;/em&gt;; it does not evict anything.&lt;/p&gt;</description></item><item><title>Lab 14 - Services</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-14-services/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-14-services/index.html</guid><description>&lt;h1 id="lab-14---services"&gt;Lab 14 - Services&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; reach Pods by a stable name, from inside and from outside.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/07-services/"&gt;Services&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - something to expose&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl create deploy web --image nginx:1.27 --replicas &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -l &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;web -o wide &lt;span class="c1"&gt;# note the Pod IPs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - ClusterIP, the default&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl expose deploy web --port &lt;span class="m"&gt;80&lt;/span&gt; --name web-svc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get svc web-svc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get endpointslices -l kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;web-svc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The EndpointSlice is the interesting object: it holds the three Pod IPs. The
Service is just a stable front; the EndpointSlice is the live membership list,
maintained by a controller as Pods become ready.&lt;/p&gt;</description></item><item><title>Lab 15 - Gateway API</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-15-gateway-api/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-15-gateway-api/index.html</guid><description>&lt;h1 id="lab-15---gateway-api"&gt;Lab 15 - Gateway API&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; install a Gateway controller and route two applications by host name
through one port - then split traffic between two versions.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/08-gateway-api/"&gt;Gateway API&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gateway API resources are only data. Two things must exist first: the &lt;strong&gt;CRDs&lt;/strong&gt;
(they are not part of Kubernetes) and a &lt;strong&gt;controller&lt;/strong&gt; that reads them.&lt;/p&gt;
&lt;h2 id="install-the-crds"&gt;Install the CRDs&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - the standard channel: GatewayClass, Gateway, HTTPRoute&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get crd &lt;span class="p"&gt;|&lt;/span&gt; grep gateway.networking
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl api-resources --api-group&lt;span class="o"&gt;=&lt;/span&gt;gateway.networking.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You have just extended the API server with new kinds - exactly the CRD mechanism
covered on Day 3, met here in the wild. Check
&lt;a href="https://github.com/kubernetes-sigs/gateway-api/releases" target="_blank"&gt;the releases page&lt;/a&gt; if
a newer version is out.&lt;/p&gt;</description></item><item><title>Lab 16 - Node operations</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-16-node-operations/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-16-node-operations/index.html</guid><description>&lt;h1 id="lab-16---node-operations"&gt;Lab 16 - Node operations&lt;/h1&gt;
&lt;span class="badge cstyle info badge-with-title"&gt;&lt;span class="badge-title"&gt;&lt;i class="fa-fw fas fa-info-circle"&gt;&lt;/i&gt; Info&lt;/span&gt;&lt;span class="badge-content"&gt;discovery&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; take a node out for maintenance and put it back, safely.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/09-nodes/"&gt;Nodes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Everything here is taints underneath - see
&lt;a href="https://training.caha.cloud/en/kubernetesintro/labs/lab-13-scheduling/"&gt;Lab 13&lt;/a&gt; if you want to
see the same effects expressed by hand.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# setup - something to move around&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl create deploy filler --image nginx:1.27 --replicas &lt;span class="m"&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -o wide &lt;span class="p"&gt;|&lt;/span&gt; sort -k7
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Task 1.&lt;/strong&gt; Stop new Pods from being scheduled on worker03, without disturbing
anything already running there. Expected: &lt;code&gt;kubectl get nodes&lt;/code&gt; shows
&lt;code&gt;Ready,SchedulingDisabled&lt;/code&gt; for worker03, and the Pods on it are untouched.&lt;/p&gt;</description></item><item><title>Lab 17 - ConfigMaps and Secrets</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-17-configmaps-secrets/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-17-configmaps-secrets/index.html</guid><description>&lt;h1 id="lab-17---configmaps-and-secrets"&gt;Lab 17 - ConfigMaps and Secrets&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; same image, different configuration - and learn which changes need a
restart.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/01-configmaps-secrets/"&gt;ConfigMaps and Secrets&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - from literals and from a file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;color=blue\nretries=3\n&amp;#39;&lt;/span&gt; &amp;gt; app.properties
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl create cm app-cfg &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --from-literal&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;DATACENTER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dc01 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --from-file&lt;span class="o"&gt;=&lt;/span&gt;app.properties
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get cm app-cfg -o yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--from-literal&lt;/code&gt; makes one key; &lt;code&gt;--from-file&lt;/code&gt; makes a key named after the file
whose value is the whole file. Both live in the same &lt;code&gt;data&lt;/code&gt; map.&lt;/p&gt;</description></item><item><title>Lab 18 - Persistent storage on NFS</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-18-persistent-storage/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-18-persistent-storage/index.html</guid><description>&lt;h1 id="lab-18---persistent-storage-on-nfs"&gt;Lab 18 - Persistent storage on NFS&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; give a Pod storage that survives it - with no StorageClass and no CSI
driver, the way an on-premise cluster really looks.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/02-storage/"&gt;Persistent storage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;support01 exports &lt;code&gt;/storage1&lt;/code&gt;, &lt;code&gt;/storage2&lt;/code&gt; and &lt;code&gt;/storage3&lt;/code&gt; over NFS. There is no
dynamic provisioning in this cluster, so &lt;strong&gt;you&lt;/strong&gt; write the PersistentVolume.&lt;/p&gt;
&lt;h2 id="prepare-the-nodes"&gt;Prepare the nodes&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - every node that mounts NFS needs the client tools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; n in worker01 worker02 worker03&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh student@&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;dpkg -l nfs-common &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; echo &amp;#34;$(hostname): ok&amp;#34; || sudo apt-get install -y nfs-common&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2 - prove the export works from a node, outside Kubernetes first&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh student@worker01 &lt;span class="s1"&gt;&amp;#39;sudo mkdir -p /mnt/t &amp;amp;&amp;amp; sudo mount -t nfs support01:/storage1 /mnt/t &amp;amp;&amp;amp; df -h /mnt/t &amp;amp;&amp;amp; sudo umount /mnt/t&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Always test the mount by hand before blaming Kubernetes. A Pod stuck in
&lt;code&gt;ContainerCreating&lt;/code&gt; with an NFS error is usually a missing &lt;code&gt;nfs-common&lt;/code&gt;, a wrong
export path, or export permissions.&lt;/p&gt;</description></item><item><title>Lab 19 - StatefulSets</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-19-statefulsets/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-19-statefulsets/index.html</guid><description>&lt;h1 id="lab-19---statefulsets"&gt;Lab 19 - StatefulSets&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; stable names, per-Pod storage, ordered start - and the clean-up
surprise.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/03-statefulsets/"&gt;StatefulSets&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This lab needs the three PVs from
&lt;a href="https://training.caha.cloud/en/kubernetesintro/labs/lab-18-persistent-storage/"&gt;Lab 18&lt;/a&gt;.
Check they are &lt;code&gt;Available&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl patch pv pv-storage1 -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;claimRef&amp;#34;:null}}&amp;#39;&lt;/span&gt; 2&amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="headless-service-first"&gt;Headless Service first&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 -&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; web-headless.yaml &lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;YAML&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;kind: Service
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; name: web-headless
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; clusterIP: None # headless - no virtual IP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; selector:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; app: web-sts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; ports:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; - port: 80
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;YAML&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl apply -f web-headless.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get svc web-headless &lt;span class="c1"&gt;# CLUSTER-IP is &amp;#34;None&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A normal Service hides the Pods behind one IP. A headless Service does the
opposite: DNS returns the individual Pod addresses, so each replica is
addressable by name. A StatefulSet requires one.&lt;/p&gt;</description></item><item><title>Lab 20 - Helm releases</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-20-helm-releases/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-20-helm-releases/index.html</guid><description>&lt;h1 id="lab-20---helm-releases"&gt;Lab 20 - Helm releases&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; install, configure, upgrade and roll back somebody else&amp;rsquo;s chart.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/04-helm-basics/"&gt;Helm basics&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Helm should already be installed from Lab 14. If not:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x get_helm.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo ./get_helm.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; helm version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - a repository&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm repo add podinfo https://stefanprodan.github.io/podinfo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm repo list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm search repo podinfo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm search repo podinfo --versions &lt;span class="p"&gt;|&lt;/span&gt; head -5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A repository is just a web server with an &lt;code&gt;index.yaml&lt;/code&gt;. &lt;code&gt;helm repo update&lt;/code&gt;
refetches that index - Helm does not go online for anything else until you
install.&lt;/p&gt;</description></item><item><title>Lab 21 - Writing your own chart</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-21-helm-chart-authoring/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-21-helm-chart-authoring/index.html</guid><description>&lt;h1 id="lab-21---writing-your-own-chart"&gt;Lab 21 - Writing your own chart&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; package an application so it can be installed many times with
different values.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/05-helm-charts/"&gt;Helm charts&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 - scaffold and read what you got&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm create shop
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find shop -type f &lt;span class="p"&gt;|&lt;/span&gt; sort
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat shop/Chart.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;head -30 shop/values.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;helm create&lt;/code&gt; gives you a working nginx chart with far more machinery than you
need. Reading it is worthwhile: it shows the conventions every public chart
follows.&lt;/p&gt;</description></item><item><title>Lab 22 - An operator: PostgreSQL</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-22-postgres-operator/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-22-postgres-operator/index.html</guid><description>&lt;h1 id="lab-22---an-operator-postgresql"&gt;Lab 22 - An operator: PostgreSQL&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; install a real operator, create a database cluster with one small
manifest, and watch the operator repair it.
&lt;strong&gt;Chapter:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/06-crds-operators/"&gt;CRDs and operators&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You will use &lt;a href="https://cloudnative-pg.io/" target="_blank"&gt;CloudNativePG&lt;/a&gt;, a PostgreSQL operator.
Everything you have learned so far applies: what the operator creates is
StatefulSet-like Pods, Services, Secrets and PVCs - objects you can already read.&lt;/p&gt;
&lt;h2 id="storage-first---and-it-must-be-dynamic"&gt;Storage first - and it must be dynamic&lt;/h2&gt;
&lt;p&gt;PostgreSQL is the first workload in this course that will &lt;strong&gt;not&lt;/strong&gt; run on the
static NFS PVs you wrote by hand. nginx ran as root and wrote to the export
root quite happily; the CloudNativePG image runs as the unprivileged &lt;code&gt;postgres&lt;/code&gt;
user (UID 26), and it cannot write into a root-owned NFS directory. The Pod
starts, &lt;code&gt;initdb&lt;/code&gt; fails on permissions, and the Pod crash-loops.&lt;/p&gt;</description></item><item><title>Lab 23 - Application end to end</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-23-application-end-to-end/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-23-application-end-to-end/index.html</guid><description>&lt;h1 id="lab-23---application-end-to-end"&gt;Lab 23 - Application end to end&lt;/h1&gt;
&lt;p&gt;&lt;span class="badge cstyle info badge-with-title"&gt;&lt;span class="badge-title"&gt;&lt;i class="fa-fw fas fa-info-circle"&gt;&lt;/i&gt; Info&lt;/span&gt;&lt;span class="badge-content"&gt;discovery&lt;/span&gt;&lt;/span&gt; &lt;em&gt;optional / if time permits&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; build, operate, break and fix a complete application using everything
from the three days.&lt;/p&gt;
&lt;p&gt;This lab gives you &lt;strong&gt;what&lt;/strong&gt;, not &lt;strong&gt;how&lt;/strong&gt;. Every command is in the
&lt;a href="https://training.caha.cloud/en/kubernetesintro/cheatsheets/"&gt;cheat sheets&lt;/a&gt;, in
&lt;code&gt;kubectl explain&lt;/code&gt;, or behind &lt;code&gt;--help&lt;/code&gt;.&lt;/p&gt;
&lt;div class="box notices cstyle tip"&gt;
&lt;div class="box-label"&gt;&lt;i class="fa-fw fas fa-lightbulb"&gt;&lt;/i&gt; Tip&lt;/div&gt;
&lt;div class="box-content"&gt;
&lt;p&gt;Each stage ends with an &lt;strong&gt;answer key&lt;/strong&gt; box. Try the stage first; open the box if
you get stuck or if you want to check your solution against one that works. Each
box is self-contained, so you can rejoin the lab at the start of any stage
without having done the previous one your own way. If you are completely lost,
jump to &lt;a href="#catch-up-in-one-paste"&gt;Catch up in one paste&lt;/a&gt; at the bottom.&lt;/p&gt;</description></item><item><title>Extended Lab A - Deploy KubeQuiz</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-24-extended-a-deploy/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-24-extended-a-deploy/index.html</guid><description>&lt;h1 id="extended-lab-a---deploy-kubequiz"&gt;Extended Lab A - Deploy KubeQuiz&lt;/h1&gt;
&lt;p&gt;&lt;span class="badge cstyle info badge-with-title"&gt;&lt;span class="badge-title"&gt;&lt;i class="fa-fw fas fa-info-circle"&gt;&lt;/i&gt; Info&lt;/span&gt;&lt;span class="badge-content"&gt;challenge&lt;/span&gt;&lt;/span&gt; &lt;em&gt;optional / after the course&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chapters:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/06-crds-operators/"&gt;CRDs and operators&lt;/a&gt;,
&lt;a href="https://training.caha.cloud/en/kubernetesintro/day-02/08-gateway-api/"&gt;Gateway API&lt;/a&gt;,
&lt;a href="https://training.caha.cloud/en/kubernetesintro/day-03/02-storage/"&gt;Persistent storage&lt;/a&gt;
&lt;strong&gt;Cheat sheet:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/cheatsheets/kubectl/"&gt;kubectl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This lab lives in a git repository, together with the application it deploys and
a script that grades your work. Everything runs on &lt;strong&gt;support01&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install -y git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/ecaha/kubequiz.git ~/kubequiz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/kubequiz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./labs/verify.sh a0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="box notices cstyle tip"&gt;
&lt;div class="box-label"&gt;&lt;i class="fa-fw fas fa-lightbulb"&gt;&lt;/i&gt; Tip&lt;/div&gt;
&lt;div class="box-content"&gt;
&lt;p&gt;A challenge lab gives you the &lt;strong&gt;task&lt;/strong&gt; and the &lt;strong&gt;result&lt;/strong&gt;, not the commands.
Each stage ends with a &lt;em&gt;Show one answer&lt;/em&gt; box - open it after you have tried, not
before. &lt;code&gt;./labs/verify.sh &amp;lt;stage&amp;gt;&lt;/code&gt; tells you PASS or FAIL per criterion, so you
never have to wait for anybody.&lt;/p&gt;</description></item><item><title>Extended Lab B - Ship a change</title><link>https://training.caha.cloud/en/kubernetesintro/labs/lab-25-extended-b-cicd/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/labs/lab-25-extended-b-cicd/index.html</guid><description>&lt;h1 id="extended-lab-b---ship-a-change"&gt;Extended Lab B - Ship a change&lt;/h1&gt;
&lt;p&gt;&lt;span class="badge cstyle info badge-with-title"&gt;&lt;span class="badge-title"&gt;&lt;i class="fa-fw fas fa-info-circle"&gt;&lt;/i&gt; Info&lt;/span&gt;&lt;span class="badge-content"&gt;challenge&lt;/span&gt;&lt;/span&gt; &lt;em&gt;optional / after the course&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisite:&lt;/strong&gt; &lt;a href="https://training.caha.cloud/en/kubernetesintro/labs/lab-24-extended-a-deploy/"&gt;Extended Lab A&lt;/a&gt;
finished and still running.
&lt;strong&gt;You also need:&lt;/strong&gt; a GitHub account and a personal access token.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; change one line of C#, and follow it all the way into the running
cluster without ever typing &lt;code&gt;kubectl apply&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Starting point:&lt;/strong&gt; Extended Lab A finished, with the app running from
&lt;code&gt;ghcr.io/ecaha/...&lt;/code&gt; and outbound internet from support01 and the cluster nodes.&lt;/p&gt;</description></item></channel></rss>