diff --git a/pilot/arc.tpl.html b/pilot/arc.tpl.html index fa635f5..bfdb284 100644 --- a/pilot/arc.tpl.html +++ b/pilot/arc.tpl.html @@ -15,7 +15,7 @@
  • Course IIKubernetes - a cluster is a promise, not a place
  • Course IIIaThe node - where intent becomes a process
  • Course IIIbThe pod - one IP, shared fate
  • -
  • Course IVThe traffic - pods are cattle, Services are the brand
  • +
  • Course IVThe traffic - pods die constantly, the address does not
  • Course VOpenShift - Kubernetes with opinions, and a security guard
  • Course VIGitOps - nobody deploys anything; the cluster syncs itself
  • Course VIIThe image supply chain - a tag is a promise, a digest is a fact
  • @@ -72,6 +72,8 @@ OpenShift's CLI. Everything shown works identically with kubectl - oc is a superset that adds OpenShift's own verbs. Read kubectl in the docs, type whichever your cluster gives you.

    +

    That 1/1 reads as containers-ready over containers-wanted: a pod + can hold more than one, which is Course IIIb.

    An image got built - of what, exactly? Pushed - to where, and what travelled? Applied - which is not the same as launched. Running - according to whom? Every course below takes one of those words apart. The armour is already loose.

    @@ -165,7 +167,7 @@
    -

    Desired against actual, forever

    +

    Desired against actual, on a loop

    The habit underneath everything: the reconciliation loop - compare desired state against actual state, fix the difference, repeat. That oc apply didn't launch anything; it filed paperwork. The machine took it from there, and it never @@ -230,8 +232,8 @@ runtime pulls the image (through the mirror of Course VII) and actually creates and starts the container, handing the low-level work to runc or crun. A CNI plugin hands the pod a real IP, and kube-proxy - or an eBPF datapath replacing it - makes Service - addresses route to real pods. The kubelet drives and the runtime executes - and it is the - runtime, not the kubelet, that calls the CNI plugin to wire the pod up.

    + addresses route to real pods - and it is the runtime, not the kubelet, that calls the CNI + plugin to wire the pod up.

    The kubelet decides what should run. The runtime is what starts it.

    Field note. Node NotReady? Check kubelet-to-API-server connectivity before anything else - a node that cannot phone home is presumed lost.

    @@ -280,7 +282,11 @@ It does not say by whom. The kernel's OOM killer surfaces as reason OOMKilled; a failed liveness probe shows up in the pod's events; eviction and node pressure look different again. One exit code, several possible crimes - read the termination reason and the events, never - the number alone.

    + the number alone: oc describe pod <name> shows both together, + and oc logs --previous shows what the dead container said on its + way out. Worth connecting to what you already know: a memory limit becomes a + cgroup ceiling, and the kernel's OOM killer enforces it exactly as it would for any + other process on the box.

    The pod is the smallest schedulable unit - the jacket, never the container. Once that distinction lands, half of Kubernetes networking stops being mysterious.

    @@ -294,7 +300,7 @@

    Course IV · The traffic

    -

    Pods are cattle.
    Services are the brand.

    +

    Pods die constantly.
    The address does not.

    Pods die, respawn and change addresses - and traffic still arrives. Scroll, and the delivery route assembles checkpoint by checkpoint; watch what happens to the pod that stops answering.

    @@ -315,6 +321,20 @@

    A Service is the fixed point: a ClusterIP inside, a LoadBalancer at the edge, Ingress or the Gateway API doing host- and path-routing above. Clients hold the name; the pods behind it come and go without anyone being told.

    +

    How a Service actually finds its pods

    +

    A Service holds no list of pods. It holds a label selector - match + app: api - and a controller continuously matches that against every + pod in the namespace, keeping the passing set in an EndpointSlice. Labels are how + everything here finds everything else, from a Service picking pods to a fleet hub picking + whole clusters (Course VI). Wear the label and you are eligible; readiness decides whether + you stay.

    +

    And the ClusterIP is worth a Linux translation: no interface owns that address. + Nothing answers ARP for it. It exists as a rule - kube-proxy programs iptables (or + IPVS) on every node so packets aimed at the virtual IP are DNATed to one of the ready pod + IPs, and an eBPF dataplane does the same job further down without the rule tables. Cluster + DNS - CoreDNS - resolves api.myns.svc.cluster.local to that + VIP. If you have ever written a DNAT rule by hand, you have already built a small Service.

    +

    Readiness decides membership

    A pod failing its readiness probe silently leaves the pool. No error, no event at the client - traffic simply stops arriving. That is the feature: broken instances remove @@ -327,7 +347,7 @@

    Field note. "The network is broken" after a deploy is usually readiness telling the truth about your app - not the network lying about your packets.

    The dark pod in the scene is not an error state - it is the system - working. Membership is earned per probe, continuously, forever.

    + working. Membership is re-earned every few seconds, by every pod, for as long as it serves.

    Pre-reads: C-III's pod scene (readiness lives there)  Further: Services and networking

    @@ -369,8 +389,8 @@

    Field note. Deployment stuck at 0/1 with no pod at all? The refusal happened above scheduling - read the ReplicaSet events. The error lives a level up.

    -

    Everything in the ring is opinion wrapped around the same core you - already know. Learn the core once; the opinions are just house rules.

    +

    Everything in the ring wraps the same core you already know. What + OpenShift adds is a house style with teeth - and admission is where it bites first.

    Pre-reads: C-II  Further: OpenShift documentation · Red Hat OpenShift

    @@ -385,8 +405,7 @@

    The mental model everyone arrives with: someone with credentials pushes manifests at the cluster. In the architecture this course teaches, nothing is pushed: a repository holds the desired state, an agent inside the cluster watches it, and the cluster pulls its own future - from git. oc is for - looking; git is for changing.

    + from git.

    @@ -517,8 +536,8 @@ the through-line.

    If the digest changed, it is not a promotion - it is a new candidate.

    Names that can move are convenient exactly until they move. Address content - by what it is, and the supply chain stops being a chain of trust and becomes a chain of - arithmetic.

    + by what it is, and the supply chain stops resting on trust: it rests on a hash anyone can + check.

    Pre-reads: C-I · Kubernetes imagesFurther: zot · @@ -578,9 +597,8 @@ later as enforcement pointed at nothing.

    Field note. The failure you want is the render that refuses. It costs a red pipeline. The alternative reports healthy the whole time.

    -

    Fleet consistency is not a discipline problem, it is a construction - problem. Divergence stops being something you police and becomes something the tooling cannot - express.

    +

    Consistency stops being something you police and becomes something the + tooling cannot express.

    Pre-reads: C-II · Kubernetes objectsFurther: Helm docs ·