- Core
- 90 min
- 10 min read
- You marked this lesson done
- Updated
After this lesson you can
- Read a deployment and a service manifest and say what they do
- Spot missing resource limits, missing health checks and risky settings
- Explain how config and secrets should be kept apart from images
- Direct an agent to write a manifest to a spec and verify it with a checklist
Read these first
Lesson 2 of the Kubernetes and GitOps track. It supports the Master Developer delivery spine, stage “deployment”. Lesson 1 should come first.
1. Why this matters
A manifest is a file that declares what you want Kubernetes to run. It is the thing an agent will write, change and propose in a merge request. If you can read one, you can judge what the agent did. If you cannot, you are approving a diff you do not understand, and with infrastructure that is how outages and breaches start.
A manifest is also a very good thing to review, because it is short, structured and has a small set of common faults. This lesson gives you the reading method and the fault list.
| The 2030 PDM decides | Delegates to agents | Verifies by | Other disciplines |
|---|---|---|---|
| How many copies, how much capacity is reserved, what a healthy service means, what is exposed | Writing and changing manifests, explaining a diff, templating for several environments | Reading with the checklist below, comparing the diff to the spec, checking that nothing secret is in the file | Operations (capacity and health), security (exposure, secrets), finance (what the limits cost), engineering (what “healthy” means in the code) |
2. Key ideas, explained
The shape of every manifest
Every Kubernetes object is a YAML file with the same four top-level parts.
| Part | What it says |
|---|---|
apiVersion and kind |
What type of object this is (Deployment, Service, and so on) |
metadata |
Its name, namespace and labels |
spec |
What you want: the desired state |
status |
Written by Kubernetes, not by you: the actual state |
You write spec. Kubernetes fills status. The Workloads documentation explains the main kinds.
A deployment, read line by line
apiVersion: apps/v1
kind: Deployment
metadata:
name: signup
namespace: trailmug
labels:
app: signup
spec:
replicas: 3
selector:
matchLabels:
app: signup
template:
metadata:
labels:
app: signup
spec:
containers:
- name: signup
image: registry.example.org/trailmug/signup@sha256:ab12...
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
memory: "256Mi"
readinessProbe:
httpGet:
path: /ready
port: 8080
livenessProbe:
httpGet:
path: /healthy
port: 8080
envFrom:
- configMapRef:
name: signup-config
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
Reading it, as questions and answers:
- What runs? The container image named under
image. Is it pinned by digest (@sha256:) as CI/CD lesson 2 taught, not a floating tag likelatest? - How many?
replicas: 3. Three copies. What happens if two nodes fail? - How much does it reserve and how much may it use?
requestsis what the scheduler sets aside,limitsis the ceiling. The resource management page explains the units:100mmeans a tenth of a processor core,Mimeans mebibytes of memory. - How is health checked?
readinessProbesays when a pod may receive traffic.livenessProbesays when a pod is stuck and must be restarted. See Configure probes. - Where do settings come from?
envFromreads a ConfigMap. No settings or secrets are inside the image. - Does it run safely?
runAsNonRootandallowPrivilegeEscalation: falseare the two lines to look for. They limit damage if the software is compromised.
The service that goes with it
apiVersion: v1
kind: Service
metadata:
name: signup
namespace: trailmug
spec:
selector:
app: signup
ports:
- port: 80
targetPort: 8080
The service finds pods whose labels match app: signup and sends traffic to the healthy ones. If the labels in the service and the deployment do not match, the service has no pods and the product is silently down. That mismatch is one of the most common simple faults.
The type of service matters for exposure. The default keeps it inside the cluster. A LoadBalancer type asks the cloud for a public address. An Ingress routes web traffic by name. Always ask: which of these are reachable from the internet, and should they be?
Requests and limits
Without requests, the scheduler cannot place pods sensibly. Without memory limits, one buggy pod can eat a whole node. With CPU limits too tight, the service slows. A sensible starting point is requests close to typical use, and a memory limit with some headroom. Do not guess; measure (the observability track covers how). The cost link is direct: requests decide how many nodes you need.
Probes: readiness and liveness
A readiness probe answers “can I take traffic now?”. A pod that is starting up or temporarily overloaded fails readiness and is taken out of rotation without being killed. A liveness probe answers “am I stuck?”. If it fails, Kubernetes restarts the pod. Two common faults:
- No probes at all. Kubernetes assumes healthy as soon as the process starts, and sends traffic to a pod that is not ready.
- A liveness probe that checks a dependency, such as the database. When the database is slow, every pod is declared stuck and restarted together, which makes the outage worse.
Config and secrets
Keep settings out of the image (the Twelve-Factor idea from the Cloud platforms track). Non-sensitive settings go in a ConfigMap. Sensitive ones go in a Secret. A Secret in Kubernetes is only encoded, not encrypted, by default. Anyone who can read the Secret object can read the value. The Secrets page explains the protections to add: restrict who can read them, enable encryption at rest, and prefer an external secret manager.
The absolute rule: no real secret value appears in a manifest in git. If an agent writes password: hunter2, or a base64 string that decodes to a password, reject the change and rotate the value. Teams use sealed or encrypted secrets, or a controller that pulls from a secret manager, so that the file in git holds only a reference or an encrypted blob.
Namespaces and labels
Namespaces separate environments or teams. Labels let objects find each other and let you group them for cost and ownership. A manifest with no namespace lands in the default one, which is a sign of carelessness. Ask for consistent labels: app name, owner, environment, and the issue that created it.
Templating: Helm and Kustomize
Writing separate manifests for test and production leads to copy-paste errors. Two tools help. Helm packages manifests as a template with values; see Using Helm. Kustomize layers small changes over a base, and is described in the Kubernetes SIG CLI book. For a reader, the question is the same: what is the final result, and where do the environment differences live? Ask the agent to render the final manifests so you can review the actual output, not just the template.
The review checklist
| Check | Question |
|---|---|
| Image | Pinned by digest, from a source you trust? |
| Replicas | At least two for anything that matters? |
| Resources | Requests and a memory limit set? |
| Probes | Readiness present, liveness careful? |
| Security context | Non-root, no privilege escalation? |
| Config | Settings outside the image? |
| Secrets | No real value in the file? |
| Exposure | Only what must be public is public? |
| Namespace and labels | Present and consistent? |
| Matching | Service selector equals pod labels? |
3. Step by step: review a manifest change
- Read the spec the change should satisfy.
- Read the file list. Does it touch only what the spec names?
- Apply the checklist to each changed object.
- For a template, ask for the rendered output and check that.
- Check the diff against the previous version: what changed in image, replicas, limits, exposure?
- Look for secrets by eye and with a scanner.
- Verify matching: labels and selectors.
- Ask for a failure story: “if one node fails, what happens?”
- Approve or send back with specific, checkable comments.
4. Worked example: TrailMug
For the partner project mentioned in lesson 1, Maya reviews a merge request that adds a new service. The spec said: “Two copies, reserve a small amount of memory, readiness check, only reachable inside the cluster, no secrets in the file.”
She reads the file list: one deployment, one service, one ConfigMap. Good. She applies the checklist.
- Image: a tag
1.4, not a digest. She comments: “Pin by digest, as the pipeline prints it.” - Replicas:
1. The spec said two. Comment. - Resources: requests present, no memory limit. Comment: “Add a memory limit.”
- Probes: readiness present. Liveness checks
/db-ping, which queries the database. She comments: “A slow database would restart every pod at once. Use a simple /healthy check.” - Security context: missing. Comment.
- Secrets: the ConfigMap contains
API_KEY: sk-test-12345. She stops. The value is invented here, but in real life she would treat it as leaked: ask for removal, rotate the real value, and add a secret scan. - Exposure: the service type is
LoadBalancer. The spec said inside only. Comment. - Matching: the service selects
app: signupbut pods are labelledapp: sign-up. The service would have no pods.
Seven comments, each checkable. The agent fixes them, and she re-reads the new diff, not the old one. Two comments need a second round. She approves only when the checklist is clean and the preview shows two ready pods.
5. Working with AI agents on this
What the PDM decides: copies, capacity, health definition, exposure, which environment gets what.
Delegate: writing manifests from a spec, rendering templates, running a linter, explaining a diff line by line.
Verify: the checklist; rendered output; a secret scan; a failure story; and a check that the cluster state matches after sync (lesson 3).
Prompt to write a manifest:
Write Kubernetes manifests for <service> to this spec: <paste spec>. Rules: pin the
image by digest <digest>, set requests and a memory limit, add readiness and a
simple liveness probe that does not call other services, run as non-root with
no privilege escalation, expose only inside the cluster, put settings in a ConfigMap,
and put no secret values in any file. Add namespace and labels app, owner, issue.
After the files, list each rule and where it is satisfied, and anything you assumed.
Prompt for a review pass (you still review):
Review these manifests against this checklist: image pinned, replicas, requests and
limits, probes, security context, config outside the image, no secret values,
exposure, namespace and labels, selector matches labels. Output a table of
check, result, file and line. Do not edit anything. Mark what you cannot tell.
Disclose AI-written manifests in the merge request.
6. Common mistakes and how to avoid them
- Floating image tags. Fix: digest.
- One replica for something important. Fix: at least two, spread.
- No limits or probes. Fix: set them, and review.
- A liveness probe that checks the database. Fix: simple self-check only.
- Secrets in manifests. Fix: external or encrypted secrets, rotate any leak.
- Public by accident. Fix: ask about every service type and ingress.
- Selector and label mismatch. Fix: check the pair.
- Reviewing a template instead of the output. Fix: render.
7. Practice
Deliverable in git: specs/k8s-02.md, briefs/k8s-02.md, reviews/k8s-02.md, and a merge request with the manifests.
- Choose a tiny service, or a sample app, for a throwaway cluster.
- Write a spec with at least eight acceptance criteria from the checklist.
- Brief an agent to write manifests. Plan first. Do not apply to any cluster yet.
- Review with the checklist. Write each finding in
reviews/k8s-02.md. - Ask the agent to fix; re-review the new diff.
- Optional: apply to a throwaway cluster, then break one thing on purpose (a wrong label) and watch what happens.
- Record the faults the agent made. Open a merge request with a disclosure block.
8. Checklist
- I read each object and can say what it does.
- Image is pinned by digest.
- Requests, a memory limit and probes are set sensibly.
- Containers run as non-root.
- No secret values in any file.
- Only intended services are exposed.
- Selectors match labels.
- I reviewed the rendered output of any template.
9. Further learning
Read the Workloads page for the objects, then the probes and resource pages when you review your first real file. The Secrets page is essential before you let anything sensitive near a cluster. Helm and Kustomize pages are for when you manage more than one environment.
Finished this lesson?
This is only for you. It is saved in this browser, on this device, and nothing is sent anywhere. It is not a grade and not a certificate.
Go deeper
Further learning
Free or low-cost material from other publishers. We opened every link; check the cost label before you start.
Kubernetes
Workloads (opens the publisher's site in a new tab)
- Free
- Docs
- Intermediate
The official guide to Pods, Deployments, StatefulSets, Jobs and the other workload objects. Read the Deployment pages first.
Kubernetes
Configure Liveness, Readiness and Startup Probes (opens the publisher's site in a new tab)
- Free
- Docs
- Intermediate
How to tell Kubernetes when your app is alive and ready for traffic. A bad probe causes outages, so read this carefully.
Kubernetes
Resource Management for Pods and Containers (opens the publisher's site in a new tab)
- Free
- Docs
- Intermediate
Explains CPU and memory requests and limits and what happens when a container exceeds them.
Kubernetes
Secrets (opens the publisher's site in a new tab)
- Free
- Docs
- Intermediate
Explains Kubernetes Secret objects and, importantly, their limits: by default they are only base64 encoded. Read the good practices section.
Helm
Using Helm (opens the publisher's site in a new tab)
- Free
- Docs
- Intermediate
Explains charts, releases and values in Helm, the package manager for Kubernetes applications.
Kubernetes
SIG CLI (Kubectl and Kustomize docs) (opens the publisher's site in a new tab)
- Free
- Docs
- Intermediate
The documentation site of the Kubernetes CLI special interest group, with guides for kubectl and Kustomize, the tool for customising manifests without templates.



