feat(root): author networking and configuration curriculum

root-07-m03-services-and-service-discovery — a new, full gold-standard-
pattern module: the Service/Endpoints/DNS request path, choosing the
right Service type. Lesson, demonstration (a Service with zero
Endpoints — the single fastest diagnostic check for this failure
class), knowledge check, guided exercise (ClusterIP vs. NodePort vs.
LoadBalancer for three real components), a real Lab
(expose-service-basics), and a reflection.

root-07-m04-ingress-networkpolicy-foundations — a new PARTIAL module:
Ingress and NetworkPolicy at the architectural level (the security-
control framing of NetworkPolicy is deliberately deferred to ROOT 09).
Lesson + knowledge check + real Labs (ingress-task, network-policy).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-26 09:06:19 -05:00
co-authored by Claude Sonnet 5
parent 86ea035e9b
commit dbcc210889
8 changed files with 481 additions and 0 deletions
@@ -0,0 +1,90 @@
# Ingress and NetworkPolicy: What They Architecturally Do
## Ingress: routing external HTTP(S) traffic by host/path
You already know a LoadBalancer Service can expose something to the public internet. But a real
application usually needs more than "one raw IP to one Service" — you might want
`api.example.com` and `app.example.com` to route to different backend Services, all through one
entry point, with TLS termination handled in one place instead of per-Service.
**Ingress** is the Kubernetes object for exactly this: a set of HTTP routing rules (by hostname
and/or URL path) that an Ingress controller reads and turns into actual load-balancer/proxy
configuration.
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port: { number: 80 }
```
An important distinction: Ingress is a set of ROUTING RULES, not a load balancer itself — an
Ingress controller (a separate piece of software running in the cluster) is what actually reads
these rules and does the routing. Without a controller installed, an Ingress object exists in
the API but nothing acts on it.
## NetworkPolicy: traffic reachability as something you declare, not assume
By default, every Pod in a Kubernetes cluster can reach every other Pod — there is no built-in
network isolation between them at all. This surprises people coming from a "obviously the
network is locked down unless configured otherwise" assumption. It is exactly backwards from
that assumption: **everything is reachable until you say otherwise.**
A NetworkPolicy changes this for the Pods it selects, by declaring which traffic IS allowed —
everything not explicitly allowed to a Pod covered by at least one NetworkPolicy is then denied.
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
podSelector:
matchLabels: { app: backend }
ingress:
- from:
- podSelector:
matchLabels: { app: frontend }
```
This example allows traffic to `backend` Pods only from `frontend` Pods — once this policy
exists and selects `backend`, every OTHER Pod trying to reach `backend` is now blocked, even
though nothing was true about that before the policy existed.
## Why this matters architecturally, before it matters as a security control
Right now, think of NetworkPolicy purely as "declaring intended reachability, not assuming it."
ROOT 09 comes back to NetworkPolicy specifically as a SECURITY control (default-deny postures,
least-privilege network access) — this module is deliberately just the architectural mental
model: Kubernetes doesn't isolate network traffic for you by default, and NetworkPolicy is the
mechanism for declaring the reachability you actually intend.
## Instructor Notes
**Approximate timing:** 15 minutes read; 10 minutes live.
**Likely misconceptions to watch for:**
- Students often assume Ingress by itself "does" the routing. Emphasize the controller
requirement — an Ingress object with no controller installed does nothing.
- The "everything reachable by default" fact genuinely surprises most students the first time
they hear it — it's worth stating plainly and letting it land rather than rushing past it.
**Discussion question:** "If NO NetworkPolicy exists anywhere in a Namespace, what's the actual
reachability between Pods in that Namespace?" (Answer: completely open — every Pod can reach
every other Pod, matching the "everything reachable by default" rule.)
**Optional extension:** ask what would happen if you created a NetworkPolicy that selects
`frontend` Pods but declares no `ingress` rules at all (answer: `frontend` Pods would become
completely unreachable by anything — an empty ingress list inside a NetworkPolicy that HAS an
ingress policyType means "deny all incoming," not "no policy applies").
@@ -0,0 +1,46 @@
# Knowledge Check: Ingress & NetworkPolicy Foundations
---
**1. You create an Ingress object with correct routing rules, but no traffic is ever routed
according to them. What's the most likely reason?**
*Answer:* No Ingress controller is installed/running in the cluster. Ingress objects are just
routing rules; a separate controller has to actually read and act on them, or nothing happens.
---
**2. True or false: by default, a Pod in Namespace A cannot reach a Pod in Namespace B unless a
NetworkPolicy explicitly allows it.**
*Answer:* False — the opposite is true by default. With NO NetworkPolicy in place at all,
every Pod can reach every other Pod regardless of Namespace. NetworkPolicy is what RESTRICTS
this default-open behavior, not what's required to enable connectivity in the first place.
---
**3. A NetworkPolicy selects Pods labeled `app: backend` and declares one ingress rule allowing
traffic from Pods labeled `app: frontend`. What happens to traffic from a Pod labeled
`app: admin-tool` trying to reach `backend`?**
*Answer:* It's blocked. Once a NetworkPolicy selects a Pod, only traffic matching one of its
explicit rules is allowed — everything else to that Pod is denied, including traffic that would
have worked fine before the policy existed.
---
**4. Why is Ingress the right tool for exposing an HTTP application by hostname, rather than
creating a separate LoadBalancer Service per hostname?**
*Answer:* A LoadBalancer Service typically provisions its own external IP/load balancer per
Service — one per hostname would mean paying for and managing N separate external endpoints.
Ingress lets one entry point route to many backend Services by hostname/path, which is both
cheaper and centralizes concerns like TLS termination.
## Instructor Notes
**Facilitation:** Question 2 catches a very common and consequential misconception — worth
confirming out loud that everyone actually updated their mental model, not just guessed
correctly.
**Approximate timing:** 5 minutes.