Kubernetes - kubectl + Manifest Authoring
Overview
Kubernetes runs containerized workloads against a declarative API. You don't tell it how to run things; you declare what you want (a manifest's spec) and the system continuously works to make reality (status) match. kubectl is the CLI you use to submit that desired state and to inspect, debug, and roll out workloads against any cluster — regardless of how the cluster was built.
This skill is the kubectl + resource/manifest layer: authoring core API objects and driving the API with kubectl. It is independent of how the cluster was stood up.
Disambiguation: This skill documents kubectl and core-resource manifest authoring — how to write Kubernetes objects and drive the API. It does not cover installing or administering a cluster. To run a local or lightweight cluster (install a single binary, join nodes, etcd snapshots, bundled ingress/LB/DNS, certs), use the k3s skill. Out of scope entirely: client libraries (client-go), cloud-provider specifics (EKS/GKE/AKS IAM, cloud LBs/CSI), and Helm (mention as a packaging option, defer).
Mental Model
Four ideas unlock everything:
- Declarative desired state. You declare what you want in a manifest (
spec); the system drives reality (status) to match. kubectl apply submits desired state; controllers do the rest.
- Control loops (reconciliation). Every resource type has a controller that watches and drives
status toward spec. A Deployment controller creates a ReplicaSet; the ReplicaSet controller creates Pods; the scheduler binds Pods to Nodes; the kubelet runs containers. Self-healing falls out of this for free.
- Everything is an API object addressed by Group / Version / Kind (GVK):
apiVersion: apps/v1 + kind: Deployment. The empty "core" group is written as just v1 (Pod, Service, ConfigMap, Secret, Namespace). Named groups include apps/v1, batch/v1, networking.k8s.io/v1, rbac.authorization.k8s.io/v1, policy/v1, autoscaling/v2, storage.k8s.io/v1. Run kubectl api-resources to see the live map.
- Namespaces scope most resources (Pods, Deployments, Services, ConfigMaps…). Cluster-scoped resources (Nodes, PersistentVolumes, Namespaces, ClusterRoles, StorageClasses, PriorityClasses) live outside any namespace.
default exists out of the box; kube-system holds control-plane add-ons.
Every object shares a shape: apiVersion, kind, metadata (name, namespace, labels, annotations), spec (desired), status (observed, managed by the system — never author it).
When to Use This Skill
Use this skill when:
- Writing/editing manifests (YAML) for any core resource.
- Driving kubectl: deploy, inspect, debug, roll out, scale, exec/logs, port-forward, generate manifests, check RBAC.
- Debugging a workload: a Pod stuck Pending, CrashLoopBackOff, ImagePullBackOff, OOMKilled; reading events; describing resources.
- Managing contexts/namespaces across clusters via kubeconfig.
Relationship to the k3s skill
This skill is the kubectl + resource/manifest layer — authoring Kubernetes objects and driving the API with kubectl, regardless of how the cluster was created. It does not cover standing up or administering a cluster. To run a local or lightweight cluster (install the single k3s binary, join nodes, snapshots, bundled ingress/LB/DNS/storage, certs), use the k3s skill. k3s hands you a working API endpoint and a kubeconfig; this skill is everything you do against it. (k3s even bundles kubectl — every command here works on a k3s cluster.) Out of scope: client libraries, cloud-provider specifics, and Helm.
Prerequisites
CRITICAL: Before proceeding, verify kubectl is installed and check the version:
kubectl version --client # prints e.g. "Client Version: v1.28.2"
Version note: This skill is documented against the Kubernetes API as of ~1.37; the empirical CLI baseline is kubectl v1.28.2 (bundled kustomize v5.0.4). Long-standing features (GA at or before 1.20) are "bedrock" and shown unannotated. Features added later are tagged inline as (k8s 1.X+) by their GA version — see references/version-features.md for the full feature → version map with source citations. Version skew: keep kubectl within ±1 minor of the cluster.
Install kubectl + kubeconfig/contexts
# macOS
brew install kubectl
# Linux (direct binary, matching minor)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client # verify
(For a cluster to point it at, see the k3s skill.)
kubeconfig lives at ~/.kube/config (override with $KUBECONFIG, which may be a :-separated list that gets merged). It holds three lists — clusters (API server URL + CA), users (credentials), contexts (a cluster+user+namespace triple) — plus a current-context.
kubectl config get-contexts # list; * marks current
kubectl config use-context <ctx> # switch cluster
kubectl config set-context --current --namespace=<ns> # set default namespace
kubectl config view --minify # effective config for current ctx
(kubectx / kubens are popular third-party helpers for switching contexts/namespaces.)
Core Workflows
1. Deploy + expose
kubectl create deployment web --image=nginx --replicas=3 # imperative, quick
kubectl expose deployment web --port=80 --target-port=8080 # creates a ClusterIP Service
kubectl get deploy,rs,pods,svc -l app=web
Prefer declarative for anything you keep: generate with --dry-run=client -o yaml > web.yaml, edit, then kubectl apply -f web.yaml.
2. Inspect / debug a failing pod
kubectl get pods # the STATUS column tells the story
kubectl describe pod <pod> # Events at the bottom are the #1 clue
kubectl logs <pod> [-c <container>] [--previous] # --previous = last crashed container
kubectl get events --sort-by=.lastTimestamp # or: kubectl events
Map STATUS → cause in Troubleshooting below.
3. Apply / diff / rollout cycle
kubectl diff -f web.yaml # preview what apply would change
kubectl apply -f web.yaml # converge to desired state
kubectl rollout status deploy/web # wait for the rollout to finish
kubectl rollout history deploy/web
kubectl rollout undo deploy/web # roll back to previous revision
kubectl rollout restart deploy/web # re-roll pods (e.g. to pick up a changed Secret)
4. Exec / logs / port-forward
kubectl exec -it <pod> -- sh # shell in a running container
kubectl logs -f deploy/web # stream logs (Deployment → a pod)
kubectl port-forward svc/web 8080:80 # localhost:8080 → Service:80
5. Generate manifests with --dry-run=client (offline, no cluster)
kubectl create deployment web --image=nginx --dry-run=client -o yaml
kubectl create configmap app-cfg --from-literal=LOG=info --dry-run=client -o yaml
kubectl create cronjob nightly --image=busybox --schedule="0 2 * * *" --dry-run=client -o yaml
These emit clean starter YAML you then edit (verified emitting on 1.28.2: deployment→apps/v1, job/cronjob→batch/v1, service/cm/secret→v1, rolebinding→rbac.authorization.k8s.io/v1, ingress→networking.k8s.io/v1, pdb→policy/v1, priorityclass→scheduling.k8s.io/v1).
Not offline generators. kubectl run, kubectl expose, kubectl autoscale, and kubectl create role --resource=… consult the API server even under --dry-run=client (for resource/GVR resolution), so they need a reachable cluster. Don't expect them to render YAML with no cluster.
6. RBAC quick-check with auth can-i
kubectl auth can-i create deployments # for yourself
kubectl auth can-i get pods --as=system:serviceaccount:ns:sa # impersonate
kubectl auth can-i --list # everything you can do
kubectl auth whoami # who am I (Experimental in 1.28)
Quick Reference
| Task |
Command |
| List / wide / labels |
kubectl get <r> [-o wide] [--show-labels] [-A] |
| Full detail + events |
kubectl describe <r> <name> |
| Apply / preview |
kubectl apply -f f.yaml · kubectl diff -f f.yaml |
| Server-side apply |
kubectl apply --server-side -f f.yaml (k8s 1.22+) |
| Delete |
kubectl delete -f f.yaml / kubectl delete <r> <name> |
| Logs / follow / prev |
kubectl logs [-f] [--previous] [-c c] <pod> |
| Shell in |
kubectl exec -it <pod> -- sh |
| Port-forward |
kubectl port-forward svc/<s> L:R |
| Rollout |
kubectl rollout status|history|undo|restart <deploy> |
| Scale |
kubectl scale deploy/<d> --replicas=N |
| Debug pod |
kubectl debug -it <pod> --image=busybox --target=<c> (k8s 1.25+) |
| Explain a field |
kubectl explain deploy.spec.template.spec.containers |
| Switch namespace |
kubectl config set-context --current --namespace=<ns> |
| Can I…? |
kubectl auth can-i <verb> <resource> |
| Resource map |
kubectl api-resources |
| Output as jsonpath |
kubectl get pods -o jsonpath='{.items[*].metadata.name}' |
| Wait for condition |
kubectl wait --for=condition=Available deploy/web --timeout=120s |
| Build + apply kustomize |
kubectl apply -k overlays/prod/ |
Troubleshooting
A failing Pod's STATUS column is the fastest diagnostic. Map it to a cause, then confirm with kubectl describe pod <pod> (read the Events at the bottom).
| STATUS / symptom |
Likely cause |
First moves |
| ImagePullBackOff / ErrImagePull |
bad image name/tag, private registry without imagePullSecrets, rate-limit |
describe pod → Events; fix image or add a pull secret |
| CrashLoopBackOff |
container starts then exits/errors repeatedly |
logs --previous; check command/args, config, a failing probe, missing env/secret |
| Pending |
no node fits: insufficient CPU/mem, unschedulable taints, no matching nodeSelector/affinity, unbound PVC |
describe pod → Events ("FailedScheduling"); kubectl get pvc; check requests vs node capacity |
OOMKilled (in describe/last state) |
container exceeded its memory limit |
raise resources.limits.memory, or fix the leak; check requests too |
| Init:… / PodInitializing stuck |
an init container is failing/looping |
logs <pod> -c <init-container> |
| CreateContainerConfigError |
referenced ConfigMap/Secret/key missing |
describe pod; create/fix the referenced object |
| Terminating (stuck) |
finalizers, or graceful shutdown hanging |
check metadata.finalizers; --grace-period=0 --force as a last resort |
Common kubectl errors:
The connection to the server <host> was refused → wrong/empty context or cluster down. Check kubectl config current-context and your kubeconfig.
error: You must be logged in to the server (Unauthorized) → bad/expired credentials.
Error from server (Forbidden) → RBAC; confirm what you can do with kubectl auth can-i.
Error from server (NotFound) → wrong namespace (try -n <ns> / -A) or the object is truly absent.
no matches for kind "X" in version "Y" → a CRD isn't installed, or the wrong apiVersion.
References
For exhaustive detail, see the bundled reference files:
- references/kubectl.md — the full
kubectl CLI: verbs, output formats (-o jsonpath/custom-columns/go-template), selectors, the apply model (client- vs server-side, --prune), diff, rollout, scale/autoscale, exec/logs/cp/port-forward/proxy, debug, node ops (drain/cordon/taint), auth can-i, api-resources/explain, config, kustomize (-k), events, top, --dry-run, wait, --subresource, and plugins/krew.
- references/workloads.md — manifest authoring for workloads: Pod spec essentials (env, resources, probes, securityContext, init/sidecar containers, volumes), Deployment, ReplicaSet, StatefulSet, DaemonSet, Job, CronJob, HorizontalPodAutoscaler, PodDisruptionBudget, and scheduling controls (affinity, topology spread, tolerations, priority).
- references/cluster-resources.md — Service (incl. headless), Ingress/IngressClass, NetworkPolicy, ConfigMap/Secret, storage (PV/PVC/StorageClass, access modes), Namespace/ResourceQuota/LimitRange, RBAC (Role/ClusterRole/bindings/aggregation), ServiceAccount + bound tokens, DNS conventions, and the Downward API.
- references/version-features.md — source-cited feature → minimum-version map (what's bedrock vs. added later), so you know when each
(k8s 1.X+) annotation applies.
Resources
1---2name: kubernetes3description: Author and operate Kubernetes workloads with kubectl and YAML manifests — the kubectl CLI plus core resource authoring (Pods, Deployments, StatefulSets, Jobs/CronJobs, Services, Ingress, ConfigMaps/Secrets, PV/PVC, RBAC). Use when writing or debugging Kubernetes manifests, running kubectl (get/describe/apply/diff/rollout/logs/exec/debug/port-forward), inspecting a failing pod (CrashLoopBackOff/ImagePullBackOff/Pending/OOMKilled), managing contexts/namespaces, generating manifests with --dry-run=client, checking permissions with auth can-i, or doing server-side apply. Triggers on kubectl, kube, k8s, Pod/Deployment/Service/Ingress/ConfigMap YAML, kubeconfig, kustomize. This is the kubectl + resource/manifest layer — for installing or running a lightweight cluster use the k3s skill; cluster install/admin, client libraries, cloud-provider specifics, and Helm are out of scope.4---56# Kubernetes - kubectl + Manifest Authoring78## Overview910Kubernetes runs containerized workloads against a **declarative API**. You don't tell it *how* to run things; you declare *what* you want (a manifest's `spec`) and the system continuously works to make reality (`status`) match. `kubectl` is the CLI you use to submit that desired state and to inspect, debug, and roll out workloads against any cluster — regardless of how the cluster was built.1112This skill is the **kubectl + resource/manifest layer**: authoring core API objects and driving the API with `kubectl`. It is independent of how the cluster was stood up.1314> **Disambiguation:** This skill documents **`kubectl` and core-resource manifest authoring** — how to write Kubernetes objects and drive the API. It does **not** cover installing or administering a cluster. To **run a local or lightweight cluster** (install a single binary, join nodes, etcd snapshots, bundled ingress/LB/DNS, certs), use the **k3s** skill. Out of scope entirely: client libraries (client-go), cloud-provider specifics (EKS/GKE/AKS IAM, cloud LBs/CSI), and Helm (mention as a packaging option, defer).1516## Mental Model1718Four ideas unlock everything:19201. **Declarative desired state.** You declare *what* you want in a manifest (`spec`); the system drives reality (`status`) to match. `kubectl apply` submits desired state; controllers do the rest.212. **Control loops (reconciliation).** Every resource type has a controller that watches and drives `status` toward `spec`. A Deployment controller creates a ReplicaSet; the ReplicaSet controller creates Pods; the scheduler binds Pods to Nodes; the kubelet runs containers. Self-healing falls out of this for free.223. **Everything is an API object** addressed by **Group / Version / Kind (GVK)**: `apiVersion: apps/v1` + `kind: Deployment`. The empty "core" group is written as just `v1` (Pod, Service, ConfigMap, Secret, Namespace). Named groups include `apps/v1`, `batch/v1`, `networking.k8s.io/v1`, `rbac.authorization.k8s.io/v1`, `policy/v1`, `autoscaling/v2`, `storage.k8s.io/v1`. Run `kubectl api-resources` to see the live map.234. **Namespaces** scope most resources (Pods, Deployments, Services, ConfigMaps…). Cluster-scoped resources (Nodes, PersistentVolumes, Namespaces, ClusterRoles, StorageClasses, PriorityClasses) live outside any namespace. `default` exists out of the box; `kube-system` holds control-plane add-ons.2425Every object shares a shape: `apiVersion`, `kind`, `metadata` (name, namespace, labels, annotations), `spec` (desired), `status` (observed, managed by the system — **never author it**).2627## When to Use This Skill2829Use this skill when:30- **Writing/editing manifests** (YAML) for any core resource.31- **Driving kubectl**: deploy, inspect, debug, roll out, scale, exec/logs, port-forward, generate manifests, check RBAC.32- **Debugging a workload**: a Pod stuck Pending, CrashLoopBackOff, ImagePullBackOff, OOMKilled; reading events; describing resources.33- **Managing contexts/namespaces** across clusters via kubeconfig.3435### Relationship to the k3s skill3637This skill is the **kubectl + resource/manifest layer** — authoring Kubernetes objects and driving the API with `kubectl`, regardless of how the cluster was created. It does **not** cover standing up or administering a cluster. To **run a local or lightweight cluster** (install the single k3s binary, join nodes, snapshots, bundled ingress/LB/DNS/storage, certs), use the **k3s** skill. k3s hands you a working API endpoint and a kubeconfig; this skill is everything you do against it. (k3s even bundles `kubectl` — every command here works on a k3s cluster.) Out of scope: client libraries, cloud-provider specifics, and Helm.3839## Prerequisites4041**CRITICAL**: Before proceeding, verify kubectl is installed and check the version:4243```bash44kubectl version --client # prints e.g. "Client Version: v1.28.2"45```4647**Version note:** This skill is documented against the Kubernetes API as of **~1.37**; the empirical CLI baseline is **kubectl v1.28.2** (bundled **kustomize v5.0.4**). Long-standing features (GA at or before **1.20**) are "bedrock" and shown **unannotated**. Features added later are tagged inline as `(k8s 1.X+)` by their **GA** version — see [references/version-features.md](references/version-features.md) for the full feature → version map with source citations. **Version skew:** keep `kubectl` within **±1 minor** of the cluster.4849## Install kubectl + kubeconfig/contexts5051```bash52# macOS53brew install kubectl54# Linux (direct binary, matching minor)55curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"56sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl57kubectl version --client # verify58```5960(For a cluster to point it at, see the **k3s** skill.)6162**kubeconfig** lives at `~/.kube/config` (override with `$KUBECONFIG`, which may be a `:`-separated list that gets merged). It holds three lists — **clusters** (API server URL + CA), **users** (credentials), **contexts** (a cluster+user+namespace triple) — plus a `current-context`.6364```bash65kubectl config get-contexts # list; * marks current66kubectl config use-context <ctx> # switch cluster67kubectl config set-context --current --namespace=<ns> # set default namespace68kubectl config view --minify # effective config for current ctx69```7071(`kubectx` / `kubens` are popular third-party helpers for switching contexts/namespaces.)7273## Core Workflows7475### 1. Deploy + expose7677```bash78kubectl create deployment web --image=nginx --replicas=3 # imperative, quick79kubectl expose deployment web --port=80 --target-port=8080 # creates a ClusterIP Service80kubectl get deploy,rs,pods,svc -l app=web81```8283Prefer declarative for anything you keep: generate with `--dry-run=client -o yaml > web.yaml`, edit, then `kubectl apply -f web.yaml`.8485### 2. Inspect / debug a failing pod8687```bash88kubectl get pods # the STATUS column tells the story89kubectl describe pod <pod> # Events at the bottom are the #1 clue90kubectl logs <pod> [-c <container>] [--previous] # --previous = last crashed container91kubectl get events --sort-by=.lastTimestamp # or: kubectl events92```9394Map STATUS → cause in [Troubleshooting](#troubleshooting) below.9596### 3. Apply / diff / rollout cycle9798```bash99kubectl diff -f web.yaml # preview what apply would change100kubectl apply -f web.yaml # converge to desired state101kubectl rollout status deploy/web # wait for the rollout to finish102kubectl rollout history deploy/web103kubectl rollout undo deploy/web # roll back to previous revision104kubectl rollout restart deploy/web # re-roll pods (e.g. to pick up a changed Secret)105```106107### 4. Exec / logs / port-forward108109```bash110kubectl exec -it <pod> -- sh # shell in a running container111kubectl logs -f deploy/web # stream logs (Deployment → a pod)112kubectl port-forward svc/web 8080:80 # localhost:8080 → Service:80113```114115### 5. Generate manifests with `--dry-run=client` (offline, no cluster)116117```bash118kubectl create deployment web --image=nginx --dry-run=client -o yaml119kubectl create configmap app-cfg --from-literal=LOG=info --dry-run=client -o yaml120kubectl create cronjob nightly --image=busybox --schedule="0 2 * * *" --dry-run=client -o yaml121```122123These emit clean starter YAML you then edit (verified emitting on 1.28.2: deployment→`apps/v1`, job/cronjob→`batch/v1`, service/cm/secret→`v1`, rolebinding→`rbac.authorization.k8s.io/v1`, ingress→`networking.k8s.io/v1`, pdb→`policy/v1`, priorityclass→`scheduling.k8s.io/v1`).124125> **Not offline generators.** `kubectl run`, `kubectl expose`, `kubectl autoscale`, and `kubectl create role --resource=…` consult the API server **even under `--dry-run=client`** (for resource/GVR resolution), so they need a reachable cluster. Don't expect them to render YAML with no cluster.126127### 6. RBAC quick-check with `auth can-i`128129```bash130kubectl auth can-i create deployments # for yourself131kubectl auth can-i get pods --as=system:serviceaccount:ns:sa # impersonate132kubectl auth can-i --list # everything you can do133kubectl auth whoami # who am I (Experimental in 1.28)134```135136## Quick Reference137138| Task | Command |139|------|---------|140| List / wide / labels | `kubectl get <r> [-o wide] [--show-labels] [-A]` |141| Full detail + events | `kubectl describe <r> <name>` |142| Apply / preview | `kubectl apply -f f.yaml` · `kubectl diff -f f.yaml` |143| Server-side apply | `kubectl apply --server-side -f f.yaml` (k8s 1.22+) |144| Delete | `kubectl delete -f f.yaml` / `kubectl delete <r> <name>` |145| Logs / follow / prev | `kubectl logs [-f] [--previous] [-c c] <pod>` |146| Shell in | `kubectl exec -it <pod> -- sh` |147| Port-forward | `kubectl port-forward svc/<s> L:R` |148| Rollout | `kubectl rollout status\|history\|undo\|restart <deploy>` |149| Scale | `kubectl scale deploy/<d> --replicas=N` |150| Debug pod | `kubectl debug -it <pod> --image=busybox --target=<c>` (k8s 1.25+) |151| Explain a field | `kubectl explain deploy.spec.template.spec.containers` |152| Switch namespace | `kubectl config set-context --current --namespace=<ns>` |153| Can I…? | `kubectl auth can-i <verb> <resource>` |154| Resource map | `kubectl api-resources` |155| Output as jsonpath | `kubectl get pods -o jsonpath='{.items[*].metadata.name}'` |156| Wait for condition | `kubectl wait --for=condition=Available deploy/web --timeout=120s` |157| Build + apply kustomize | `kubectl apply -k overlays/prod/` |158159## Troubleshooting160161A failing Pod's STATUS column is the fastest diagnostic. Map it to a cause, then confirm with `kubectl describe pod <pod>` (read the **Events** at the bottom).162163| STATUS / symptom | Likely cause | First moves |164|------------------|--------------|-------------|165| **ImagePullBackOff / ErrImagePull** | bad image name/tag, private registry without `imagePullSecrets`, rate-limit | `describe pod` → Events; fix image or add a pull secret |166| **CrashLoopBackOff** | container starts then exits/errors repeatedly | `logs --previous`; check command/args, config, a failing probe, missing env/secret |167| **Pending** | no node fits: insufficient CPU/mem, unschedulable taints, no matching nodeSelector/affinity, unbound PVC | `describe pod` → Events ("FailedScheduling"); `kubectl get pvc`; check requests vs node capacity |168| **OOMKilled** (in `describe`/last state) | container exceeded its memory **limit** | raise `resources.limits.memory`, or fix the leak; check `requests` too |169| **Init:… / PodInitializing stuck** | an init container is failing/looping | `logs <pod> -c <init-container>` |170| **CreateContainerConfigError** | referenced ConfigMap/Secret/key missing | `describe pod`; create/fix the referenced object |171| **Terminating (stuck)** | finalizers, or graceful shutdown hanging | check `metadata.finalizers`; `--grace-period=0 --force` as a last resort |172173**Common kubectl errors:**174- `The connection to the server <host> was refused` → wrong/empty context or cluster down. Check `kubectl config current-context` and your kubeconfig.175- `error: You must be logged in to the server (Unauthorized)` → bad/expired credentials.176- `Error from server (Forbidden)` → RBAC; confirm what you can do with `kubectl auth can-i`.177- `Error from server (NotFound)` → wrong namespace (try `-n <ns>` / `-A`) or the object is truly absent.178- `no matches for kind "X" in version "Y"` → a CRD isn't installed, or the wrong apiVersion.179180## References181182For exhaustive detail, see the bundled reference files:183184- [references/kubectl.md](references/kubectl.md) — the full `kubectl` CLI: verbs, output formats (`-o jsonpath`/`custom-columns`/`go-template`), selectors, the apply model (client- vs server-side, `--prune`), `diff`, `rollout`, `scale`/`autoscale`, `exec`/`logs`/`cp`/`port-forward`/`proxy`, `debug`, node ops (`drain`/`cordon`/`taint`), `auth can-i`, `api-resources`/`explain`, `config`, kustomize (`-k`), `events`, `top`, `--dry-run`, `wait`, `--subresource`, and plugins/krew.185- [references/workloads.md](references/workloads.md) — manifest authoring for workloads: Pod spec essentials (env, resources, probes, securityContext, init/sidecar containers, volumes), Deployment, ReplicaSet, StatefulSet, DaemonSet, Job, CronJob, HorizontalPodAutoscaler, PodDisruptionBudget, and scheduling controls (affinity, topology spread, tolerations, priority).186- [references/cluster-resources.md](references/cluster-resources.md) — Service (incl. headless), Ingress/IngressClass, NetworkPolicy, ConfigMap/Secret, storage (PV/PVC/StorageClass, access modes), Namespace/ResourceQuota/LimitRange, RBAC (Role/ClusterRole/bindings/aggregation), ServiceAccount + bound tokens, DNS conventions, and the Downward API.187- [references/version-features.md](references/version-features.md) — source-cited feature → minimum-version map (what's bedrock vs. added later), so you know when each `(k8s 1.X+)` annotation applies.188189## Resources190191- **Help**: `kubectl help`, `kubectl <verb> --help`, `kubectl explain <type>[.<path>]`192- **Official docs**: https://kubernetes.io/docs/193- **Reference**: https://kubernetes.io/docs/reference/kubectl/194- **API reference**: https://kubernetes.io/docs/reference/kubernetes-api/