kubectl and Declarative YAML
The idea in one sentence
Section titled “The idea in one sentence”kubectl is how you send desired state to a cluster and inspect what it is doing, and almost everything you send it is a YAML manifest built from the same four top-level fields.
kubectl basics: contexts, namespaces, and verbs
Section titled “kubectl basics: contexts, namespaces, and verbs”Your kubeconfig can hold credentials for several clusters at once, grouped into contexts; switch which one your commands target with:
kubectl config use-context my-clusterkubectl get pods -n my-namespaceThe -n (or --namespace) flag scopes a command to one namespace — leaving it off targets whatever namespace your current context defaults to, usually default. Beyond that, a small set of verbs covers most of daily kubectl usage:
kubectl get podskubectl describe pod web-7d9f8c6b7-abcdekubectl logs web-7d9f8c6b7-abcdekubectl exec -it web-7d9f8c6b7-abcde -- shget lists objects, describe shows detailed status and recent events for one object (the first place to look when something is wrong), logs streams a container’s stdout/stderr, and exec runs a command inside a running container — handy for a quick shell to poke around.
Every manifest has four top-level fields
Section titled “Every manifest has four top-level fields”Whatever kind of object you are creating — Pod, Deployment, Service, anything — its YAML has the same shape:
apiVersion: v1kind: Podmetadata: name: web labels: app: webspec: containers: - name: web image: nginx:1.27 ports: - containerPort: 80apiVersion and kind say which API group and object type you mean. metadata carries identity and bookkeeping — name, optional namespace, and the labels and annotations you attach yourself. spec is the desired state you author — everything above is spec for a Pod. Kubernetes adds a fifth field on its own, status, once the object exists: that one you never write, only read, since it reflects observed reality rather than what you asked for.
apply vs create, and labels as the gluing mechanism
Section titled “apply vs create, and labels as the gluing mechanism”kubectl apply -f file.yaml is declarative: it diffs your file against the object’s last-applied configuration (tracked in an annotation) and patches only what changed, creating the object if it does not exist yet. That makes it safe to re-run the same command over and over, which is exactly what you want in scripts and CI. kubectl create -f file.yaml is imperative instead — it creates the object once and errors out if it already exists. This course uses apply throughout.
kubectl apply -f pod.yamlkubectl create -f pod.yamlLabels are arbitrary key-value pairs you attach to objects, like app: web in the Pod above. On their own they do nothing — their power comes from selectors, which other objects use to find the Pods labeled a certain way. A Service with selector: { app: web } routes traffic to every Pod carrying that label; a Deployment’s ReplicaSet uses a matchLabels selector to know which Pods are “its” Pods to keep at the desired replica count. This label-and-selector pattern is the fundamental way objects in Kubernetes find each other, and you will see it again in nearly every later module.
flowchart LR cmd["kubectl apply -f pod.yaml"] --> api["kube-apiserver"] api --> etcd["etcd"] api --> ctrl["Controllers notice the change and react"]