KCA cheat sheet
KCA · Keep the key ideas within reach.
Kubernetes Core Concepts
A Pod is the smallest deployable unit: one or more containers sharing a network namespace (same IP and port space), IPC namespace, and mounted volumes; containers inside communicate over localhost.
API object hierarchy: Namespace scopes names for most objects; Pods are owned by ReplicaSets, which are owned by Deployments; ownerReferences and labels drive this relationship, not names.
A Service selects Pods by label selector and provides a stable virtual IP; ClusterIP (default, cluster-internal), NodePort (30000-32767 on every node), LoadBalancer (external LB), ExternalName (CNAME alias, no proxy).
Endpoints/EndpointSlices are populated by the control plane only for Pods that are Ready and match the selector; a selector mismatch or unready Pod yields an empty endpoint list.
ConfigMap holds non-confidential key-value data; Secret holds base64-encoded data (not encrypted at rest unless EncryptionConfiguration is set); both can be consumed as env vars, envFrom, or volume mounts.
Namespaces do not isolate network by default; NetworkPolicy is required. kube-system, kube-public, kube-node-lease and default exist out of the box.
Resource requests affect scheduling; limits affect runtime enforcement. CPU limits cause throttling (cfs quota); memory limits cause OOMKill of the container.
Static Pods are managed by the kubelet from a local manifest directory (e.g. /etc/kubernetes/manifests) and appear as mirror Pods in the API; they cannot be managed by the scheduler.
Installation, Configuration and Validation
kubeadm init phases: preflight, certificates, kubeconfig, kubelet-start, control-plane, etcd, upload-config, upload-certs, addon, and join stages; --dry-run and --v=5 expose what will happen.
kubeadm join requires a bootstrap token (or --discovery-file) and the API server address; tokens are stored as Secrets of type bootstrap.kubernetes.io/token in kube-system and expire after 24h by default.
Certificate expiry: kubeadm certs check-expiration; renew with kubeadm certs renew all; CA certs last 10 years, leaf certs 1 year by default (kubeadm v1.15+).
kubelet config lives in /var/lib/kubelet/config.yaml; the systemd unit reads it via --config. Container runtime endpoint is set with --container-runtime-endpoint (e.g. unix:///run/containerd/containerd.sock).
Validation order for a broken cluster: systemctl status kubelet, journalctl -u kubelet, crictl ps / crictl logs, then kubectl get nodes and kubectl describe node.
CNI plugin must be installed after kubeadm init for Pod networking and CoreDNS to become Ready; without it nodes stay NotReady with 'cni plugin not initialized'.
kubeconfig precedence: --kubeconfig flag > KUBECONFIG env var (colon-separated merge list) > $HOME/.kube/config. kubectl config view --minify shows the effective context.
Upgrades: control plane first (kubeadm upgrade apply), then kubelets one node at a time (drain, upgrade, uncordon); kubelet may be at most 3 minor versions behind the API server.
Security
RBAC is additive and allow-only: a request is allowed if any Role/ClusterRole binding grants it; there is no deny rule. Roles are namespaced, ClusterRoles are cluster-scoped.
verbs are the action (get, list, watch, create, update, patch, delete, deletecollection); resources and resourceNames narrow the target; nonResourceURLs apply to paths like /healthz and /metrics.
ServiceAccount tokens: legacy long-lived Secret tokens vs bound projected tokens (audience, expiry, automatically rotated). automountServiceAccountToken: false disables mounting.
Pod Security Admission modes: privileged, baseline, restricted, set per namespace via labels pod-security.kubernetes.io/enforce, -audit, -warn with a version label.
SecurityContext fields: runAsUser, runAsNonRoot, readOnlyRootFilesystem, allowPrivilegeEscalation, capabilities (drop ALL is the common hardening), seccompProfile, fsGroup.
Secrets are only obfuscated by base64; enable encryption at rest via --encryption-provider-config on kube-apiserver, and restrict get/list/watch on secrets with RBAC.
NetworkPolicy default-deny pattern: a policy selecting all Pods with empty podSelector and policyTypes [Ingress, Egress] with no rules blocks all traffic; add allow rules afterwards.
Admission chain order: mutating admission webhooks, then schema validation, then validating admission webhooks; validating webhooks can reject but cannot mutate.
Networking
Pod-to-Pod traffic is routed by the CNI plugin without NAT; every Pod gets a unique cluster-routable IP. Service ClusterIP traffic is DNATed by kube-proxy (iptables or IPVS mode).
DNS: ..svc.cluster.local; Pods use ..pod.cluster.local. CoreDNS is the cluster DNS server, exposed as Service kube-dns in kube-system.
DNS resolution config: /etc/resolv.conf options ndots:5 causes short names to be tried with search domains first; FQDN with trailing dot avoids search-path lookups.
Headless Service (clusterIP: None) returns Pod IPs directly in DNS A/AAAA records; used by StatefulSets for stable per-Pod DNS names.
Ingress is an L7 HTTP/HTTPS routing rule object; it needs an Ingress controller (e.g. ingress-nginx) to be enforced. Gateway API is the newer successor.
NodePort range defaults to 30000-32767 (kube-apiserver --service-node-port-range); kube-proxy programs the rules on every node.
NetworkPolicy is enforced by the CNI plugin, not by kube-proxy; if the plugin does not support it (e.g. basic flannel), policies are silently ignored.
Troubleshooting CNI: check /etc/cni/net.d for the active config, /opt/cni/bin for plugins, and kubelet logs for 'failed to set up sandbox'.
Troubleshooting
Pod lifecycle states: Pending (unscheduled or image pull pending), ContainerCreating, Running, Succeeded, Failed, Unknown. kubectl get pod -o wide and describe show events and last state.
CrashLoopBackOff means the container exits and kubelet restarts it with exponential backoff (10s, 20s, 40s ... capped at 5m). Check kubectl logs --previous.
ImagePullBackOff/ErrImagePull: wrong image name or tag, private registry without imagePullSecrets, or node cannot reach the registry.
Pending due to scheduling: describe shows '0/N nodes are available' with reasons - insufficient cpu/memory, node affinity mismatch, taints without tolerations, or unbound PVC.
TaintNoSchedule vs PreferNoSchedule vs NoExecute: NoExecute evicts running Pods that lack a matching toleration; NoSchedule only blocks new scheduling.
Node NotReady: check kubelet and container runtime status on the node; cordon/drain isolates a suspect node for investigation.
kubectl debug: ephemeral containers (kubectl debug -it pod --image=busybox --target=container) attach to a running Pod without restarting it.
Events are the primary signal: kubectl get events --sort-by=.lastTimestamp -A, or kubectl describe for the object-specific event list.
Workloads and Scheduling
Deployment strategy: RollingUpdate (maxSurge, maxUnavailable; default 25% each) or Recreate. rollback with kubectl rollout undo; status with kubectl rollout status.
StatefulSet guarantees stable identity (-0..N), ordered creation/deletion, and per-Pod PVCs via volumeClaimTemplates; requires a headless Service.
DaemonSet runs one Pod per eligible node (or per node matching nodeSelector/affinity); used for node agents, log shippers, and CNI.
Job runs to completion (completions, parallelism, backoffLimit, activeDeadlineSeconds); CronJob uses a cron schedule and concurrencyPolicy (Allow/Forbid/Replace).
Scheduling constraints: nodeSelector (simple label match), nodeAffinity (requiredDuringScheduling vs preferred), podAffinity/podAntiAffinity (topologyKey), and topologySpreadConstraints.
Taints and tolerations are node-side; node affinity is Pod-side. A taint repels Pods unless tolerated; a toleration does not force scheduling onto that node.
Resource-based scheduling uses sum of container requests, not limits; QoS classes: Guaranteed (requests==limits for all), Burstable, BestEffort (no requests/limits).
HorizontalPodAutoscaler scales replicas from metrics (CPU/memory via metrics-server or custom metrics); it requires resource requests to compute utilization percentages.
Kubernetes Core Concepts (continued)
kubectl get -o wide adds node and IP columns; -o yaml/json shows the full object; --show-managed-fields reveals server-side apply ownership.
Labels are for selection (kubectl get -l app=web); annotations hold non-identifying metadata and are not selectable.
Garbage collection: dependent objects are deleted when the owner is deleted unless ownerReference blockOwnerDeletion/foreground or orphan propagation is set.
A ReplicaSet ensures the desired number of identical Pods; a Deployment manages ReplicaSets and provides rollout history.
Namespace deletion is asynchronous; objects with finalizers block termination until the finalizer is removed.
kubectl explain . documents the API schema for the installed server version; --recursive expands nested fields.
Security (continued)
kubectl auth can-i --as=system:serviceaccount:ns:name tests RBAC for another identity without changing your own credentials.
RoleBinding can reference a ClusterRole, granting that ClusterRole's rules within the binding's namespace only.
Default ServiceAccount exists in every namespace; Pods use it unless spec.serviceAccountName is set.
Image pull secrets: spec.imagePullSecrets or the ServiceAccount's imagePullSecrets field; the kubelet uses them to authenticate to the registry.
Audit policy levels: None, Metadata, Request, RequestResponse; configured via --audit-policy-file on kube-apiserver.
Admission controllers that matter for security: NodeRestriction (limits kubelet's API access), PodSecurity, ResourceQuota, LimitRanger.
Networking (continued)
Service traffic path: client -> ClusterIP -> kube-proxy iptables/IPVS DNAT -> Pod IP. In iptables mode, conntrack entries keep flows sticky.
externalTrafficPolicy: Local preserves client source IP but only routes to Pods on the receiving node; Cluster sends to any node's Pods but SNATs.
sessionAffinity: ClientIP makes a Service sticky per client IP; default is None.
CoreDNS ConfigMap (coredns in kube-system) controls upstream forwarders, caching, and stub domains.
Ingress TLS uses a Secret of type kubernetes.io/tls with tls.crt and tls.key; the controller terminates TLS.
MTU mismatch between CNI overlay and node NIC causes intermittent large-packet failures; check with ping -M do -s .
Troubleshooting (continued)
kubectl top pod/node requires metrics-server; it reports current usage, not historical data.
OOMKilled in describe means the container exceeded its memory limit; increase the limit or fix the leak.
Evicted Pods appear with reason Evicted when the node is under disk or memory pressure; kubelet eviction thresholds govern this.
Image pull on a node uses the node's container runtime credentials; a Pod that pulls fine on one node may fail on another without the secret.
kubectl logs -f streams; --tail=N limits lines; --since=1h filters by time; -c selects a container in a multi-container Pod.
API server unreachable: check the control plane node, the kube-apiserver static Pod manifest, and the kubeconfig server URL.
Workloads and Scheduling (continued)
PodDisruptionBudget (minAvailable or maxUnavailable) limits voluntary disruptions during drain; it does not prevent node failure.
PriorityClass sets pod priority; higher-priority Pods can preempt lower-priority ones on a full node.
preemption does not guarantee placement; the preemptor is scheduled after victims are evicted.
initContainers run to completion before app containers start; they share the Pod's volumes but not its lifecycle.
Pod topology spread: topologySpreadConstraints with maxSkew and whenUnsatisfiable (DoNotSchedule/ ScheduleAnyway) balances Pods across zones or nodes.
Vertical Pod Autoscaler recommends or applies requests/limits; it does not add replicas, unlike HPA.
Installation, Configuration and Validation (continued)
kubeadm config images list shows the exact control plane images for the kubeadm version; --kubernetes-version pins them.
etcd backup: etcdctl snapshot save; restore with etcdctl snapshot restore and point --data-dir at the new directory.
kube-proxy mode is set in the kube-proxy ConfigMap (mode: iptables|ipvs); IPVS requires the ip_vs kernel modules.
Node registration: kubelet registers with the API server using the bootstrap token or a client cert; rotate certs with kubeadm certs renew.
Cluster validation: kubectl get componentstatuses is deprecated; use kubectl get --raw='/readyz?verbose' for API server health.
Static Pod manifests live in /etc/kubernetes/manifests on control plane nodes; editing them triggers kubelet to restart the Pod.