Keentune

Kubernetes curriculum

23 chapters
·
218 concepts
·
free
Everything the adaptive question bank can teach and test in Kubernetes, from foundations through advanced practice. Work through it in order, or start practising and let the questions find your level.
New here? Read the Kubernetes guide
A free 16-minute primer — the mental model, the mistakes beginners make, and what to practise first.
A. The API object model
every object carries apiVersion, kind, metadata, spec and status
you write spec, controllers write status, and never the reverse
a name is unique per kind per namespace; the UID is unique for all time
namespaces partition names, not nodes, and not every kind is namespaced
labels are queryable selectors, annotations are unqueryable metadata
equality-based and set-based selectors, and which APIs accept each
filter on object fields like status.phase, which labels cannot do
a child names its owner so cascading deletion can find it
a finalizer blocks deletion until a controller clears it; deletionTimestamp is set meanwhile
a stale resourceVersion makes an update conflict instead of clobbering
B. Cluster architecture and the control plane
every component reads and writes cluster state only through the API server
etcd holds all cluster state, so it is the one thing a backup must capture
the scheduler picks a node and writes a binding; the kubelet does the starting
one process runs many controllers, each a reconcile loop over one resource
the kubelet reconciles the pods assigned to its node and reports their status back
kube-proxy writes iptables or IPVS rules for Services; it does not carry pod traffic
the kubelet drives containerd or CRI-O over the CRI; dockershim was removed in 1.24
controllers compare desired to actual state rather than reacting to an event stream
a Node object plus a Lease heartbeat is how the control plane decides a node is alive
HA control-plane components elect one active leader through a Lease object
clients watch from a resourceVersion instead of polling, and informers cache the result locally
C. Pods and the pod lifecycle
containers in a pod share a node, a network namespace and a lifetime
containers in a pod reach each other on localhost and share one IP and port space
a replaced pod gets a new IP, so nothing may hardcode one
phase is a coarse summary; conditions carry PodScheduled, Initialized, ContainersReady and Ready
Always, OnFailure and Never apply to the containers inside the pod, not to the pod itself
the exponential delay before the next restart attempt, not a failure mode of its own
they run in declared order before app containers, each to a successful exit
a native sidecar (GA 1.33) starts before app containers and keeps running alongside them
kubectl debug injects a container into a running pod; it cannot be removed or restarted
preStop, then SIGTERM, then SIGKILL when the grace period expires
a pod is never rescheduled to another node; a controller creates a new one
D. Containers, images and the runtime
IfNotPresent is the default, Always is implied for the latest tag
a digest pins exactly one image; a tag can be repointed under you
private registry credentials come from a Secret on the pod or its ServiceAccount
a pull failure backs off, and the reason is in the pod events, not in container logs
command overrides the image ENTRYPOINT, args overrides CMD
a shell-wrapped entrypoint never forwards SIGTERM unless it execs the process
postStart runs concurrently with the entrypoint, preStop delays termination
selects an alternate sandboxed runtime such as gVisor or Kata for a pod
E. Workload controllers
a Deployment manages ReplicaSets, and the ReplicaSet manages pods
any pod-template change makes a new ReplicaSet and scales the old one down
maxSurge and maxUnavailable bound how many pods exist and how many are missing mid-rollout
old ReplicaSets are retained for undo, capped by revisionHistoryLimit
a Deployment's selector cannot be changed after creation
kills every old pod before starting new ones, accepting downtime for exclusivity
ordinal names, stable DNS and stable storage survive rescheduling
pods update in reverse ordinal order, one at a time, and a stuck pod halts the rest
each StatefulSet pod gets its own PVC, which is not deleted with the pod by default
a clusterIP None Service gives every StatefulSet pod its own DNS record
a DaemonSet has no replica count; it runs one pod per matching node
system DaemonSets carry tolerations so they still land on tainted and control-plane nodes
F. Jobs, CronJobs and batch
completions is how many pods must succeed, parallelism how many run at once
the number of pod failures tolerated before the Job itself is marked failed
exit codes and disruption conditions can be classified so a Job fails fast instead of retrying
an Indexed Job gives each pod a completion index for static work partitioning
a wall-clock cap that terminates the Job regardless of remaining retries
finished Jobs are garbage collected after a TTL; without one they accumulate forever
Allow, Forbid or Replace decides what happens when a run overlaps the previous one
startingDeadlineSeconds bounds lateness, and 100 missed schedules stops the CronJob
G. Resource requests, limits and QoS
the request is what the scheduler reserves, the limit is what the runtime enforces
exceeding a CPU limit throttles the container, it is never killed for it
exceeding a memory limit is an immediate OOMKill of the container
the evidence is the container's lastState with exit code 137, not a pod-level event
1000m is one core of time share, not one pinned core
Mi is 2^20 bytes while M is 10^6, and the wrong suffix silently under-provisions
every container in the pod sets requests equal to limits for both CPU and memory
some requests set versus none at all, which decides eviction order
a LimitRange injects default requests and limits into pods that omit them
a namespace CPU or memory quota makes explicit requests mandatory
H. Scheduling and placement
the scheduler filters feasible nodes, scores the survivors, and binds the best
a plain label match where every key must hold, with no soft variant
requiredDuringScheduling filters nodes, preferred only adds a score weight
a node label changing after placement never evicts the running pod
co-location is defined relative to a topology key such as hostname or zone
pod anti-affinity is evaluated pairwise and degrades scheduling at large scale
a taint keeps pods off a node; a toleration permits but never attracts
NoSchedule, PreferNoSchedule and NoExecute, of which only NoExecute evicts running pods
how long a pod tolerates a NoExecute taint before the node controller removes it
maxSkew bounds the difference in matching pods between topology domains
DoNotSchedule leaves the pod Pending; ScheduleAnyway downgrades the rule to a preference
setting nodeName skips scheduling and every check it would have run
I. Preemption, eviction and disruption
a higher-priority pending pod can evict lower-priority pods to make room
preemption tries to respect a PodDisruptionBudget but is not blocked by one
the kubelet evicts locally under memory or disk pressure and ignores PDBs
BestEffort first, then Burstable pods over their request, then Guaranteed
a soft eviction threshold waits out a grace period, a hard one acts immediately
the Eviction subresource is what drain calls and what a PDB actually gates
minAvailable protects against drains and upgrades, never against a node crash
cordon only marks the node unschedulable, drain also evicts what is already running
a RuntimeClass's overhead is added to the pod's effective request and quota usage
J. Probes and application health
a failed liveness probe kills and restarts the container; it never removes traffic
a failed readiness probe pulls the pod out of Service endpoints without restarting it
while a startup probe is running, liveness and readiness checks are disabled
periodSeconds 10 with failureThreshold 3 means failure is declared in roughly 30 seconds
probing a downstream service restarts healthy pods during that service's outage
httpGet, tcpSocket, exec and gRPC, and that exec forks a process every period
a liveness kill honors the grace period, which a probe may override
a fixed initial delay is a guess, a startup probe adapts to slow starts
K. Services and load balancing
the ClusterIP exists only as forwarding rules; no process listens on it
the endpoints controller lists ready matching pods into EndpointSlices
the default type, reachable only from inside the cluster
allocates the same port on every node from the 30000-32767 range
a cloud load balancer fronts the NodePort rather than replacing it
DNS aliasing with no proxying, no endpoints and no selector
clusterIP None returns the pod IPs from DNS instead of a single virtual IP
port is what the Service exposes, targetPort is where the pod listens
ClientIP is the only built-in stickiness, and it keys on the source IP
publishes not-ready pods in DNS, which StatefulSet peer discovery relies on
L. Cluster networking and DNS
every pod reaches every pod without NAT, which is a requirement on the CNI plugin
Kubernetes itself implements no pod networking; the plugin does
iptables rule chains grow linearly with Services while IPVS uses a hash table
service.namespace.svc.cluster.local, with shorter forms resolving via the search path
the default ndots of 5 makes external hostnames try several search suffixes first
ClusterFirst, Default, None and ClusterFirstWithHostNet resolve differently
a headless Service gives each pod an A record; individual pod records are opt-in
preserves the client source IP but drops traffic on nodes with no local endpoint
restricts in-cluster Service traffic to endpoints on the same node
ipFamilyPolicy chooses SingleStack, PreferDualStack or RequireDualStack
M. Ingress and the Gateway API
the Ingress object does nothing unless an ingress controller is running
selects which controller owns a given Ingress, replacing the old annotation
Exact, Prefix and ImplementationSpecific, where Prefix matches whole path segments
TLS termination reads a Secret of type kubernetes.io/tls named in the spec
Ingress covers HTTP and HTTPS; other protocols need a LoadBalancer Service
controller-specific annotations are why an Ingress rarely moves between controllers
GatewayClass, Gateway and HTTPRoute separate infrastructure ownership from app ownership
a route requests attachment to a Gateway, and the Gateway's listener decides whether to allow it
N. Network policy
all pod traffic is permitted until some policy selects that pod
once a pod is selected, only what a policy explicitly allows gets through
allowing one direction says nothing about the other
multiple policies union together; there is no deny rule and no ordering
podSelector and namespaceSelector in one entry are an AND, in separate entries an OR
with a CNI that ignores NetworkPolicy the object is accepted and silently inert
O. Storage
a plain volume dies with the pod; only a PersistentVolume outlives it
shared between containers in the pod and lost the moment the pod is replaced
a tmpfs emptyDir counts against the pod's memory limit, not against disk
a PVC is a request, and the control plane binds it exclusively to one PV
a StorageClass provisions a PV on demand instead of requiring one to pre-exist
ReadWriteOnce is one node, ReadWriteOncePod is one pod, ReadWriteMany needs a shared filesystem
it constrains binding and scheduling, not what the application actually does
Delete destroys the backing volume when the PVC goes, Retain leaves it unbound and unusable
allowVolumeExpansion lets a PVC grow in place, and it can never shrink
delaying binding until scheduling stops a zonal disk being created in the wrong zone
in-tree cloud volume plugins were migrated out to CSI drivers
VolumeSnapshot plus its class, restored by naming the snapshot as a new PVC's dataSource
a StatefulSet's PVCs outlive their pods unless a retention policy says otherwise
P. Configuration and secrets
plain data readable by anyone with get on that namespace
base64 is encoding, and in etcd it is plaintext unless encryption is configured
an EncryptionConfiguration on the API server, or a KMS provider, is what actually encrypts
environment variables are read once at container start and never updated
a mounted ConfigMap or Secret key is eventually updated by the kubelet sync loop
a subPath mount is a one-time copy that never sees a later change
a referenced ConfigMap, Secret or key that is absent stops the pod unless marked optional
Opaque, kubernetes.io/tls, dockerconfigjson and the service-account-token type
marking one immutable removes kubelet watch load and prevents accidental edits
pod name, namespace, labels and resource limits injected as environment variables or files
Q. Authentication, authorization and RBAC
every request is authenticated, then authorized, then run through admission
users come from certificates, tokens or an OIDC provider; the API has no User kind
a Role is namespaced, a ClusterRole covers cluster-scoped resources and all namespaces
binds the ClusterRole's rules into one namespace only
there is no deny rule; effective access is the union of every matching binding
get, list, watch, create, update, patch and delete, plus subresources like pods/exec
list on Secrets returns their data, so it is equivalent to reading every one
you cannot grant a permission you do not hold unless you have the escalate verb
every pod runs as a ServiceAccount, and the default one holds no permissions
modern tokens are short-lived, audience-bound and rotated rather than stored in a Secret
disabling automounting removes the API credential from pods that never call the API
R. Pod and cluster security
privileged, baseline and restricted are cumulative profiles, not independent settings
enforce, audit and warn are applied per namespace by label, and can differ from each other
PodSecurityPolicy is gone as of 1.25; Pod Security Admission or a policy engine replaces it
the container-level field wins wherever both levels set the same thing
rejects the container at start if its resolved user is root, unlike merely setting runAsUser
blocks a setuid binary gaining more privilege than its parent process
every writable path must then be an explicit volume, which surfaces hidden state
dropping ALL and adding back only what is needed, instead of running privileged
mounting the host filesystem or namespace is a node-level escape path
mutating webhooks run before validating ones, and failurePolicy decides what an outage does
S. Autoscaling
the HPA changes the replica count and never the size of a pod
desired replicas is current replicas times current metric over target metric, rounded up
CPU utilization is a percentage of the request, so a pod with no request cannot scale
metrics-server supplies resource metrics, an adapter supplies custom and external ones
scale-down is damped against flapping while scale-up reacts faster by default
the VPA right-sizes requests and limits rather than the replica count
both driving CPU on the same workload fight each other
resizing a running pod's resources without recreating it, GA in 1.35
it adds nodes in response to unschedulable pods, so requests must be set
T. Extending Kubernetes
a CustomResourceDefinition makes the API server serve and store a new kind, with no behavior
a custom resource is inert data until some controller reconciles it
the OpenAPI schema on the CRD is what rejects a malformed custom resource
several served versions, exactly one storage version, and a conversion webhook between them
a status subresource splits write permission, and scale makes kubectl scale work
a controller that encodes the operational knowledge for one specific application
a controller reconciles from observed state because a watch event can always be lost
CEL policies evaluated in-process, avoiding a webhook's availability coupling
an extension API server serving a whole API group, which a CRD cannot do
device plugins advertise GPUs to the kubelet; DRA is the structured replacement, GA in 1.34
U. Observability and debugging
Events are short-lived API objects, retained about an hour by default
kubectl logs reads the runtime's files on the node, not a store in the API server
the previous flag is the only way to read a crashed container's last output
the cluster collects stdout and stderr; a logfile inside the container is invisible
the kubelet rotates and drops container logs, so unshipped history is lost
it feeds the HPA and kubectl top and keeps no history
who called what on the API, driven by an audit policy, independent of app logs
the events and conditions in describe explain Pending, ImagePullBackOff and failed mounts
V. kubectl and the declarative workflow
apply is declarative and repeatable, create fails when the object already exists
the server records which manager owns each field and reports a conflict
client-side apply diffs against an annotation, which is why a manual edit gets reverted
strategic merge, JSON merge patch and JSON patch differ mainly in how they treat lists
patches a template annotation so a new pod-template hash forces a rolling replacement
a context is a cluster, user and namespace triple, and the wrong current context is a real risk
a server dry run passes through admission, a client dry run only checks the schema
W. Packaging: Helm and Kustomize
a chart is a template package, a release is one installed instance with its own values
the chart's values.yaml, then each values file, then set flags, with the last one winning
Helm renders text before the API sees it, so indentation errors surface as parse failures
annotated hook resources run outside the normal manifest ordering, such as a pre-upgrade migration Job
overlays patch plain YAML with no templating language at all
Kustomize appends a content hash to generated ConfigMaps so a change triggers a rollout
parameterization and distribution against plain, directly reviewable manifests
Keentune is not affiliated with or endorsed by the organizations whose documentation informs these maps.
All about Kubernetes practice
Also on your phone
All exam, test, and product names and trademarks are the property of their respective owners and are used here for identification and reference only. Keentune is independent study practice — not affiliated with, authorized, or endorsed by any of these organizations.
© 2026 SportaApp LLC