4.5.12 · D4Software Engineering

Exercises — Kubernetes — pods, deployments, services, ingress (concepts)

2,272 words10 min readBack to topic

Before any counting problem, one picture fixes the vocabulary. The number line below is the available-Pods bar we will reuse: how many healthy copies exist at each moment of an update.

Figure — Kubernetes — pods, deployments, services, ingress (concepts)

Level 1 — Recognition

Goal: can you name the object and recall its one job?

Exercise 1.1 (L1)

Match each job to exactly one object — Pod, Deployment, Service, Ingress: (a) "Give me one stable virtual IP that spreads traffic over many copies." (b) "Route api.site.com and site.com/shop to different backends over HTTPS." (c) "The actual place my container process runs." (d) "Keep 3 identical copies alive and upgrade them one at a time."

Recall Solution

(a) Service — stable virtual IP + load balancing across matching Pods. (b) Ingress — L7 HTTP(S) router by host/path with TLS termination. (c) Pod — smallest deployable unit, where the container actually runs. (d) Deployment — controller keeping a replica count and doing rolling updates.

Exercise 1.2 (L1)

True or false, with one-line reason each: (a) A Pod that dies is restarted with the same IP. (b) A ClusterIP Service is reachable from the public internet. (c) An Ingress works without any Ingress Controller running.

Recall Solution

(a) False. Pods are ephemeral; a new Pod with a new IP appears — never the same identity. (b) False. ClusterIP is reachable only inside the cluster; expose it via NodePort, LoadBalancer, or an Ingress. (c) False. An Ingress is only a rule-set. Rules do nothing unless an Ingress Controller (nginx, Traefik, …) is running to enforce them.


Level 2 — Application

Goal: apply one formula or rule to concrete numbers.

Exercise 2.1 (L2) — Endpoints after scaling

A Service selects app=cart. The Deployment runs replicas: 3, so 3 Pods carry that label. You scale to replicas: 8. How many entries are in the Service's Endpoints list now, and how many clients must you reconfigure?

Recall Solution

Each new Pod is created from the same template, so it also carries app=cart. The Service's label selector automatically picks up all matching healthy Pods. Endpoints = 8. Clients to reconfigure = 0 — the Service IP and DNS name never change. That zero is the whole payoff of indirection.

Exercise 2.2 (L2) — Minimum available during an update

A Deployment has replicas = 10, maxUnavailable = 2, maxSurge = 3. Using compute (a) the minimum number of available Pods during the rollout, and (b) the maximum total Pods that may briefly exist.

Recall Solution

(a) Minimum available . (b) Maximum total . So capacity never dips below 8 (zero-downtime), while up to 13 Pods can co-exist for a moment. Look at the bar in s01: the shaded floor is the "min available" line.

Exercise 2.3 (L2) — Percentage knobs

Same Deployment, replicas = 10. Now the knobs are given as percentages: maxUnavailable = 25\%, maxSurge = 50\%. Kubernetes rounds maxUnavailable down and maxSurge up. Find both as whole Pods, then the min-available and max-total.

Recall Solution

. . Min available . Max total .


Level 3 — Analysis

Goal: reason about why a design breaks and what fixes it.

Exercise 3.1 (L3) — The hardcoded IP incident

A team points client code at 10.1.4.7, the IP of a payments Pod. It works for a week, then payments break every few days at 3 a.m. Explain the failure mechanism and the one-object fix.

Recall Solution

Pods are mortal. Nightly node maintenance / autoscaling reschedules the payments Pod; the replacement gets a new IP (e.g. 10.1.9.2). The clients still dial the dead 10.1.4.7 → connection refused. Fix: put a Service (ClusterIP) in front. Clients dial the stable Service DNS name; the Service's Endpoints list is auto-updated to the current Pod IP. This is the classic "add a layer of indirection over a moving target."

Exercise 3.2 (L3) — Selector mismatch

A Service has selector app: web, tier: frontend. The Deployment's Pod template has labels app: web only. kubectl get endpoints web-svc shows 0 endpoints even though 3 Pods are healthy. Why, and what is the minimal fix?

Recall Solution

A Service selector is an AND of all its key/value pairs. A Pod joins the Endpoints only if it matches every pair. The Pods match app=web but are missing tier=frontend, so none match → 0 endpoints → all traffic fails. Minimal fix: add tier: frontend to the Pod template's labels (or drop tier: frontend from the selector). Match the sets exactly.

Exercise 3.3 (L3) — Rollout that stalls

replicas = 4, maxSurge = 0, maxUnavailable = 0. You push a new image. Nothing rolls out — it hangs. Explain using the two inequalities.

Recall Solution

With : total Pods can never exceed , so no new Pod can be created without first removing an old one. With : available must stay , so no old Pod may be removed either. The two knobs together forbid both adding and removing → the rollout deadlocks. Fix: set at least one knob to (commonly maxSurge: 1).


Level 4 — Synthesis

Goal: assemble multiple objects into a working design and quantify it.

Exercise 4.1 (L4) — Cost of LB-per-service vs Ingress

You expose 6 microservices to the internet. Cloud LoadBalancers cost $18/month each and each consumes one public IP. Compare two designs: (a) one LoadBalancer Service per microservice; (b) one Ingress (backed by one LB) routing by host/path to 6 ClusterIP Services. Give LB count, public-IP count, and monthly cost for each, and the saving.

Recall Solution

(a) 6 LoadBalancers → 6 LBs, 6 public IPs, cost = 6 \times 18 = \108/\text{month}= 1 \times 18 = $18/\text{month}= 108 - 18 = $90/\text{month}$** (and 5 fewer public IPs). This is exactly why Ingress exists: one L7 entry point routing by URL beats one dumb L4 LB per service.

Exercise 4.2 (L4) — Trace the full request path

For https://shop.example.com/cart with a cart Deployment at replicas: 3, list the 4 hops (which object, what it does) and state what happens to an in-flight request if the serving Pod dies mid-request.

Recall Solution
  1. DNS resolves shop.example.com → the Ingress Controller's external IP (the internet only knows public DNS).
  2. Ingress matches host + path /cart, terminates TLS, forwards to cart-service (L7 routing).
  3. Service (ClusterIP) load-balances via selector app=cart to one healthy Pod (stable target, Load Balancing).
  4. Pod runs the container and replies. If the serving Pod dies: the Deployment keeps replicas: 3, so a new Pod is created; the Service's readiness checks drop the dead Pod from Endpoints and route the client's retry to a live one — hence no permanent outage.

Level 5 — Mastery

Goal: design under constraints, prove the guarantee, connect to the pipeline.

Exercise 5.1 (L5) — Choose knobs to meet an SLA

A service must keep at least 12 Pods serving at all times (an SLA) and normally runs replicas = 15. Node capacity allows at most 20 Pods of this app to co-exist. Choose the largest legal maxUnavailable and maxSurge, and verify both constraints.

Recall Solution

SLA: . Largest . Capacity: . Largest . Check: min available ✓ (SLA exactly met); max total ✓ (capacity exactly met). See s02.

Figure — Kubernetes — pods, deployments, services, ingress (concepts)

Exercise 5.2 (L5) — Design a two-app cluster

Design objects to serve api.site.com (a stateless API, needs 4 copies, zero-downtime deploys from your CI-CD Pipelines) and site.com/shop (a shop UI, 2 copies), both over HTTPS through one entry point. List every object and its key field. State how many public IPs you use.

Recall Solution

Objects:

  • Deployment apireplicas: 4, Pod label app: api, strategy e.g. maxSurge: 1, maxUnavailable: 0 (strict zero-downtime).
  • Service api-svc — type ClusterIP, selector app: api.
  • Deployment shopreplicas: 2, Pod label app: shop.
  • Service shop-svc — type ClusterIP, selector app: shop.
  • One Ingress — rule host: api.site.com → api-svc; rule host: site.com, path: /shop → shop-svc; TLS termination for both.
  • Ingress Controller running (nginx/Traefik) exposed via one LoadBalancer. Public IPs used: 1 (the Ingress LB). CI/CD updates the image tag in a Deployment; the reconciliation loop rolls Pods within the knobs → no client touches the change.

Exercise 5.3 (L5) — Prove the zero-downtime bound

Show that during any rolling update, the fraction of promised capacity that stays available is at least . Evaluate it for Exercise 5.1's numbers.

Recall Solution

Available Pods satisfy at every instant (the update controller never removes a Pod that would violate this). Dividing by the promised count : For , : fraction , i.e. at least 80% capacity throughout — the guaranteed floor.