<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Day 1 on Eriks training corner</title><link>https://training.caha.cloud/en/kubernetesintro/day-01/index.html</link><description>Recent content in Day 1 on Eriks training corner</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://training.caha.cloud/en/kubernetesintro/day-01/index.xml" rel="self" type="application/rss+xml"/><item><title>Services and microservices</title><link>https://training.caha.cloud/en/kubernetesintro/day-01/01-microservices/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/day-01/01-microservices/index.html</guid><description>&lt;h1 id="services-and-microservices"&gt;Services and microservices&lt;/h1&gt;
&lt;h2 id="monolith"&gt;Monolith&lt;/h2&gt;
&lt;p&gt;One artifact, one deployment, one runtime. Internal calls are method calls.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; single deployable, no network between modules.
&lt;strong&gt;Cons:&lt;/strong&gt; long release cycle, scales only as a whole, hard to split across teams.&lt;/p&gt;
&lt;h2 id="microservices"&gt;Microservices&lt;/h2&gt;
&lt;div class="mermaid align-center"&gt;graph LR
C[Clients] --&amp;gt; G[API Gateway]
G --&amp;gt; B[Book service]
G --&amp;gt; R[Review service]
B --&amp;gt; BD[(Book DB)]
R --&amp;gt; RD[(Review DB)]&lt;/div&gt;&lt;p&gt;Each service is developed, deployed, scaled and upgraded separately and may own
its own database.&lt;/p&gt;</description></item><item><title>Containers and images</title><link>https://training.caha.cloud/en/kubernetesintro/day-01/02-containers-and-images/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/day-01/02-containers-and-images/index.html</guid><description>&lt;h1 id="containers-and-images"&gt;Containers and images&lt;/h1&gt;
&lt;h2 id="container-vs-virtual-machine"&gt;Container vs virtual machine&lt;/h2&gt;
&lt;div class="mermaid align-center"&gt;graph TB
subgraph VMs
H1[Hardware] --&amp;gt; HV[Hypervisor]
HV --&amp;gt; G1[Guest OS &amp;#43; App]
HV --&amp;gt; G2[Guest OS &amp;#43; App]
end
subgraph Containers
H2[Hardware] --&amp;gt; OS[Host OS kernel]
OS --&amp;gt; CR[Container runtime]
CR --&amp;gt; C1[App]
CR --&amp;gt; C2[App]
end&lt;/div&gt;&lt;p&gt;A container is a process on the host kernel, isolated by namespaces and limited
by cgroups. No guest OS, so start-up is milliseconds.&lt;/p&gt;
&lt;h2 id="image"&gt;Image&lt;/h2&gt;
&lt;p&gt;Read-only template built from &lt;strong&gt;layers&lt;/strong&gt;; each Dockerfile instruction adds one.
Layers are shared and cached. The running container adds one thin writable layer
that disappears when the container is removed - which is why data belongs in a
volume.&lt;/p&gt;</description></item><item><title>Kubernetes basics</title><link>https://training.caha.cloud/en/kubernetesintro/day-01/03-kubernetes-basics/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/day-01/03-kubernetes-basics/index.html</guid><description>&lt;h1 id="kubernetes-basics"&gt;Kubernetes basics&lt;/h1&gt;
&lt;p&gt;Started at Google in 2014, built on Borg (2003) and Omega (2013), donated to the
CNCF in 2015.&lt;/p&gt;
&lt;h2 id="the-one-big-idea"&gt;The one big idea&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Desired state vs current state.&lt;/strong&gt; You declare what you want; controllers
compare it with reality and act until the two match. Everything else is a
variation on this loop.&lt;/p&gt;
&lt;div class="mermaid align-center"&gt;graph LR
U[You: manifest] --&amp;gt; A[API server]
A --&amp;gt; E[(etcd - desired state)]
C[Controller] --&amp;gt; A
C --&amp;gt; C
C --&amp;gt;|create / delete| K[kubelet on node]
K --&amp;gt;|reports current state| A&lt;/div&gt;&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;
&lt;div class="mermaid align-center"&gt;graph TB
subgraph control01 [Control plane]
API[kube-apiserver]
ETCD[(etcd)]
SCH[kube-scheduler]
CM[kube-controller-manager]
end
subgraph worker0X [Worker node]
KL[kubelet]
KP[kube-proxy]
CRI[containerd]
end
API --- ETCD
SCH --- API
CM --- API
KL --- API
KP --- API
KL --- CRI&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;kube-apiserver&lt;/td&gt;
&lt;td&gt;the only door to the cluster; REST + validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;etcd&lt;/td&gt;
&lt;td&gt;stores the desired state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kube-scheduler&lt;/td&gt;
&lt;td&gt;picks a node for each new Pod&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kube-controller-manager&lt;/td&gt;
&lt;td&gt;runs the reconciliation loops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kubelet&lt;/td&gt;
&lt;td&gt;runs and watches containers on its node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kube-proxy&lt;/td&gt;
&lt;td&gt;implements Service networking on its node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;containerd&lt;/td&gt;
&lt;td&gt;the container runtime (CRI)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="pluggable-by-standard"&gt;Pluggable by standard&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CRI&lt;/strong&gt; - runtime. Docker is not a CRI runtime and has not been supported
since 1.24; this cluster runs containerd.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CNI&lt;/strong&gt; - networking plugin.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSI&lt;/strong&gt; - storage drivers. This cluster has none, which is why the storage lab
builds PersistentVolumes by hand.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="imperative-vs-declarative"&gt;Imperative vs declarative&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 web01 --image nginx &lt;span class="c1"&gt;# imperative: an action&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl apply -f pod.yaml &lt;span class="c1"&gt;# declarative: a desired state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Imperative is for exploring. Everything that must survive gets versioned as YAML
and applied. Only &lt;code&gt;apply&lt;/code&gt; is idempotent.&lt;/p&gt;</description></item><item><title>Finding your way around kubectl</title><link>https://training.caha.cloud/en/kubernetesintro/day-01/04-finding-your-way/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/day-01/04-finding-your-way/index.html</guid><description>&lt;h1 id="finding-your-way-around-kubectl"&gt;Finding your way around kubectl&lt;/h1&gt;
&lt;p&gt;Nobody memorises the Kubernetes API. The cluster can describe itself, and this
chapter is how you make it do that. Everything here works offline, against the
version you are actually running - which is more than the internet can promise.&lt;/p&gt;
&lt;h2 id="what-kinds-of-object-exist"&gt;What kinds of object exist?&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 api-resources
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl api-resources &lt;span class="p"&gt;|&lt;/span&gt; grep -i ingress
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl api-resources --namespaced&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;# cluster-scoped kinds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The output gives you four things per kind: the plural name you type, its short
name (&lt;code&gt;deploy&lt;/code&gt;, &lt;code&gt;svc&lt;/code&gt;, &lt;code&gt;po&lt;/code&gt;), the API group and version, and whether it is
namespaced.&lt;/p&gt;</description></item><item><title>Pods</title><link>https://training.caha.cloud/en/kubernetesintro/day-01/05-pods/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://training.caha.cloud/en/kubernetesintro/day-01/05-pods/index.html</guid><description>&lt;h1 id="pods"&gt;Pods&lt;/h1&gt;
&lt;p&gt;The smallest schedulable unit. Not a container - an &lt;em&gt;environment&lt;/em&gt; for one or
more containers.&lt;/p&gt;
&lt;div class="mermaid align-center"&gt;graph TB
subgraph pod [Pod - one IP, one network namespace]
C1[container: app]
C2[container: sidecar]
V[(shared volume)]
C1 --- V
C2 --- V
end&lt;/div&gt;&lt;p&gt;Containers in a Pod share the IP address, ports, IPC and volumes, and always run
on the same node. They talk over &lt;code&gt;localhost&lt;/code&gt;. This is the &lt;code&gt;--network container:&lt;/code&gt;
mode from Docker, made into a first-class object.&lt;/p&gt;</description></item></channel></rss>