6.2 Kubernetes: the core objects
Checked against Docker's and Kubernetes' own reference documentation, August 2026
What this is and why it exists
Kubernetes is a system for keeping a described state true. You write down what should be running; a control loop compares that to what is running and makes up the difference, continuously, forever. Everything else — the object names, the YAML, the vocabulary — is detail on top of that one idea. This lesson is about reading a manifest and predicting what the cluster will do with it, which is the skill that makes the rest learnable.
The vocabulary
- Pod — the smallest thing Kubernetes runs: one or more containers that share a network address and lifetime.
- ReplicaSet — keeps a stated number of identical Pods running.
- Deployment — manages ReplicaSets for you, and is how you actually ship an application. Amazon's managed offering is EKS, Azure's is AKS, Google's is GKE.
- Controller — a loop watching the cluster and moving actual state toward desired state.
- Service — a stable way to reach a changing set of Pods.
- Ingress — HTTP routing from outside the cluster to Services inside it.
- ConfigMap — non-secret configuration, mounted as files or given as environment variables.
- Secret — the same shape, for sensitive values.
- Namespace — a named partition of the cluster, for separating environments or teams.
- Requests and limits — what a container is guaranteed and what it may not exceed.
The mental model
Read every manifest as a sentence about how the future should be, not as an order to do something now. The documentation puts it exactly — "you describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state at a controlled rate". Nothing you write is an instruction to do something once. Delete a Pod that a Deployment owns and another appears, because the loop noticed a shortfall. That is not a quirk to work around; it is the entire product.
A Deployment "provides declarative updates for Pods and ReplicaSets", and the layering is worth holding: the Deployment owns ReplicaSets, a ReplicaSet owns Pods, and a rollout is a Deployment creating a new ReplicaSet and shifting Pods from the old to the new. The old ReplicaSet stays behind at zero Pods, which is exactly what makes rolling back cheap.
Traffic is the second idea and the one people find surprising. Pods are cattle with changing addresses; a Service is "a method for exposing a network application that is running as one or more Pods in your cluster", giving a stable name and address in front of them. The set of Pods behind it "is usually determined by a selector that you define" — labels, matched — and Kubernetes "updates the EndpointSlices for a Service whenever the set of Pods in a Service changes". So the wiring is by label, not by name, and a label typo produces a Service with nothing behind it and no error anywhere. When traffic mysteriously goes nowhere, check the selector against the Pod's labels first.
Service types step outward: ClusterIP, the default, is reachable only inside the cluster; NodePort "exposes the Service on each Node's IP at a static port"; LoadBalancer "exposes the Service externally using a cloud provider's load balancer". Ingress sits above all of these for HTTP, routing by hostname and path so that many applications share one entry point instead of each buying its own load balancer.
Configuration comes in as ConfigMaps and Secrets, mounted as files or injected as environment variables — the same container image with different content around it, which is the container lesson's rule expressed in cluster objects. Be clear-eyed about Secrets: they keep sensitive values out of your manifests and away from the image, which is worth having, and they are not a substitute for a real secret store with rotation and audit.
Then requests and limits, which decide both where a Pod lands and how it behaves under pressure — and which behave differently for processor and memory in a way that explains most confusing incidents. The scheduler "uses this information to decide which node to place the Pod on", so a request is a promise the cluster reserves for you. A limit is enforced by the kubelet, and here is the asymmetry: processor limits "are enforced by CPU throttling", so a container runs slower and stays alive, while memory limits "are enforced by the kernel with out of memory (OOM) kills" — over its memory limit, a container may be terminated. Slow is a processor limit; killed and restarted is a memory limit. Set requests from measurement, keep them honest, and remember that a Pod with no requests at all is a Pod the scheduler places blind.
Reading a manifest
The documentation's own Deployment example, which is worth being able to read line by line:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80Read it as: three copies of this Pod should exist; the ones I mean are those labelled app: nginx; and here is the Pod to make. Note that the label appears twice on purpose — once in the Deployment's selector, saying which Pods it owns, and once in the Pod template, putting that label on the Pods it creates. They must agree, and when they do not the Deployment manages nothing.
And the commands, whose form the reference gives as kubectl [command] [TYPE] [NAME] [flags]:
kubectl apply -f deployment.yaml
kubectl get pods
kubectl describe deployment nginx-deploymentapply applies "a configuration change to a resource from a file or stdin", get lists resources, and describe displays "the detailed state of one or more resources" — which is where the events explaining a stuck Pod actually live.
What you should now be able to explain or do
State the one idea Kubernetes implements, in a sentence. Read the Deployment manifest above and say what the cluster will do with it. Explain why deleting a Pod does not remove it. Say how a Service finds its Pods, and what a label typo looks like from the outside. Give the difference between what happens over a processor limit and over a memory limit. Explain why the label appears twice in the manifest.
Check yourself
You delete a Pod created by a Deployment. What happens, and why?
Another appears. The Deployment describes a desired state and its controller continuously moves actual state toward it — the deletion is only a shortfall for the loop to make up.
A Service exists, the Pods are running, and no traffic arrives. What do you check first?
The selector against the Pods' labels. Services find Pods by label, and a mismatch produces a Service with no endpoints and no error message anywhere.
A container is throttled to a crawl. Another is killed and restarted. Which limit did each hit?
The slow one hit its processor limit, which is enforced by throttling. The killed one exceeded its memory limit, which the kernel enforces with an out-of-memory kill.
Why does app: nginx appear twice in the Deployment manifest?
Once in the selector, saying which Pods this Deployment owns, and once in the Pod template, putting that label on the Pods it creates. If they disagree the Deployment owns nothing.
What is the difference between a Service and an Ingress?
A Service gives a stable address in front of a changing set of Pods, mostly inside the cluster. An Ingress routes HTTP from outside by hostname and path, so many applications share one entry point.
Go deeper
We haven't checked most of these for screen reader use yet.
Back to Kubernetes: the core objects: work through the checklist