Appendix A — kubectl cheatsheet¶
A task-organized
kubectlreference for this guide, current for Kubernetes v1.30+ (verified againstkubectlv1.35 / embedded Kustomize v5.7). Every command here is one this guide actually uses; the conventions (distrolesskubectl debug, the PSA-restrictedbookstorenamespace, Helm-pinned operator installs, the bootstrap order, server-side apply) are the guide's hard-won ones — they are called out where they matter, not invented here. Keep this open while you work; the Which chapter teaches this table at the end maps every area back to the chapter that explains why.
This is a reference, not a tutorial. It does not follow the nine-section
chapter anatomy. <NS> = a namespace, <POD>/<SVC>/<D> = object names,
<C> = a container name. The running example is the Bookstore in the
bookstore namespace (PSA enforce: restricted).
The one rule that prevents the worst outage: before any mutating command, confirm
kubectl config current-context. Acting on the wrong cluster is the single most expensive everyday mistake (00-foundations/07).
1. Context & namespace (always set the namespace)¶
kubectl config get-contexts # list all contexts (* = current)
kubectl config current-context # which cluster/user am I on RIGHT NOW?
kubectl config use-context <NAME> # switch the active context
kubectl config set-context --current --namespace=<NS> # default ns for THIS context
kubectl config view --minify # the effective config for the current context
Per-command overrides (do not rely on these for safety — set the context):
kubectl get pods -n <NS> # one-off namespace override
kubectl get pods -A # --all-namespaces
kubectl --context <CTX> -n <NS> get pods # fully explicit (scripts/CI)
Discipline: always either set the namespace on the context or pass
-n <NS>. A command with no namespace silently targetsdefault— a common "why is nothing there?" The Bookstore lives inbookstore, neverdefault.kubens/kubectx(https://github.com/ahmetb/kubectx) are widely-used third-party helpers (not part ofkubectl) for fast namespace/context switching; a shell prompt that shows the context is the cheapest safeguard.
2. Fast imperative creation (CKAD-speed) → manifest workflow¶
The guide's workflow: generate YAML imperatively, redirect to a file, edit, then
apply and keep in Git. --dry-run=client -o yaml is the bridge from "fast to
type" to "declarative and reviewable"
(00-foundations/06).
# The imperative -> manifest pattern (use this constantly):
kubectl create deployment catalog --image=bookstore/catalog:dev \
--dry-run=client -o yaml > catalog-deploy.yaml # generate, don't apply
$EDITOR catalog-deploy.yaml # add probes, resources, securityContext
kubectl apply -f catalog-deploy.yaml # declarative create/update
Generators (each accepts --dry-run=client -o yaml):
kubectl run catalog --image=bookstore/catalog:dev --port=8080 --restart=Never # a bare Pod
kubectl create deployment catalog --image=bookstore/catalog:dev --replicas=3
kubectl create job db-migrate --image=postgres:16 \
-- psql -h postgres -U bookstore -d bookstore -c 'SELECT 1' # args after -- are argv (no shell)
kubectl create cronjob cleanup --image=postgres:16 --schedule="0 3 * * *" \
-- sh -c '/scripts/cleanup.sh' # use sh -c for a path; bare 'cleanup.sh' would resolve via $PATH
kubectl create configmap catalog-config --from-literal=LOG_LEVEL=info \
--from-file=app.properties
kubectl create secret generic db-credentials \
--from-literal=POSTGRES_PASSWORD=devpassword # base64, NOT encryption
kubectl create secret docker-registry regcred \
--docker-server=<REG> --docker-username=<U> --docker-password=<P>
kubectl create serviceaccount catalog-sa
kubectl create role catalog-config-reader --verb=get --resource=configmaps \
--resource-name=catalog-config
kubectl create rolebinding catalog-config-reader-binding \
--role=catalog-config-reader --serviceaccount=bookstore:catalog-sa
kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
kubectl create clusterrolebinding pr --clusterrole=pod-reader --serviceaccount=bookstore:catalog-sa
kubectl create quota bookstore-quota --hard=cpu=4,memory=8Gi,pods=20
kubectl create namespace bookstore
kubectl create ingress bookstore --rule="bookstore.localdev.me/*=storefront:80"
Expose a workload as a Service:
kubectl expose deployment catalog --port=80 --target-port=8080 --name=catalog
kubectl expose deployment catalog --port=8080 --type=ClusterIP --dry-run=client -o yaml
In-place edits to running objects (fast for learning/incident response; in production change the source, not the live object — 00-foundations/06):
kubectl set image deploy/catalog catalog=bookstore/catalog:dev -n bookstore
kubectl set env deploy/catalog -n bookstore LOG_LEVEL=warn # set an env var
kubectl set env deploy/catalog -n bookstore LOG_LEVEL- # trailing '-' DELETES it
kubectl set resources deploy/catalog -n bookstore \
--requests=cpu=50m,memory=64Mi --limits=cpu=250m,memory=128Mi
kubectl set serviceaccount deploy/catalog catalog-sa -n bookstore
kubectl scale deploy/catalog --replicas=4 -n bookstore
kubectl scale deploy/catalog --replicas=4 --current-replicas=3 -n bookstore # guarded
kubectl autoscale deploy/catalog --min=2 --max=10 --cpu-percent=70 -n bookstore
kubectl label pod <POD> tier=backend -n bookstore [--overwrite]
kubectl annotate deploy/catalog kubernetes.io/change-cause="bump to 1.4" -n bookstore
kubectl patch deploy/catalog -n bookstore --type=json \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path","value":"/readyz"}]'
kubectl patch deploy/catalog -n bookstore --type=merge -p='{"spec":{"replicas":3}}'
Rollout management (Deployments/StatefulSets/DaemonSets):
kubectl rollout status deploy/catalog -n bookstore # wait for the rollout
kubectl rollout history deploy/catalog -n bookstore # revisions
kubectl rollout history deploy/catalog -n bookstore --revision=3
kubectl rollout undo deploy/catalog -n bookstore # roll back one revision
kubectl rollout undo deploy/catalog -n bookstore --to-revision=2
kubectl rollout restart deploy/catalog -n bookstore # re-roll (e.g. pick up a rotated Secret)
kubectl rollout pause deploy/catalog -n bookstore # batch several edits then resume
kubectl rollout resume deploy/catalog -n bookstore
Schema discovery (authoritative, version-correct — reach for it constantly):
kubectl explain deploy.spec.template.spec.containers # one level
kubectl explain deploy.spec --recursive # the whole subtree
kubectl explain pod.spec.securityContext --recursive # what 'restricted' fields exist
kubectl api-resources # every kind, its group, namespaced?
kubectl api-resources --namespaced=true -o wide # verbs too
kubectl api-versions # every served group/version
3. Inspect & observe¶
kubectl get pods -n <NS> # list (STATUS, RESTARTS, AGE)
kubectl get pods -n <NS> -o wide # + node, Pod IP
kubectl get deploy,svc,pods -n <NS> # several kinds at once
kubectl get pod <POD> -n <NS> -o yaml # full spec AND controller-written status
kubectl get pod <POD> -n <NS> -o json
kubectl get pods -n <NS> -w # watch (stream changes)
kubectl get pods -n <NS> --watch-only # only subsequent changes
kubectl get pods -A --sort-by=.metadata.creationTimestamp # newest last
kubectl get pods -n <NS> --show-labels # all labels
kubectl get pods -n <NS> -L app -L version # selected labels as columns
kubectl get pods -n <NS> -l app=catalog # equality selector
kubectl get pods -n <NS> -l 'app in (catalog,orders)' # set-based selector
kubectl get pods -n <NS> -l 'app,!canary' # has 'app', NOT 'canary'
kubectl get pods -n <NS> --field-selector status.phase=Running
Custom output — jsonpath, custom-columns, go-template:
# jsonpath: pull exact fields (note the {} and quoting)
kubectl get pod <POD> -n <NS> -o jsonpath='{.spec.containers[0].image}{"\n"}'
kubectl get pods -n <NS> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
# custom-columns: a tidy table
kubectl get pods -n <NS> \
-o custom-columns='NAME:.metadata.name,IMAGE:.spec.containers[0].image,NODE:.spec.nodeName'
# go-template (when jsonpath is not enough)
kubectl get pods -n <NS> \
-o go-template='{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'
describe, events, resource usage, raw endpoints:
kubectl describe pod <POD> -n <NS> # human view + the Events section
kubectl describe deploy/catalog -n <NS>
# kubectl events (the modern command; richer than `get events`):
kubectl events -n <NS> # namespace events
kubectl events -n <NS> --for pod/<POD> # events for ONE object
kubectl events -n <NS> --types=Warning # warnings only
kubectl events -n <NS> -w # stream
kubectl get events -n <NS> --sort-by=.lastTimestamp # older form, still valid
kubectl top pod -n <NS> # live CPU/mem (needs metrics-server)
kubectl top pod -n <NS> --containers
kubectl top node
kubectl get --raw='/readyz?verbose' # API server health gates
kubectl get --raw='/livez?verbose'
kubectl get --raw='/metrics' | head # apiserver Prometheus metrics
kubectl cluster-info # control-plane endpoints
kubectl get componentstatuses # legacy; prefer /readyz on modern clusters
4. Debug — guide-consistent (distroless, PSA-restricted)¶
The reflex that fails in this codebase.
catalog,orders, andpayments-workerare distrolessgcr.io/distroless/static:nonrootimages: no shell, nops, nocurl.kubectl exec catalog -- shreturnsexec: "sh": executable file not found. The correct tool iskubectl debugwith an ephemeral container.postgres/redis/rabbitmqare stock images and do have a shell — the Bookstore is mixed; know which (08-day-2-operations/03).
Logs and the troubleshooting trident:
kubectl logs <POD> -n <NS> # stdout/stderr
kubectl logs <POD> -n <NS> -c <C> # a specific container
kubectl logs <POD> -n <NS> -f # follow
kubectl logs <POD> -n <NS> --previous # the PREVIOUS (crashed) container — CrashLoop
kubectl logs <POD> -n <NS> --since=15m # time-bounded
kubectl logs <POD> -n <NS> --tail=100 --timestamps
kubectl logs deploy/catalog -n <NS> --all-containers # logs across a workload's pods
kubectl logs -n <NS> -l app=catalog --prefix # by label, prefix each line with the pod
kubectl debug — ephemeral containers (the right primitive for distroless):
# (a) EPHEMERAL debug into a RUNNING distroless pod — inject a tooling
# container that SHARES the target's PROCESS + NETWORK namespaces.
# --target=<CTR> requires a *Pod name* (not a Deployment): with a workload
# name kubectl debug does copy-to instead, NOT ephemeral injection. Resolve
# one pod of the workload first. --profile=restricted (GA in v1.30) shapes
# it runAsNonRoot + drop ALL + seccomp RuntimeDefault so PSA admits it.
POD=$(kubectl get pod -n bookstore -l app=catalog \
-o jsonpath='{.items[0].metadata.name}')
kubectl debug -it -n bookstore pod/"$POD" \
--image=nicolaka/netshoot --target=catalog --profile=restricted -- /bin/bash
# inside: curl -s localhost:8080/healthz ; nslookup postgres ; nc -vz postgres 5432 ; ps aux
# (the ephemeral container is gone on exit; the live Pod is untouched.)
# (b) Debug a COPY (mutate freely — swap image/entrypoint — live Pod untouched).
# This form DOES take a Pod name OR a workload; --copy-to makes a new Pod:
kubectl debug -n bookstore pod/"$POD" --copy-to=catalog-dbg \
--set-image=catalog=busybox:1.36 --profile=restricted -- sh
# equivalently from the Deployment: kubectl debug -n bookstore deploy/catalog \
# --copy-to=catalog-dbg --set-image=catalog=busybox:1.36 --profile=restricted -- sh
kubectl delete pod catalog-dbg -n bookstore # clean up the copy when done
# Node-level debugging (host fs at /host, host namespaces) — for kubelet/containerd/disk:
kubectl debug node/<NODE> -it --profile=sysadmin --image=busybox:1.36
Why
--profile, not a bare--image. An ephemeral container joins the target Pod's namespace, so inbookstoreit must itself satisfy PSArestricted.--profile=restrictedshapes it to comply (use this forbookstore); a bare--image=busyboxwith no profile is rejected by PSA. The fallback for a tool image that cannot be made restricted-compliant: debug a copy in thedefaultnamespace (--copy-to=dbg --namespace=default), which has no PSA enforcement. Profiles:restricted(PSA-restrictedns — the Bookstore),general(non-PSA ns),sysadmin/netadmin(privileged / NET_ADMIN, fornode/<N>debugging only) (08-day-2-operations/03, 05-security/02).
Ad-hoc pod in the bookstore namespace — must be restricted-compliant. The
one-liner --overrides JSON the guide uses (busybox/curl/netshoot all run fine
under this securityContext):
kubectl run sa-peek -n bookstore --image=busybox:1.36 --restart=Never -i --rm \
--overrides='{"apiVersion":"v1","spec":{"securityContext":{"runAsNonRoot":true,"runAsUser":65532,"seccompProfile":{"type":"RuntimeDefault"}},"containers":[{"name":"sa-peek","image":"busybox:1.36","securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}},"command":["sh","-c","echo restricted-compliant pod OK"]}]}}'
# NOTE: "apiVersion":"v1" is REQUIRED (kubectl needs the Pod wrapper to
# merge the override). The "containers" override REPLACES the generated
# container (it does not merge), so "name" AND "image" must be repeated
# correctly. Preview the merged Pod with --dry-run=client -o yaml:
# kubectl run sa-peek -n bookstore --image=busybox:1.36 --restart=Never \
# --dry-run=client -o yaml --overrides='{...same JSON...}'
# (Or: run an unconstrained throwaway pod in the `default` namespace, which
# does NOT enforce PSA — the simplest path when you just need a scratch pod.)
exec, port-forward, cp, attach (note: exec ... sh only works on
images that have a shell — not the distroless Go services):
kubectl exec -it -n <NS> <POD> -c <C> -- sh # shell (stock images only)
kubectl exec -n <NS> <POD> -- env # one-shot command
kubectl exec -n bookstore statefulset/postgres -- psql -U bookstore -c '\dt'
kubectl port-forward -n <NS> pod/<POD> 8080:8080 # tunnel localhost:8080 -> pod:8080
kubectl port-forward -n <NS> svc/catalog 8080:80 # forward to a Service
kubectl cp <NS>/<POD>:/path/in/pod ./local # copy out (needs tar in the image)
kubectl attach -it -n <NS> <POD> # attach to PID 1's stdio
5. Apply / diff / server-side apply¶
kubectl apply -f manifest.yaml # declarative create/update (3-way merge)
kubectl apply -f dir/ # a directory of manifests
kubectl apply -f https://example.com/manifest.yaml # a URL (pin the URL — see note)
kubectl apply -k overlays/dev # render a kustomization, then apply
kubectl apply -f manifest.yaml --dry-run=client # parse + local validate, NO cluster
kubectl apply -f manifest.yaml --dry-run=server # run apiserver admission incl. PSA, NO persist
kubectl apply -f manifest.yaml --server-side --field-manager=ci # Server-Side Apply (field ownership)
kubectl apply -f manifest.yaml --server-side --force-conflicts # take ownership on conflict (use deliberately)
kubectl diff -f manifest.yaml # what apply WOULD change (live vs desired)
kubectl diff -k overlays/prod
kubectl replace -f manifest.yaml # full replace (object must exist)
kubectl replace --force -f manifest.yaml # delete + recreate (loses immutable-field history)
kubectl delete -f manifest.yaml # delete what a manifest declares
kubectl delete -k overlays/dev
kubectl kustomize overlays/prod # render only (no apply) — built into kubectl
Server dry-run is the PSA proof.
--dry-run=clientonly parses YAML.--dry-run=serverruns the full admission pipeline (including Pod Security Admission) without persisting — this is how the guide certifies every Bookstore workload is admitted underenforce: restricted(05-security/02, 07-delivery/01).Server-Side Apply (SSA). Each field has a recorded manager (
metadata.managedFields); the API server merges by field ownership and reports a conflict if two managers fight over the same field. This is what makes "Git owns most of the Deployment, an HPA ownsspec.replicas" safe. Prefer--server-sidefor GitOps/CI; resolve conflicts deliberately, not by reflexively adding--force-conflicts(00-foundations/06, appendix C).Operator installs — pin, do not
latest-URL. The guide installs operators (Prometheus, KEDA, Kyverno, Gateway API, snapshotter, CNPG, Argo) with pinned Helm charts (helm repo add … && helm install … --version <PINNED>), neverkubectl apply -f https://…/releases/latest/download/<PINNED-FILE>.yaml— that URL 404s the moment a new release ships (08-day-2-operations/05, 07-delivery/01).
6. RBAC & auth¶
kubectl auth whoami # your identity (the authN result)
kubectl auth can-i create pods -n <NS> # your authZ (SubjectAccessReview)
kubectl auth can-i --list -n <NS> # everything YOU can do here
kubectl auth can-i delete clusterroles # almost certainly: no
kubectl auth can-i get configmap/catalog-config -n bookstore \
--as=system:serviceaccount:bookstore:catalog-sa # audit a workload's SA
kubectl auth can-i --list -n bookstore \
--as=system:serviceaccount:bookstore:orders-sa # what can this SA do? (~nothing, by design)
kubectl auth can-i get secrets -n <NS> --as=alice --as-group=dev # impersonate user+group
kubectl create token catalog-sa -n bookstore # mint a short-lived SA token (TokenRequest API)
kubectl create token catalog-sa -n bookstore --duration=10m --audience=api
kubectl get sa,role,rolebinding,clusterrole,clusterrolebinding -n <NS>
kubectl describe clusterrole view # inspect a built-in role
--as/--as-groupis impersonation — itself an RBAC-gated power (impersonateverb), the canonical way to audit another identity without its credentials.kubectl auth can-iasks the real authorizer, so it is the authoritative answer (05-security/01).
7. Cleanup, labels & selectors¶
kubectl delete pod <POD> -n <NS>
kubectl delete pod <POD> -n <NS> --grace-period=0 --force # last resort (skips graceful shutdown)
kubectl delete pods -n <NS> -l app=catalog # by selector
kubectl delete deploy,svc -n <NS> -l app.kubernetes.io/part-of=bookstore
kubectl delete pods --all -n <NS>
kubectl delete namespace <NS> # deletes EVERYTHING in it (incl. PVCs)
kubectl delete -f manifest.yaml --wait=true # block until gone (finalizers)
kubectl get pods -n <NS> -l app=catalog -o name | xargs -r kubectl delete -n <NS>
kubectl label pods -n <NS> -l app=catalog tier=backend --overwrite
kubectl label pod <POD> -n <NS> tier- # trailing '-' REMOVES the label
A
kubectl delete namespace bookstore(or deleting a packaging tree that templates the Namespace) destroys the postgres PVC and its data. In production keep the namespace/PVCs out of the release's ownership (07-delivery/01, 08-day-2-operations/02).
8. The Bookstore bootstrap order (the standing invariant)¶
Every flow that brings up catalog/orders must respect this order, or you get
schema-missing CrashLoopBackOff and a kubectl wait timeout
(09-end-to-end-bookstore/01,
05-security/01):
# from the repo root (full-guide/)
kubectl apply -f examples/bookstore/raw-manifests/00-namespace.yaml # ns + PSA restricted labels
kubectl apply -f examples/bookstore/raw-manifests/05-serviceaccounts-rbac.yaml
kubectl apply -f examples/bookstore/raw-manifests/15-catalog-config.yaml # config
kubectl apply -f examples/bookstore/raw-manifests/16-db-credentials.yaml # secret (demo-only)
kubectl apply -f examples/bookstore/raw-manifests/35-priorityclasses.yaml # cluster-scoped
# ... workloads (10-/11-/14-/19-/20-/40-/12-/13-) ...
kubectl apply -f examples/bookstore/raw-manifests/21-db-migrate-job.yaml
kubectl wait --for=condition=complete job/db-migrate -n bookstore --timeout=180s # MUST complete first
kubectl wait --for=condition=available deploy --all -n bookstore --timeout=300s
kubectl wait is the generic gate primitive used throughout:
kubectl wait --for=condition=complete job/db-migrate -n bookstore --timeout=180s
kubectl wait --for=condition=available deploy --all -n bookstore --timeout=300s
kubectl wait --for=condition=Ready pod -l app=catalog -n bookstore --timeout=120s
kubectl wait --for=delete pod/postgres-0 -n bookstore --timeout=120s
kubectl wait --for=jsonpath='{.status.phase}'=Running pod/<POD> -n <NS>
kubectl rollout status statefulset/postgres -n bookstore # StatefulSet readiness gate
CKAD speed tips¶
┌─ FAST IN THE EXAM (and in real incident response) ───────────────────────────┐
│ • alias k=kubectl ; export do='--dry-run=client -o yaml' ; export now= │
│ '--grace-period=0 --force' → k run x --image=nginx $do > x.yaml │
│ • GENERATE, don't hand-write: create/run/expose ... --dry-run=client -o yaml │
│ > f.yaml, then edit. Faster and less error-prone than typing YAML. │
│ • kubectl explain <KIND>.spec.<FIELD> --recursive before guessing a field. │
│ • kubectl <CMD> --help | less — the per-command flags are exam-legal docs. │
│ • -o jsonpath / custom-columns to extract one value fast (image, nodeName). │
│ • k get po -w (or kubectl events -w) to watch a rollout converge live. │
│ • k delete po x $now to skip the 30s graceful term when you need it gone. │
│ • Set the namespace ONCE: k config set-context --current --namespace=<NS>. │
│ • kubectl debug (NOT exec sh) for distroless; --profile=restricted in a │
│ PSA-restricted ns. │
│ • --dry-run=server validates against admission (incl. PSA) without applying. │
│ • k apply -k <OVERLAY> / k kustomize <OVERLAY> — Kustomize is built in. │
└──────────────────────────────────────────────────────────────────────────────┘
Which chapter teaches this¶
Every command area maps back to the chapter that explains why it works that way. Read the chapter; keep this page for the syntax.
| Command area | Chapter that teaches it |
|---|---|
Contexts, kubeconfig, the everyday verbs, kubectl as a REST client |
00-foundations/07 — Local cluster setup |
The declarative model, apply 3-way merge, SSA, explain, diff, labels/selectors |
00-foundations/06 — The declarative API model |
| The API server pipeline (authN/authZ/admission) behind these calls | 00-foundations/04 — Control plane deep dive |
Pods, kubectl run, multi-container |
01-core-workloads/01 — Pods |
Probes, lifecycle, --previous, readiness vs Endpoints |
01-core-workloads/02 — Health and lifecycle |
set resources, requests/limits, QoS, OOM |
01-core-workloads/03 — Resources and QoS |
create deployment, scale, rollout *, set image |
01-core-workloads/04 — ReplicaSets and Deployments |
StatefulSet rollout status, ordinals |
01-core-workloads/05 — StatefulSets |
create job/cronjob, wait --for=condition=complete |
01-core-workloads/07 — Jobs and CronJobs |
expose, Services, Endpoints |
02-networking/02 — Services |
| DNS lookups from a debug container | 02-networking/03 — DNS and service discovery |
create ingress |
02-networking/04 — Ingress |
NetworkPolicy diagnosis (nc/nslookup from kubectl debug) |
02-networking/06 — Network policies |
create configmap, set env |
03-config-and-storage/01 — ConfigMaps |
create secret, why it is base64 not encryption, create token |
03-config-and-storage/02 — Secrets |
| PVC/StorageClass inspection | 03-config-and-storage/04 — Persistent storage |
Affinity/taint/topology fields (via explain/describe node) |
04-scheduling/02 — Affinity, taints, topology |
PriorityClass, preemption, Evicted |
04-scheduling/03 — Priority and preemption |
auth whoami/can-i, create token, RBAC objects, --as |
05-security/01 — Authn, authz, RBAC |
PSA restricted, --dry-run=server as the PSA proof, restricted --overrides/--profile |
05-security/02 — Pod security |
Image digests, kubectl debug & distroless rationale |
05-security/03 — Supply chain |
top pod/node, get --raw /metrics |
06-production-readiness/01 — Observability: metrics |
logs patterns, --since, -l --prefix |
06-production-readiness/02 — Logging |
autoscale, HPA inspection |
06-production-readiness/04 — Autoscaling |
| PodDisruptionBudget, drain interaction | 06-production-readiness/05 — Reliability and disruptions |
Helm-pinned operator installs, --dry-run=server cert |
07-delivery/01 — Packaging with Helm |
apply -k, kustomize, diff -k |
07-delivery/02 — Packaging with Kustomize |
cordon/drain/uncordon, version skew |
08-day-2-operations/01 — Cluster lifecycle |
kubectl debug (distroless, --profile=restricted), the per-symptom tree |
08-day-2-operations/03 — Troubleshooting playbook |
Namespaces, ResourceQuota, create quota |
08-day-2-operations/04 — Multi-tenancy and namespaces |
CRDs/operators, api-resources for CRD discovery |
08-day-2-operations/05 — Operators and CRDs |
The full bootstrap order & kubectl wait gating |
09-end-to-end-bookstore/01 — Bookstore end-to-end |
Node lifecycle (drain/cordon) and crictl (data-plane peek inside a kind node):
kubectl cordon <NODE> # mark unschedulable
kubectl drain <NODE> --ignore-daemonsets --delete-emptydir-data # evict (respects PDBs)
kubectl uncordon <NODE> # back into rotation
kubectl get nodes -o wide ; kubectl describe node <NODE> # capacity, conditions, taints
docker exec -it bookstore-control-plane crictl ps # kind node: running containers
docker exec -it bookstore-control-plane crictl pods # kind node: pod sandboxes
See also: Appendix B — Glossary for any term above,
Appendix C — YAML & API conventions for the
apply/SSA/jsonpath/deprecation details, and Appendix E — Learning
paths for where these commands appear in a study order.