Skip to main content

Kubernetes object model

Exam guide§2.1

Two ideas make Kubernetes work, and the exam expects both: the object model (everything Kubernetes manages is an object with a spec and a status) and declarative management (you declare desired state, a control loop maintains it). The declarative vs imperative distinction lives on the basics page; this page is the object model and the loop that enforces it.

Objects: spec vs status

Every item Kubernetes manages is represented by an object - a persistent entity that records the state of something running in a cluster. You view and change an object's attributes and state through the API. Objects represent containerized applications, the resources available to them, and the policies that affect their behavior.

Each object has two important elements:

  • Object spec - the desired state, defined by you. What you want to exist.
  • Object status - the current state, provided by the Kubernetes control plane. What actually exists right now.
Kubernetes object modelObjectObject specDesired state described by youObject statusCurrent state described by Kubernetes
Every Kubernetes object has a spec (desired state, described by you) and a status (current state, described by Kubernetes).
GotchaYou write the spec, never the status

The spec is yours to declare; the status is reported back by the control plane. You don't edit status to make something happen - you change the spec (desired state) and let the control plane drive status (current state) toward it.

Each object also has a kind - the type of thing it is (Pod, Deployment, Service, ...).

Manifest files

You declare the objects you want Kubernetes to create and maintain in manifest files - ordinary text files written in YAML or JSON (this course uses YAML). A manifest records a desired state (the spec): what the object is and how it should run.

apiVersion: v1 # Kubernetes API version used to create the object
kind: Pod # the object you want
metadata: # identifies the object
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
FactsRequired top-level fields
  • apiVersion - the Kubernetes API version used to create the object.
  • kind - the object you want (here, a Pod).
  • metadata - identifies the object: its name, unique UID, and an optional namespace.
GotchaGroup related objects in one file

If several objects are related, define them all in the same YAML file - it is easier to manage. Then keep those files in a version-control repository (Cloud Source Repositories is a popular choice) so changes are tracked, reversible, and available when recreating or restoring a cluster.

Object identity

Three things identify and organize an object:

NumbersName, UID, and labels
  • Name - a unique string under 253 characters. Allowed: numbers, letters, hyphens, and periods. Only one object can hold a given name at a time within the same namespace; after the object is deleted the name can be reused.
  • UID - a unique identifier generated by Kubernetes for every object created over the life of a cluster.
  • Labels - key-value pairs that tag objects during or after creation to identify and organize them.

Label selectors let you pick resources by label with kubectl. You can ask for all resources that have a certain value, all that do not, or all whose value is in a set you supply.

# select every Pod labelled app=nginx
kubectl get pods -l app=nginx

Pods

A Pod is the foundational building block of the Kubernetes model and the smallest deployable object. Every running container in Kubernetes lives inside a Pod. A Pod creates the environment its containers run in, and that environment can hold one or more containers.

PodShared networkingContainerContainerContainerShared storageUnique IP address (localhost 127.0.0.1)
A Pod wraps one or more containers that share the same networking (one localhost, 127.0.0.1) and the same storage volumes - the smallest deployable unit in Kubernetes.

When a Pod holds more than one container, those containers are tightly coupled and share the Pod's resources:

NumbersWhat a Pod shares
  • One unique IP address per Pod, assigned by Kubernetes.
  • Shared network namespace - every container in the Pod shares that IP and its network ports.
  • localhost - containers in the same Pod reach each other over 127.0.0.1.
  • Shared storage - the Pod can define storage volumes shared across its containers.

The watch loop

Declarative management means you tell Kubernetes the state objects should be in, and it works to achieve and maintain that state through a watch loop: the control plane endlessly compares the current state to the desired state and remedies any difference.

Control planeObjectDesiredObjectCurrentObjectDesiredObjectCurrentObjectDesiredObjectCurrent
The control plane runs a watch loop: it continuously compares the desired state of each object against its current state and reconciles any drift back to what you declared.

Take the classic example: you want three nginx web-server Pods always running. You declare three Pod objects as desired state. If the current state is zero Pods running, the desired count (3) does not match the current count (0), so the control plane launches 3. It then keeps watching - if a Pod dies, current drops below desired, and it launches a replacement.

GotchaReconciliation never stops

The control plane does not run once at create time. It continuously compares reality to what you declared and remedies drift - this is what makes Kubernetes self-healing.

Controller objects

By default Kubernetes spreads a workload evenly across available nodes. But declaring three separate Pods does not keep three running: Pods are ephemeral and disposable - they do not heal or repair themselves and are not meant to run forever.

To maintain high availability you declare a controller object whose job is to manage the state of the Pods:

FactsController object types
  • Deployment - long-lived, stateless components like web servers, managed as a group.
  • StatefulSet - stateful workloads needing stable identity and storage.
  • DaemonSet - one Pod per node.
  • Job - run-to-completion batch tasks.

Instead of three Pod manifests, one Deployment manifest launches three replicas of the same container. A Deployment's spec defines the number of replica Pods, which containers run in them, and which volumes to mount:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # desired number of Pods
selector:
matchLabels:
app: nginx
template: # the Pod spec each replica runs
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest

When you apply a Deployment, kubectl sends it to the kube-APIserver; the kube-scheduler places the Pods across nodes, and the Deployment controller creates a child object - a ReplicaSet - to launch and maintain them. If one fails, the ReplicaSet sees current state has fallen below desired and launches a replacement: the watch loop doing its job.

ClusterkubectlControl planekube-APIserveretcdkube-schedulerkube-controller-managerkube-cloud-managerkubletkube-proxynginx Pod</>Nodekubletkube-proxynginx Pod</>Nodekubletkube-proxynginx Pod</>Node
You apply a Deployment through kubectl; the control plane reconciles it and the kube-scheduler places the desired nginx Pods across the cluster nodes.
Best practiceManage Pods with a controller, never directly

A bare Pod that dies stays dead - nothing recreates it. Declaring a Deployment (or another controller) is what gives you self-healing: the controller continuously reconciles actual state back to the state you declared.