From e731bda6b10988384c7b1013818bedb44da006e9 Mon Sep 17 00:00:00 2001 From: vumast3r Date: Wed, 9 Sep 2026 17:11:05 -0600 Subject: [PATCH] docs: add missing Q21, Q105, Q106, Q110, Q113, Q121 write-ups Filled six gaps in the solutions guide (Helm, Kustomize generators, CRD validation, cluster audit, Gateway API canary, context namespace) so every question id in the bank (1-43, 101-122) has a section. Co-Authored-By: Claude Sonnet 5 --- CKA_SOLUTIONS_EXPLAINED.md | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/CKA_SOLUTIONS_EXPLAINED.md b/CKA_SOLUTIONS_EXPLAINED.md index 0d62f64..bee8f44 100644 --- a/CKA_SOLUTIONS_EXPLAINED.md +++ b/CKA_SOLUTIONS_EXPLAINED.md @@ -109,6 +109,16 @@ This guide explains how to approach and solve every question in the CKA exam ban --- +### Q21 · Helm Release Install and Upgrade +- **Concept**: Helm packages manifests as charts; `--set` overrides `values.yaml` at install/upgrade time, and every upgrade bumps the release revision (visible via `helm history`/`helm status`). +- **Step-by-Step**: + 1. Install into a new namespace with an override: `helm install {WS}/q21/chart -n --create-namespace --set replicaCount=`. + 2. **Verify** revision 1: `helm status -n `. + 3. Upgrade the same release, changing the Service type: `helm upgrade {WS}/q21/chart -n --set replicaCount= --set service.type=NodePort` (repeat any values you want kept, or add `--reuse-values`). + 4. **Verify**: `helm status -n ` shows `REVISION: 2` and `k -n get svc` shows `type: NodePort`. + +--- + ### Q33 · Aggregated ClusterRole - **Concept**: Aggregated ClusterRoles automatically aggregate permissions from other ClusterRoles that have matching labels defined in `aggregationRule.clusterRoleSelectors`. - **Step-by-Step**: @@ -190,6 +200,43 @@ This guide explains how to approach and solve every question in the CKA exam ban --- +### Q105 · [HARD] Kustomize with Generators and Patches +- **Concept**: Kustomize overlays combine `namespace`/`labels` transformers, a strategic-merge `patches` entry for simple field changes, a JSON 6902 `patches` entry for structural additions, and a `configMapGenerator` (which appends a content hash to the name and auto-rewrites every reference to it within the same kustomization). +- **Step-by-Step**: + 1. `overlays/prod/kustomization.yaml`: + ```yaml + resources: [../../base] + namespace: + labels: + - pairs: {tier: prod} + includeSelectors: false + patches: + - path: replicas.yaml + - path: envfrom.yaml + target: {kind: Deployment, name: web} + configMapGenerator: + - name: web-config + literals: [LOG_LEVEL=] + ``` + 2. `replicas.yaml` (strategic merge patch): a partial Deployment with `metadata.name: web` and `spec.replicas: `. + 3. `envfrom.yaml` (JSON 6902 patch): `- op: add`, `path: /spec/template/spec/containers/0/envFrom`, `value: [{configMapRef: {name: web-config}}]`. + 4. Apply: `k apply -k {WS}/q105/overlays/prod`. + 5. **Verify**: `k -n get deploy web -o jsonpath='{.spec.template.spec.containers[0].envFrom[0].configMapRef.name}'` returns the hashed name (e.g. `web-config-`), and `labels.tier=prod` is set without touching `spec.selector`. + +--- + +### Q106 · [HARD] CRD with Validation and Defaults +- **Concept**: An OpenAPI v3 schema on a CRD is enforced by the API server itself — `minimum`/`maximum` reject out-of-range numbers before the object is ever persisted, `required` forces fields to be present, and `default` fills in a value the caller omitted. +- **Step-by-Step**: + 1. In `spec.versions[0].schema.openAPIV3Schema.properties.spec.properties`, define `replicas: {type: integer, minimum: 1, maximum: 10}`, `environment: {type: string, enum: [prod, stage, dev], default: dev}`, `image: {type: string}`, and set `required: [replicas, image]`. + 2. Apply the CRD: `k apply -f crd.yaml`. + 3. Create the `good` CR with `replicas: 3`, `image: nginx:1.27`, `environment: `. + 4. Attempt an invalid CR (`replicas: 0`) and capture the rejection: `k apply -f bad.yaml 2> rejected.txt` (the API server refuses it because `0 < minimum`). + 5. Create the `defaulted` CR with only `replicas` and `image` set — the API server injects `environment: dev` automatically. + 6. **Verify**: `k -n default get defaulted -o jsonpath='{.spec.environment}'` prints `dev`. + +--- + ### Q122 · [HARD] Renew Control Plane Certificates - **Concept**: `kubeadm certs renew all` generates new certificates for all control-plane components. Static pods must be bounced to reload the new certs. - **Step-by-Step**: @@ -363,6 +410,27 @@ This guide explains how to approach and solve every question in the CKA exam ban --- +### Q110 · [HARD] Cluster Audit to Exact Files +- **Concept**: "Extract exact facts" tasks reward scripting `-o json` output through `jq`/`python3` instead of eyeballing `kubectl get` — the checker diffs your file byte-for-byte against the sorted, header-free expected output. +- **Step-by-Step**: + 1. Dump everything once: `k get pods -A -o json > /tmp/pods.json`. + 2. `no-readiness.txt`: filter pods (excluding `kube-system`) whose first container has no `readinessProbe`, print `/`, `sort` into the file. + 3. `per-node.txt`: group `Running` pods by `.spec.nodeName`, print ` `, sorted by node name. + 4. `images.txt`: from `kube-system` pods only, collect every `.spec.containers[*].image`, dedupe, sort. + 5. **Verify**: each file has no header row and is already `sort`-stable — re-running `sort -c` on it should exit 0. + +--- + +### Q121 · [HARD] The Context's Namespace +- **Concept**: A kubeconfig context carries its own default namespace (`contexts[].context.namespace`); commands run without `-n` land there. `kubectl config view --minify` shows only the active context, so it's the safe way to read that default without guessing. +- **Step-by-Step**: + 1. Discover the context's default namespace: `k config view --minify -o jsonpath='{..namespace}'`. + 2. Create the Deployment and Service **without** `-n`/`--namespace` so they inherit that default (do not assume it's `default`). + 3. Write the namespace name you discovered in step 1 to `{WS}/q121/ns.txt`. + 4. **Verify**: `k get deploy,svc ` (still no `-n`) shows them Running/present, and `k -n default get deploy ` returns not-found — confirming nothing leaked into `default`. + +--- + ## Domain 3: Services & Networking (20%) ### Q11 · NetworkPolicy (Ingress Restriction) @@ -477,6 +545,17 @@ This guide explains how to approach and solve every question in the CKA exam ban --- +### Q113 · [HARD] Gateway API Canary with Header Match +- **Concept**: Gateway API `HTTPRoute` rules are evaluated in order; a rule with a header `matches` entry only applies to requests carrying that header, letting you layer a canary override (100% to one backend) on top of a default weighted split. `parentRefs[].sectionName` pins the route to one specific `Gateway` listener instead of all of them. +- **Step-by-Step**: + 1. Create a `GatewayClass` (`controllerName: example.com/gw`) and a `Gateway` with two listeners — `web` for `.example.com` and `api` for `api..example.com`, both port 80. + 2. Create `HTTPRoute` with `spec.parentRefs: [{name: , sectionName: web}]` so it only attaches to the `web` listener. + 3. Rule 1 (checked first): `matches: [{headers: [{name: X-Canary, value: always}]}]`, `backendRefs: [{name: v2, weight: 100}]`. + 4. Rule 2 (default, no header match): `backendRefs: [{name: v1, weight: }, {name: v2, weight: }]`. + 5. **Verify**: `k -n get httproute -o yaml` shows both rules in order; a request with `X-Canary: always` always lands on `v2`, everything else splits by weight. + +--- + ### 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 in `Corefile`. - **Step-by-Step**: