32 KiB
32 KiB
CKA Simulator — Step-by-Step Solutions & Conceptual Guide
This guide explains how to approach and solve every question in the CKA exam bank. It breaks down the underlying Kubernetes concepts, the step-by-step commands, why specific flags are used, and how to verify your solution before submitting.
Domain 1: Cluster Architecture, Installation & Configuration (25%)
Q01 · RBAC for a Deployment Bot
- Concept: Role-Based Access Control (RBAC) separates permissions using
Roles(namespaced) andClusterRoles(cluster-wide), bound to users/ServiceAccounts viaRoleBindingsorClusterRoleBindings. - Step-by-Step:
- Create the ServiceAccount in the target namespace:
k -n rbac-app create sa deploy-bot - Create the Role with explicit verbs on
deployments.apps:k -n rbac-app create role deploy-manager \ --verb=get,list,watch,create,update,patch,delete \ --resource=deployments.apps - Bind the Role to the ServiceAccount:
k -n rbac-app create rolebinding deploy-bot-binding \ --role=deploy-manager \ --serviceaccount=rbac-app:deploy-bot - Verify using
kubectl auth can-i:k auth can-i create deployments -n rbac-app --as=system:serviceaccount:rbac-app:deploy-bot # yes k auth can-i delete pods -n rbac-app --as=system:serviceaccount:rbac-app:deploy-bot # no
- Create the ServiceAccount in the target namespace:
Q02 · etcd Snapshot
- Concept: etcd stores all cluster state. Snapshots require TLS certificates (CA cert, server cert, server key) and
ETCDCTL_API=3. - Step-by-Step:
- SSH / access the control plane node (
podman exec -it <control-plane> bashorssh <control-plane>). - Run
etcdctl snapshot savepointing to the etcd TLS certificates:ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ snapshot save /opt/cka/etcd-snapshot.db - Verify snapshot integrity:
etcdutl snapshot status /opt/cka/etcd-snapshot.db -w table
- SSH / access the control plane node (
Q03 · Kustomize Overlay
- Concept: Kustomize allows environment-specific customization (like
prodoverlays) without templating YAMLs. - Step-by-Step:
- Create the overlay folder:
mkdir -p workspace/q03/overlays/prod && cd workspace/q03/overlays/prod - Create
namespace.yamlforstore-prod. - Write
kustomization.yamlreferencing../../base, adding namespace, labels, and replica count. - Apply via
kubectl apply -k . - Verify:
k -n store-prod get deploy,pod -l env=prod
- Create the overlay folder:
Q04 · CustomResourceDefinition (CRD) & Custom Resource
- Concept: CRDs extend Kubernetes APIs with custom objects. Schema validation uses OpenAPI v3.
- Step-by-Step:
- Create the
CustomResourceDefinitionYAML specifyinggroup,names,scope: Namespaced, andopenAPIV3Schema. - Apply the CRD:
k apply -f crd.yaml. - Instantiate the Custom Resource (
Backupnamednightly). - Verify:
k get bkork get backups.
- Create the
Q05 · Static Pod Creation
- Concept: Static pods are managed directly by the Kubelet on a specific node without API server scheduling. Kubelet creates a mirror pod in the API server.
- Step-by-Step:
- SSH / access the target node.
- Check static pod path:
grep staticPodPath /var/lib/kubelet/config.yaml(usually/etc/kubernetes/manifests). - Create the pod manifest in that directory:
/etc/kubernetes/manifests/static-web.yaml. - Verify: Kubelet creates the mirror pod within seconds:
k get pods -o wide | grep static-web.
Q06 · Certificate Expiry & User CSR
- Concept: Kubeadm manages control-plane certs. Kubernetes CSR API (
certificates.k8s.io/v1) signs and approves client certificates. - Step-by-Step:
- On the control plane:
kubeadm certs check-expiration | grep '^apiserver ' > apiserver-expiry.txt. - Generate user private key and CSR with OpenSSL:
openssl genrsa -out jane.key 2048 openssl req -new -key jane.key -subj "/CN=jane" -out jane.csr - Submit
CertificateSigningRequestwithbase64 -w0 jane.csrand signerkubernetes.io/kube-apiserver-client. - Approve:
k certificate approve jane. - Extract certificate:
k get csr jane -o jsonpath='{.status.certificate}' | base64 -d > jane.crt. - Create RoleBinding binding user
janeto ClusterRoleview.
- On the control plane:
Q33 · Aggregated ClusterRole
- Concept: Aggregated ClusterRoles automatically aggregate permissions from other ClusterRoles that have matching labels defined in
aggregationRule.clusterRoleSelectors. - Step-by-Step:
- Create the parent ClusterRole with
aggregationRule: {clusterRoleSelectors: [{matchLabels: {rbac.example.com/aggregate-to-parent: "true"}}]}andrules: []. - Create sub-ClusterRoles (
pods,services) with required verbs. - Label the sub-ClusterRoles to trigger aggregation.
- Bind the parent ClusterRole to the user via
ClusterRoleBinding. - Verify:
k get clusterrole <name> -o yaml(rules will be automatically populated).
- Create the parent ClusterRole with
Q34 · Discover CRD Field with kubectl explain
- Concept:
kubectl explain <resource>.<field> --recursiveinspects the live schema for any built-in or custom resource. - Step-by-Step:
- Inspect CRD schema:
k explain <kind>.spec --recursive. - Check field description:
k explain <kind>.spec.tuning.<field>. - Write path to file:
echo spec.tuning.<field> > path.txt. - Create sample custom resource with that field configured.
- Inspect CRD schema:
Q40 · Kubeadm Join Token Creation
- Concept:
kubeadm token creategenerates authentication bootstrap tokens used by new nodes to join the cluster. - Step-by-Step:
- On control plane:
kubeadm token create --ttl 1h --print-join-command. - Save output to
join.sh. - Verify with
kubeadm token list.
- On control plane:
Q41 · Component Versions Inspection
- Concept: Control-plane components run as static pods; Kubelet runs as a systemd service.
- Step-by-Step:
- Server version:
k version. - Node versions:
k get node <node> -o jsonpath='{.status.nodeInfo.kubeletVersion} {.status.nodeInfo.containerRuntimeVersion}'. - etcd version:
k -n kube-system get pod -l component=etcd -o jsonpath='{.items[0].spec.containers[0].image}'.
- Server version:
Q101 · [HARD] RBAC Cleanup & Granular Privileges
- Concept: Principle of least privilege. Remove over-privileged admin bindings before granting surgical access.
- Step-by-Step:
- Find and delete over-granting binding:
k delete clusterrolebinding <sa>-legacy-admin. - Create Role for deployments & replicasets:
k -n <ns> create role <sa>-role --verb=get,list,watch,patch --resource=deployments.apps,replicasets.apps. - Add
pods/execcreate permissions to the Role. - Create ClusterRole with
listonnodesand bind it. - Verify:
k auth can-i --list -n <ns> --as=system:serviceaccount:<ns>:<sa>.
- Find and delete over-granting binding:
Q102 · [HARD] etcd Restore
- Concept: Restoring etcd from a snapshot requires stopping etcd, restoring data to a new data directory, and updating the etcd static pod hostPath volume.
- Step-by-Step:
- On control plane, restore snapshot:
etcdutl snapshot restore /opt/cka/backup.db --data-dir /var/lib/etcd-restore. - Edit
/etc/kubernetes/manifests/etcd.yaml:- Update the
etcd-datahostPath volume path from/var/lib/etcdto/var/lib/etcd-restore.
- Update the
- Wait for Kubelet to restart etcd and the API server to reconnect (
watch crictl ps). - Verify:
k get cm <restored-cm>.
- On control plane, restore snapshot:
Q103 · [HARD] Static Pod on Relocated Path
- Concept: Some nodes may have custom
staticPodPathconfigured in/var/lib/kubelet/config.yamlinstead of/etc/kubernetes/manifests. - Step-by-Step:
- Find target node:
k get nodes -l tier=edge. - On node, inspect
grep staticPodPath /var/lib/kubelet/config.yaml. - Write pod manifest directly into that specific directory.
- Verify:
k get pods -n <ns> -o wide.
- Find target node:
Q104 · [HARD] Self-Contained Kubeconfig Creation
- Concept: A portable kubeconfig embeds all certificates using
--embed-certsrather than referencing file paths. - Step-by-Step:
- Issue & approve CSR for the user; save
user.crtanduser.key. - Extract cluster CA:
k config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > ca.crt. - Set cluster, credentials, context, and current-context with
--kubeconfig=<file> --embed-certs. - Verify:
kubectl --kubeconfig=<file> get pods.
- Issue & approve CSR for the user; save
Q122 · [HARD] Renew Control Plane Certificates
- Concept:
kubeadm certs renew allgenerates new certificates for all control-plane components. Static pods must be bounced to reload the new certs. - Step-by-Step:
- On control plane:
kubeadm certs renew all. - Bounce static pods:
mv /etc/kubernetes/manifests/*.yaml /tmp/ && sleep 20 && mv /tmp/*.yaml /etc/kubernetes/manifests/. - Update admin config:
cp /etc/kubernetes/admin.conf ~/.kube/config. - Verify:
kubeadm certs check-expiration.
- On control plane:
Domain 2: Workloads & Scheduling (15%)
Q07 · Rolling Update Strategy & Scaling
- Concept:
maxSurgecontrols how many extra pods can be created during updates;maxUnavailablecontrols how many pods can be unavailable. - Step-by-Step:
- Update image:
k -n apps set image deploy web-frontend nginx=nginx:1.27. - Scale replicas:
k -n apps scale deploy web-frontend --replicas=4. - Patch strategy:
k -n apps patch deploy web-frontend -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'. - Verify:
k -n apps rollout status deploy web-frontend.
- Update image:
Q08 · Sidecar Container & Shared Volume
- Concept: Multi-container pods share volumes (
emptyDir) and localhost network namespace. - Step-by-Step:
- Define Pod with an
emptyDirvolume mounted at/var/login both the app container and sidecar container. - App writes logs to
/var/log/app.log; sidecar runstail -f /var/log/app.log. - Verify:
k -n apps logs log-shipper -c shipper.
- Define Pod with an
Q09 · Node Affinity & Resource Requests/Limits
- Concept:
nodeAffinitymatches node labels (requiredDuringSchedulingIgnoredDuringExecution). Resourcerequestsare used for scheduling;limitsenforce runtime boundaries. - Step-by-Step:
- Create deployment template:
k -n apps create deploy cache --image=redis:7-alpine --replicas=2 $do > cache.yaml. - Add
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecutionwithmatchExpressions: [{key: disktype, operator: In, values: [ssd]}]. - Add
resources: {requests: {cpu: 100m, memory: 64Mi}, limits: {cpu: 200m, memory: 128Mi}}. - Apply and verify scheduling:
k -n apps get pods -o wide.
- Create deployment template:
Q10 · ConfigMap & Secret Consumption
- Concept: ConfigMaps and Secrets can be mounted as files via volumes, loaded as individual environment variables (
valueFrom), or loaded entirely (envFrom). - Step-by-Step:
- Create ConfigMap:
k -n apps create cm app-config --from-literal=APP_MODE=production --from-literal=LOG_LEVEL=debug. - Create Secret:
k -n apps create secret generic db-creds --from-literal=username=admin --from-literal='password=S3cr3t!'. - In Pod spec: mount ConfigMap as volume at
/etc/config, injectAPP_MODEfrom CM, and useenvFromfordb-creds. - Verify:
k -n apps exec config-pod -- ls /etc/configandk -n apps exec config-pod -- env.
- Create ConfigMap:
Q23 · Metrics Server Repair & HPA
- Concept: Metrics Server provides CPU/memory metrics for
kubectl topand Horizontal Pod Autoscalers. In non-production/kind environments,--kubelet-insecure-tlsis required. - Step-by-Step:
- Edit metrics-server deployment:
k -n kube-system edit deploy metrics-server. Add--kubelet-insecure-tlsunder container args. - Verify:
k top nodes. - Create HPA:
k -n <ns> autoscale deploy <dep> --min=2 --max=<max> --cpu-percent=<cpu>. - Verify:
k -n <ns> get hpa.
- Edit metrics-server deployment:
Q24 · PriorityClass
- Concept: PriorityClasses determine pod preemption and scheduling order. Higher value = higher priority.
- Step-by-Step:
- Create
PriorityClasswithvalue: <integer>andglobalDefault: false. - Assign
priorityClassName: <name>in the Deployment pod template spec. - Verify:
k -n <ns> rollout status deploy <dep>.
- Create
Q25 · Taints & Tolerations
- Concept: Taints repel pods (
NoSchedule,PreferNoSchedule,NoExecute). Pods require matching tolerations to be scheduled on tainted nodes. - Step-by-Step:
- Taint node:
k taint node <node> key=val:NoSchedule. - Add toleration to deployment pod spec:
tolerations: - key: "key" operator: "Equal" value: "val" effect: "NoSchedule" - Set
nodeSelector: {kubernetes.io/hostname: <node>}.
- Taint node:
Q26 · DaemonSet on All Nodes (including Control Plane)
- Concept: DaemonSets ensure all (or some) nodes run a copy of a pod. To run on control-plane nodes, they must tolerate control-plane taints (
node-role.kubernetes.io/control-plane:NoSchedule). - Step-by-Step:
- Write
DaemonSetYAML with toleration:tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule - Apply and verify:
k -n <ns> get pods -o wide -l app=<ds>.
- Write
Q27 · CronJob Configuration
- Concept: CronJobs create Jobs on a time schedule (
schedule: "*/5 * * * *").concurrencyPolicy: Forbidensures jobs do not overlap. - Step-by-Step:
- Create CronJob:
k -n <ns> create cj <name> --image=busybox:1.36 --schedule='*/5 * * * *' $do -- date > cj.yaml. - Add
concurrencyPolicy: Forbid,successfulJobsHistoryLimit: 3,failedJobsHistoryLimit: 1,activeDeadlineSeconds: 30. - Trigger manual execution:
k -n <ns> create job <name>-manual --from=cronjob/<name>.
- Create CronJob:
Q28 · Init Containers
- Concept: Init containers run to completion sequentially before application containers start.
- Step-by-Step:
- Define
initContainersblock in Pod spec with shared volume mount (/work). - Init container writes content (
echo 'hello' > /work/index.html). - Main container mounts shared volume at
/usr/share/nginx/html. - Verify:
k -n <ns> exec <pod> -c web -- cat /usr/share/nginx/html/index.html.
- Define
Q29 · Immutable ConfigMap Rotation
- Concept: Setting
immutable: trueon ConfigMaps prevents accidental updates and reduces API server load. To update apps, create a new ConfigMap (v2) and update Deployment volume references. - Step-by-Step:
- Create
cm-v2withimmutable: true. - Patch Deployment volume to point to
cm-v2. - Monitor rolling update:
k -n <ns> rollout status deploy <dep>.
- Create
Q31 · Parallel Job
- Concept: Batch Jobs manage batch tasks.
completionsis total tasks to complete;parallelismis max concurrent pods. - Step-by-Step:
- Define Job with
completions: 4,parallelism: 2,backoffLimit: 2,restartPolicy: Never. - Apply and wait:
k -n <ns> wait --for=condition=complete job/<name> --timeout=120s.
- Define Job with
Q32 · ResourceQuota & LimitRange
- Concept:
ResourceQuotaenforces aggregate consumption limits in a namespace;LimitRangeenforces default/min/max resource requests and limits on individual containers. - Step-by-Step:
- Create quota:
k -n <ns> create quota <name> --hard=pods=4,requests.cpu=1,limits.memory=2Gi. - Create LimitRange with
default,defaultRequest,min,max. - Verify:
k -n <ns> describe quotaandk -n <ns> describe limitrange.
- Create quota:
Q107 · [HARD] Anti-Affinity under Strict Quota
- Concept: Spread replicas across distinct nodes using
podAntiAffinitywhile ensuring total resource requests do not breach namespace quotas. - Step-by-Step:
- Inspect quota:
k -n <ns> get quota. - Configure deployment with
podAntiAffinityontopologyKey: kubernetes.io/hostname. - Size container requests to fit within namespace quota.
- Verify: Each pod runs on a distinct node (
k get pods -o wide).
- Inspect quota:
Q108 · [HARD] Rollback Revision and Pause Rollout
- Concept:
rollout undo --to-revision=Nrolls back to a specific ReplicaSet revision.rollout pausehalts further container rollout. - Step-by-Step:
- Inspect history:
k -n <ns> rollout history deploy <dep>. - Undo:
k -n <ns> rollout undo deploy <dep> --to-revision=<rev>. - Pause:
k -n <ns> rollout pause deploy <dep>.
- Inspect history:
Q109 · [HARD] Native Sidecar Container (K8s 1.28+)
- Concept: Native sidecar containers are defined in
initContainerswithrestartPolicy: Always. They start before app containers and keep running throughout the pod's life. - Step-by-Step:
- Define initContainer with
restartPolicy: Alwaysand readiness probe. - Define main container with liveness probe.
- Verify:
k -n <ns> get pod <pod>shows all containers running.
- Define initContainer with
Domain 3: Services & Networking (20%)
Q11 · NetworkPolicy (Ingress Restriction)
- Concept: By default, pods accept traffic from any source. A
NetworkPolicyselects target pods withpodSelectorand restricts traffic using ingress/egress rules. - Step-by-Step:
- Create NetworkPolicy in namespace:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: {name: allow-frontend, namespace: marketing} spec: podSelector: {matchLabels: {app: api}} policyTypes: [Ingress] ingress: - from: - podSelector: {matchLabels: {role: frontend}} ports: - protocol: TCP port: 80 - Verify:
k -n marketing describe netpol allow-frontend.
- Create NetworkPolicy in namespace:
Q12 · NodePort Service
- Concept:
NodePortexposes the Service on each Node's IP at a static port (default range: 30000–32767). - Step-by-Step:
- Expose deployment:
k -n web expose deploy web-server --type=NodePort --port=80 --target-port=80 $do > svc.yaml. - Edit
spec.ports[0].nodePort: 30080. - Apply and verify:
k -n web get svc web-serverandk -n web get endpoints web-server.
- Expose deployment:
Q13 · Ingress Routing
- Concept: Ingress manages external HTTP/HTTPS routing to cluster Services based on hostname and URI path prefixes.
- Step-by-Step:
- Create Ingress imperatively:
k -n web create ingress web-ingress \ --class=nginx \ --rule="order.example.com/api*=order-service:8080" - Verify:
k -n web describe ingress web-ingress.
- Create Ingress imperatively:
Q14 · Cluster DNS Querying
- Concept: Services get DNS names in the format
<service>.<ns>.svc.cluster.local. Pods with IPa.b.c.dget<a-b-c-d>.<ns>.pod.cluster.local. - Step-by-Step:
- Run transient debug pod:
k run dns-test --image=busybox:1.36 --rm -it --restart=Never -- nslookup web-service.apps.svc.cluster.local. - Query pod IP record:
nslookup 10-244-1-5.apps.pod.cluster.local.
- Run transient debug pod:
Q22 · Gateway API Configuration
- Concept: Gateway API is the modern successor to Ingress.
GatewayClassdefines the controller,Gatewaydefines listeners/ports, andHTTPRoutedefines routing rules. - Step-by-Step:
- Create
GatewayClass(controllerName: example.com/gw). - Create
Gatewaywith HTTP listener on port 80. - Create
HTTPRouteattaching to the Gateway with path prefix matching/apiforwarding to target service. - Verify:
k -n <ns> get gateway,httproute.
- Create
Q30 · Named Ports in Service
- Concept: Services can map
targetPortto thenameof a container port rather than a numeric port. - Step-by-Step:
- In Pod/Deployment container:
ports: [{name: http-web, containerPort: 80}]. - In Service:
ports: [{name: http, port: 8080, targetPort: http-web}]. - Verify:
k -n <ns> get endpoints <svc>.
- In Pod/Deployment container:
Q42 · Egress-Only NetworkPolicy
- Concept: Egress NetworkPolicies restrict outbound traffic from pods to specific IP CIDR blocks or namespaces.
- Step-by-Step:
- Define policy with
policyTypes: [Egress]. - Add
egress: [{to: [{ipBlock: {cidr: 192.168.1.0/24}}], ports: [{port: 443}]}]. - Verify:
k -n <ns> describe netpol <name>.
- Define policy with
Q43 · Headless & ExternalName Services
- Concept:
clusterIP: None(Headless) returns direct Pod IPs on DNS queries.type: ExternalNamereturns a CNAME pointing to an external domain. - Step-by-Step:
- Create Headless Service:
spec.clusterIP: None,spec.selector: {app: db}. - Create ExternalName Service:
spec.type: ExternalName,spec.externalName: api.partner.com. - Verify:
k -n <ns> get svc.
- Create Headless Service:
Q111 · [HARD] Zero-Trust Namespace Network Policies
- Concept: Zero-trust architecture starts with default-deny on both ingress and egress, then explicitly allows DNS to kube-system (port 53 UDP/TCP) and tiered service-to-service communication.
- Step-by-Step:
- Create
default-denyfor both[Ingress, Egress]. - Create
allow-dnsegress policy tokube-systemon port 53. - Create
api-ingressfrom external labeled namespace. - Create
api-to-dbegress anddb-ingresspolicies on port 5432.
- Create
Q112 · [HARD] TLS Ingress with Certificate & Fingerprint
- Concept: Secure Ingress with TLS Secrets containing
tls.crtandtls.key. - Step-by-Step:
- Generate TLS key and self-signed certificate:
openssl req -x509 -newkey rsa:2048 -nodes -days 365 -subj "/CN=<host>" -keyout tls.key -out tls.crt - Create TLS secret:
k -n <ns> create secret tls <name>-tls --cert=tls.crt --key=tls.key. - Create Ingress with
tls: [{hosts: [<host>], secretName: <name>-tls}]and annotationnginx.ingress.kubernetes.io/ssl-redirect: "true". - Extract fingerprint:
openssl x509 -in tls.crt -noout -fingerprint -sha256 | cut -d= -f2 > fp.txt.
- Generate TLS key and self-signed certificate:
Q114 · [HARD] Multi-Fault CoreDNS Repair
- Concept: CoreDNS failures can be caused by blocking NetworkPolicies in
kube-system, deployment scaled to 0, or bad upstream forwarding inCorefile. - Step-by-Step:
- Check and delete rogue NetworkPolicy in
kube-system:k -n kube-system delete netpol maintenance-lockdown. - Scale CoreDNS back to 2 replicas:
k -n kube-system scale deploy coredns --replicas=2. - Fix
Corefilein ConfigMap:k -n kube-system edit cm coredns(changeforward . <bad-ip>toforward . /etc/resolv.conf). - Restart:
k -n kube-system rollout restart deploy coredns.
- Check and delete rogue NetworkPolicy in
Domain 4: Storage (10%)
Q15 · PersistentVolume, PVC & Pod Mounting
- Concept:
PersistentVolume(PV) represents physical cluster storage;PersistentVolumeClaim(PVC) is a request for storage by a user. - Step-by-Step:
- Create PV:
capacity: 1Gi,accessModes: [ReadWriteOnce],persistentVolumeReclaimPolicy: Retain,storageClassName: manual,hostPath: {path: /mnt/data}. - Create PVC:
storageClassName: manual,requests.storage: 500Mi. - Create Pod referencing PVC under
spec.volumesand mounting it in the container. - Verify:
k get pvandk -n storage get pvcshowBound.
- Create PV:
Q16 · Default StorageClass & Dynamic Provisioning
- Concept: When a PVC omits
storageClassName, Kubernetes provisions storage using the StorageClass annotated withstorageclass.kubernetes.io/is-default-class: "true". - Step-by-Step:
- Create new StorageClass with annotation
storageclass.kubernetes.io/is-default-class: "true". - Remove default annotation from old StorageClass:
k annotate sc <old-sc> storageclass.kubernetes.io/is-default-class-. - Create PVC without
storageClassNameand attach to Pod. - Verify: Storage is dynamically created and bound upon pod scheduling (
WaitForFirstConsumer).
- Create new StorageClass with annotation
Q35 · Re-bind Released PersistentVolume
- Concept: When a PVC is deleted, a PV with
Retainpolicy entersReleasedstatus becausespec.claimRefstill points to the old PVC UID. Removingspec.claimRefreturns it toAvailable. - Step-by-Step:
- Remove old claimRef:
k patch pv <pv> --type=json -p='[{"op":"remove","path":"/spec/claimRef"}]'. - Verify PV is now
Available:k get pv <pv>. - Create new PVC specifying
volumeName: <pv>. - Verify: Status transitions back to
Bound.
- Remove old claimRef:
Q36 · Data Persistence Across Pod Restarts
- Concept: Data written to a PersistentVolume survives pod termination and rescheduling.
- Step-by-Step:
- Create PVC.
- Run writer Pod (
restartPolicy: Never) writing data to/data/marker.txt. - Wait for writer Pod completion:
k wait --for=jsonpath='{.status.phase}'=Succeeded pod/writer. - Run reader Pod mounting the same PVC.
- Verify data:
k exec reader -- cat /data/marker.txt.
Q115 · [HARD] Local PV with Node Affinity Matching
- Concept: Local PersistentVolumes use
nodeAffinityto bind to specific worker nodes. Pods mounting the claim are automatically scheduled onto the matching node. - Step-by-Step:
- Inspect PV labels and node affinity:
k get pv -l media --show-labels. - Create PVC matching
selector: {matchLabels: {media: nvme}}. - Create Pod mounting the PVC.
- Verify: Pod schedules onto the node containing the NVMe disk without explicit
nodeSelector.
- Inspect PV labels and node affinity:
Q116 · [HARD] Data Migration Between PVCs via Batch Job
- Concept: Migrating data between volumes requires running a migration Job mounting both the old claim (
src) and new claim (dst). - Step-by-Step:
- Create
new-dataPVC. - Run batch Job mounting
old-datato/srcandnew-datato/dstrunningcp -a /src/. /dst/. - Wait for Job completion:
k wait --for=condition=complete job/migrate. - Update application Pod to reference
new-dataclaim. - Delete
old-dataclaim (PV remains retained).
- Create
Domain 5: Troubleshooting (30%)
Q17 · Node NotReady (Kubelet Inactive)
- Concept: A node reports
NotReadywhen the localkubeletservice is stopped, disabled, or failing to communicate with the API server. - Step-by-Step:
- Identify broken node:
k get nodes. - SSH / access the node:
podman exec -it <node> bashorssh <node>. - Check status:
systemctl status kubelet. - Enable & start service:
systemctl enable --now kubelet. - Check logs:
journalctl -u kubelet -f --no-pager. - Verify: Node transitions to
Ready.
- Identify broken node:
Q18 · Deployment & Service Misconfiguration
- Concept: Pods in
ImagePullBackOffhave invalid image names/tags; Services without endpoints have mismatchedspec.selectoror incorrecttargetPort. - Step-by-Step:
- Fix Deployment image:
k -n troubleshoot set image deploy payments payments=nginx:1.27. - Inspect Service:
k -n troubleshoot get svc payments -o yaml. - Fix typo in selector (
app: payments) and matchtargetPort: 80to container port. - Verify:
k -n troubleshoot get endpointslices -l kubernetes.io/service-name=payments.
- Fix Deployment image:
Q19 · CrashLoopBackOff Diagnosis
- Concept:
CrashLoopBackOffmeans the application process started and crashed. Check previous logs with--previous. - Step-by-Step:
- Read crash logs:
k -n troubleshoot logs crasher --previous | tee crasher.log. - Locate missing configuration:
FATAL: required environment variable DB_HOST is not set. - Export pod YAML, add
env: [{name: DB_HOST, value: db.internal}], strip metadata, delete and recreate pod. - Verify: Pod reaches
Runningstatus and stays healthy.
- Read crash logs:
Q20 · Control Plane Component Failure (Kube-Scheduler Static Pod)
- Concept: Static pods for
kube-apiserver,kube-scheduler,kube-controller-manager, andetcdlive in/etc/kubernetes/manifests/. Kubelet watches and restarts them automatically. - Step-by-Step:
- Check failing control-plane pod:
k -n kube-system get pods. - Check logs:
k -n kube-system logs kube-scheduler-<cp>. - SSH into control plane.
- Edit
/etc/kubernetes/manifests/kube-scheduler.yaml: fix binary command typo (kube-schedulerr->kube-scheduler). - Verify: Kubelet reloads the manifest and pods schedule normally.
- Check failing control-plane pod:
Q37 · CoreDNS Misconfiguration (Invalid Forwarding)
- Concept: CoreDNS forwards external queries based on the
Corefilein ConfigMapcorednsinkube-system. - Step-by-Step:
- Inspect logs:
k -n kube-system logs -l k8s-app=kube-dns. - Edit ConfigMap:
k -n kube-system edit cm coredns. - Replace invalid forward IP (
10.255.255.1) with/etc/resolv.conf. - Restart deployment:
k -n kube-system rollout restart deploy coredns. - Verify:
k run test-dns --image=busybox:1.36 --rm -it --restart=Never -- nslookup kubernetes.default.
- Inspect logs:
Q38 · Controller-Manager Crash (Invalid Flag)
- Concept: Invalid CLI flags in static pod manifests prevent components from starting.
- Step-by-Step:
- Check logs:
k -n kube-system logs kube-controller-manager-<cp>. - Error:
invalid flag: --leader-elect-lease-duration=1s. - On control plane, edit
/etc/kubernetes/manifests/kube-controller-manager.yamland remove the bad flag. - Verify: Controller manager restarts and reconciles deployments and ReplicaSets.
- Check logs:
Q39 · Kubelet Configuration Drift (Certificate Path)
- Concept: Kubelet configuration lives at
/var/lib/kubelet/config.yaml. Broken certificate paths prevent Kubelet from starting. - Step-by-Step:
- On broken worker, inspect
journalctl -u kubelet -n 30 --no-pager. - Error:
open /etc/kubernetes/pki/ca-bundle.crt: no such file or directory. - In
/var/lib/kubelet/config.yaml, fixclientCAFile: /etc/kubernetes/pki/ca.crt. - Restart kubelet:
systemctl restart kubelet && systemctl enable kubelet. - Verify:
systemctl status kubeletis active.
- On broken worker, inspect
Q117 · [HARD] Multi-Fault Worker Node (Dead Kubelet + Wrong CA + Cordoned)
- Concept: Killer.sh-style compound failures combine multiple root causes on a single node.
- Step-by-Step:
- Check node in cluster:
k get node <node>(showsNotReady,SchedulingDisabled). - Access node, check
systemctl status kubelet. - Fix wrong CA file in
/var/lib/kubelet/config.yaml(ca-wrong.crt->ca.crt). - Start kubelet:
systemctl enable --now kubelet. - Exit node back to main terminal.
- Uncordon the node:
k uncordon <node>. - Verify: Test scheduling on the node (
k run test-pod --overrides='{"spec":{"nodeName":"<node>"}}').
- Check node in cluster:
Q118 · [HARD] Two Control Plane Components Down Simultaneously
- Concept: Both
kube-schedulerandkube-controller-managerfail for different reasons (command typo + broken image tag). - Step-by-Step:
- On control plane, fix
kube-scheduler.yamlcommand typo (kube-schedulerr->kube-scheduler). - Fix
kube-controller-manager.yamlimage tag (remove broken suffix). - Verify:
k -n kube-system get pods -wshows all control-plane pods Running.
- On control plane, fix
Q119 · [HARD] Application Failure (4 Compound Reasons)
- Concept: Quota exhaustion + image tag typo + missing Secret key + broken Service selector.
- Step-by-Step:
- Patch namespace quota hard limit from 1 to 3 pods.
- Fix deployment image tag to
nginx:1.27. - Add missing key to Secret
DATABASE_URLand restart rollout. - Fix Service selector and targetPort.
- Verify: All 3 deployment replicas are Available with active endpoints.
Q120 · [HARD] Extract Cluster Networking Facts
- Concept: Extract network configuration directly from control-plane manifests and ConfigMaps.
- Step-by-Step:
- Pod CIDR:
k -n kube-system get pod -l component=kube-controller-manager -o yaml | grep cluster-cidr. - Service CIDR:
k -n kube-system get pod -l component=kube-apiserver -o yaml | grep service-cluster-ip-range. - CoreDNS ClusterIP:
k -n kube-system get svc kube-dns -o jsonpath='{.spec.clusterIP}'. - Kube-proxy mode:
k -n kube-system get cm kube-proxy -o yaml | grep '^ *mode:'(default:iptables). - Node PodCIDR:
k get node <node> -o jsonpath='{.spec.podCIDR}'.
- Pod CIDR: