The REST API is the centre of Kubernetes: pods, deployments, services… are all API objects, with paths like /api/v1/… (core group) or /apis/<group>/<version>/…, for example /apis/apps/v1/deployments.
An object is a record of intent: you record the state you want and the system works to reach it.
apiVersion: apps/v1 # group/version
kind: Deployment # object type
metadata: # name, namespace, labels; uid set by the cluster
name: web
namespace: dev
spec: # desired state — you write it
replicas: 3
...
status: # actual state — the cluster fills it in
readyReplicas: 3
flowchart LR
M["YAML manifest"] -- "kubectl apply" --> A["kube-apiserver"]
A --> E[("etcd: spec")]
C["Controller / kubelet"] -- "update status" --> A
YAML
Manifests are usually YAML (equivalent to JSON) with three data types: mappings, sequences (- item) and scalars. Indent with spaces, never tabs.
Common apiVersions
| Kind | apiVersion |
|---|---|
| Pod, Service, ConfigMap, Namespace | v1 |
| Deployment, ReplicaSet, DaemonSet, StatefulSet | apps/v1 |
| Job, CronJob | batch/v1 |
Look things up on the cluster
| Command | Meaning |
|---|---|
kubectl explain pod.spec.containers |
Describe a field and its sub-fields |
kubectl api-resources |
Kinds, short names, API group, namespaced or not |
kubectl api-versions |
Group/versions the cluster supports |
Imperative and declarative
| Style | Example | Fits |
|---|---|---|
| Imperative commands | kubectl create deployment web --image=nginx:1.27 |
Quick experiments |
| Imperative with files | kubectl create -f web.yaml |
One-time creation |
| Declarative | kubectl apply -f k8s/ |
Everything kept in Git |
Generate a starting manifest instead of typing it by hand:
kubectl create deployment web --image=nginx:1.27 --replicas=3 --dry-run=client -o yaml > web.yaml
kubectl diff -f web.yaml shows what apply would change on the live cluster, a good habit before every apply. Server-side apply (kubectl apply --server-side) lets the apiserver track which tool owns which field, avoiding conflicts between kubectl, Helm, and controllers.
Fields the cluster manages
metadata.uiduniquely identifies an object for its whole life.metadata.resourceVersionchanges on every write; an update based on an old version is rejected, which prevents two clients overwriting each other (optimistic concurrency).metadata.ownerReferenceslinks a pod to its ReplicaSet, and a ReplicaSet to its Deployment. Deleting the owner garbage-collects its children automatically.metadata.finalizershold deletion until a controller finishes cleanup, such as releasing a cloud load balancer; a namespace or volume stuck inTerminatingis usually waiting on one.
Extending the API
A CustomResourceDefinition (CRD) adds a new kind, such as Certificate from cert-manager, and a controller (an operator) acts on it. After installing a CRD, kubectl get certificates works like any built-in resource.
API versions over time
APIs mature from v1alpha1 to v1beta1 to v1, and old versions are removed after deprecation. When upgrading a cluster, check manifests and Helm charts for removed versions; tools such as kubectl convert or the deprecation warnings that kubectl prints help find them.
kubectl get --raw /api/v1/namespaces calls the REST API directly, showing that kubectl is only a client of the same HTTP API.