@xdev-asia/xdev-knowledge-mcp 1.0.44 → 1.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/content/series/luyen-thi/luyen-thi-cka/chapters/01-cluster-architecture/lessons/01-kien-truc-cka-kubeadm.md +133 -0
  2. package/content/series/luyen-thi/luyen-thi-cka/chapters/01-cluster-architecture/lessons/02-cluster-upgrade-kubeadm.md +147 -0
  3. package/content/series/luyen-thi/luyen-thi-cka/chapters/01-cluster-architecture/lessons/03-rbac-cka.md +152 -0
  4. package/content/series/luyen-thi/luyen-thi-cka/chapters/02-workloads-scheduling/lessons/04-deployments-daemonsets-statefulsets.md +186 -0
  5. package/content/series/luyen-thi/luyen-thi-cka/chapters/02-workloads-scheduling/lessons/05-scheduling-taints-affinity.md +163 -0
  6. package/content/series/luyen-thi/luyen-thi-cka/chapters/03-services-networking/lessons/06-services-endpoints-coredns.md +145 -0
  7. package/content/series/luyen-thi/luyen-thi-cka/chapters/03-services-networking/lessons/07-ingress-networkpolicies-cni.md +172 -0
  8. package/content/series/luyen-thi/luyen-thi-cka/chapters/04-storage/lessons/08-persistent-volumes-storageclass.md +159 -0
  9. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/09-etcd-backup-restore.md +149 -0
  10. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/10-troubleshooting-nodes.md +153 -0
  11. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/11-troubleshooting-workloads.md +146 -0
  12. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/12-troubleshooting-networking-exam.md +170 -0
  13. package/content/series/luyen-thi/luyen-thi-cka/index.md +1 -1
  14. package/content/series/luyen-thi/luyen-thi-ckad/chapters/01-app-design-build/lessons/01-multi-container-pods.md +146 -0
  15. package/content/series/luyen-thi/luyen-thi-ckad/chapters/01-app-design-build/lessons/02-jobs-cronjobs-resources.md +174 -0
  16. package/content/series/luyen-thi/luyen-thi-ckad/chapters/02-app-deployment/lessons/03-rolling-updates-rollbacks.md +148 -0
  17. package/content/series/luyen-thi/luyen-thi-ckad/chapters/02-app-deployment/lessons/04-helm-kustomize.md +181 -0
  18. package/content/series/luyen-thi/luyen-thi-ckad/chapters/03-app-observability/lessons/05-probes-logging-debugging.md +183 -0
  19. package/content/series/luyen-thi/luyen-thi-ckad/chapters/04-app-environment-config/lessons/06-configmaps-secrets.md +182 -0
  20. package/content/series/luyen-thi/luyen-thi-ckad/chapters/04-app-environment-config/lessons/07-securitycontext-pod-security.md +168 -0
  21. package/content/series/luyen-thi/luyen-thi-ckad/chapters/04-app-environment-config/lessons/08-resources-qos.md +168 -0
  22. package/content/series/luyen-thi/luyen-thi-ckad/chapters/05-services-networking/lessons/09-services-ingress.md +182 -0
  23. package/content/series/luyen-thi/luyen-thi-ckad/chapters/05-services-networking/lessons/10-networkpolicies-exam-strategy.md +236 -0
  24. package/content/series/luyen-thi/luyen-thi-ckad/index.md +1 -1
  25. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/01-kien-truc-kubernetes.md +137 -0
  26. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/02-pods-workloads-controllers.md +142 -0
  27. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/03-services-networking-storage.md +155 -0
  28. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/04-rbac-security.md +137 -0
  29. package/content/series/luyen-thi/luyen-thi-kcna/chapters/02-container-orchestration/lessons/05-container-runtimes-oci.md +137 -0
  30. package/content/series/luyen-thi/luyen-thi-kcna/chapters/02-container-orchestration/lessons/06-orchestration-patterns.md +147 -0
  31. package/content/series/luyen-thi/luyen-thi-kcna/chapters/03-cloud-native-architecture/lessons/07-cloud-native-architecture.md +143 -0
  32. package/content/series/luyen-thi/luyen-thi-kcna/chapters/04-observability-delivery/lessons/08-observability.md +143 -0
  33. package/content/series/luyen-thi/luyen-thi-kcna/chapters/04-observability-delivery/lessons/09-helm-gitops-cicd.md +162 -0
  34. package/content/series/luyen-thi/luyen-thi-kcna/index.md +1 -1
  35. package/data/quizzes.json +1059 -0
  36. package/package.json +1 -1
@@ -0,0 +1,183 @@
1
+ ---
2
+ id: ckad-d3-l05
3
+ title: 'Bài 5: Probes, Logging & Debugging'
4
+ slug: 05-probes-logging-debugging
5
+ description: >-
6
+ Liveness, Readiness và Startup Probes với các probe types (httpGet, tcpSocket,
7
+ exec). Kubectl logs, exec, debug và port-forward cho CKAD troubleshooting.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 5
12
+ section_title: "Domain 3: Application Observability and Maintenance (15%)"
13
+ course:
14
+ id: lt-ckad-series-001
15
+ title: 'Luyện thi CKAD — Certified Kubernetes Application Developer'
16
+ slug: luyen-thi-ckad
17
+ ---
18
+
19
+ <img src="/storage/uploads/2026/04/k8s-cert-ckad-bai5-probes.png" alt="Liveness, Readiness và Startup Probes — timeline và probe methods" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="probe-types">1. Ba loại Probe</h2>
22
+
23
+ <table>
24
+ <thead><tr><th>Probe</th><th>Mục đích</th><th>Khi fail?</th></tr></thead>
25
+ <tbody>
26
+ <tr><td><strong>Liveness</strong></td><td>Container có còn "sống" không?</td><td>Container bị restart</td></tr>
27
+ <tr><td><strong>Readiness</strong></td><td>Container có sẵn sàng nhận traffic?</td><td>Removed from Service endpoints (không restart)</td></tr>
28
+ <tr><td><strong>Startup</strong></td><td>App đã khởi động xong chưa?</td><td>Container bị restart (dùng trước liveness check)</td></tr>
29
+ </tbody>
30
+ </table>
31
+
32
+ <pre><code class="language-text">Probe execution timeline:
33
+
34
+ Container starts
35
+
36
+
37
+ startupProbe checks (periodically)
38
+ │ success
39
+
40
+ Both livenessProbe & readinessProbe run in parallel
41
+ │ │
42
+ ▼ fail ▼ fail
43
+ Container restart Removed from Service
44
+ (pod still running)</code></pre>
45
+
46
+ <h2 id="probe-methods">2. Probe Methods (httpGet, tcpSocket, exec)</h2>
47
+
48
+ <pre><code class="language-text">livenessProbe:
49
+ httpGet: # HTTP GET — success if status 200-399
50
+ path: /healthz
51
+ port: 8080
52
+ httpHeaders:
53
+ - name: Custom-Header
54
+ value: Awesome
55
+ initialDelaySeconds: 15 # Wait before first probe
56
+ periodSeconds: 20 # How often to probe
57
+ timeoutSeconds: 5 # Timeout per probe
58
+ failureThreshold: 3 # Fail count before action
59
+ successThreshold: 1 # Success count to pass
60
+
61
+ readinessProbe:
62
+ tcpSocket: # TCP connection — success if port open
63
+ port: 3306
64
+ initialDelaySeconds: 5
65
+ periodSeconds: 10
66
+
67
+ startupProbe:
68
+ exec: # Run command in container — success if exit 0
69
+ command:
70
+ - cat
71
+ - /tmp/healthy
72
+ failureThreshold: 30 # Allows 30*10s = 5 min to start
73
+ periodSeconds: 10</code></pre>
74
+
75
+ <table>
76
+ <thead><tr><th>Field</th><th>Default</th><th>Ý nghĩa</th></tr></thead>
77
+ <tbody>
78
+ <tr><td><code>initialDelaySeconds</code></td><td>0</td><td>Chờ trước khi probe đầu tiên</td></tr>
79
+ <tr><td><code>periodSeconds</code></td><td>10</td><td>Interval giữa các probes</td></tr>
80
+ <tr><td><code>timeoutSeconds</code></td><td>1</td><td>Timeout của mỗi probe</td></tr>
81
+ <tr><td><code>failureThreshold</code></td><td>3</td><td>Fail bao nhiêu lần thì action</td></tr>
82
+ <tr><td><code>successThreshold</code></td><td>1</td><td>Pass bao nhiêu lần để "healthy"</td></tr>
83
+ </tbody>
84
+ </table>
85
+
86
+ <blockquote><p><strong>Exam tip:</strong> <strong>Startup probe</strong> dùng khi app khởi động lâu (ví dụ: legacy app cần 2 phút load). Set <code>failureThreshold * periodSeconds</code> &gt;= thời gian startup tối đa. Liveness probe không chạy cho đến khi startup probe pass.</p></blockquote>
87
+
88
+ <h2 id="logging">3. Logging & kubectl logs</h2>
89
+
90
+ <pre><code class="language-text"># Xem logs của pod
91
+ kubectl logs podname
92
+
93
+ # Follow logs (tail -f)
94
+ kubectl logs -f podname
95
+
96
+ # Previous container (nếu bị crash)
97
+ kubectl logs podname --previous
98
+
99
+ # Logs của specific container trong multi-container pod
100
+ kubectl logs podname -c container-name
101
+
102
+ # Logs với timestamp
103
+ kubectl logs podname --timestamps
104
+
105
+ # Tail N lines
106
+ kubectl logs podname --tail=100</code></pre>
107
+
108
+ <h2 id="debugging">4. Debugging Commands</h2>
109
+
110
+ <pre><code class="language-text"># Exec vào container
111
+ kubectl exec -it podname -- /bin/bash
112
+ kubectl exec -it podname -c container-name -- sh
113
+
114
+ # Port forward để test service locally
115
+ kubectl port-forward pod/podname 8080:80
116
+ kubectl port-forward service/myservice 8080:80
117
+
118
+ # Ephemeral debug container (khi container không có shell)
119
+ kubectl debug -it podname --image=busybox --target=container-name
120
+
121
+ # Debug a node
122
+ kubectl debug node/worker-1 -it --image=ubuntu
123
+
124
+ # Copy files
125
+ kubectl cp podname:/app/logs/error.log ./error.log
126
+ kubectl cp ./config.yaml podname:/app/config.yaml</code></pre>
127
+
128
+ <blockquote><p><strong>Exam tip:</strong> Khi pod không có shell (distroless image), dùng <code>kubectl debug</code> với ephemeral container. Trong CKAD exam, <code>kubectl exec</code> + <code>kubectl logs</code> là 2 commands debugging quan trọng nhất. Luôn check logs trước khi exec.</p></blockquote>
129
+
130
+ <h2 id="pod-states">5. Common Pod States & Debug</h2>
131
+
132
+ <table>
133
+ <thead><tr><th>Pod State</th><th>Nguyên nhân thường gặp</th><th>Debug command</th></tr></thead>
134
+ <tbody>
135
+ <tr><td><code>CrashLoopBackOff</code></td><td>App crash, bad command, missing config</td><td><code>kubectl logs --previous</code></td></tr>
136
+ <tr><td><code>ImagePullBackOff</code></td><td>Wrong image name, registry auth failure</td><td><code>kubectl describe pod</code></td></tr>
137
+ <tr><td><code>Pending</code></td><td>Insufficient resources, unschedulable</td><td><code>kubectl describe pod</code> → Events</td></tr>
138
+ <tr><td><code>OOMKilled</code></td><td>Memory limit exceeded</td><td><code>kubectl describe pod</code> → Last State</td></tr>
139
+ <tr><td><code>Error</code></td><td>Init container failed, bad entrypoint</td><td><code>kubectl logs -c init-c</code></td></tr>
140
+ </tbody>
141
+ </table>
142
+
143
+ <h2 id="cheatsheet">6. Cheat Sheet</h2>
144
+
145
+ <table>
146
+ <thead><tr><th>Task</th><th>Command</th></tr></thead>
147
+ <tbody>
148
+ <tr><td>Check pod sức khỏe</td><td><code>kubectl describe pod &lt;name&gt;</code></td></tr>
149
+ <tr><td>Xem logs crash</td><td><code>kubectl logs &lt;pod&gt; --previous</code></td></tr>
150
+ <tr><td>Shell vào container</td><td><code>kubectl exec -it &lt;pod&gt; -- sh</code></td></tr>
151
+ <tr><td>Test service connectivity</td><td><code>kubectl port-forward svc/&lt;name&gt; 8080:80</code></td></tr>
152
+ <tr><td>Debug distroless container</td><td><code>kubectl debug -it &lt;pod&gt; --image=busybox</code></td></tr>
153
+ </tbody>
154
+ </table>
155
+
156
+ <h2 id="practice">7. Practice Questions</h2>
157
+
158
+ <p><strong>Q1:</strong> A Pod's readinessProbe fails, but the livenessProbe passes. What happens to the Pod?</p>
159
+ <ul>
160
+ <li>A) The Pod is restarted</li>
161
+ <li>B) The Pod is deleted</li>
162
+ <li>C) The Pod remains running but is removed from the Service's endpoint list ✓</li>
163
+ <li>D) The Pod is marked as Failed</li>
164
+ </ul>
165
+ <p><em>Explanation: Readiness probe failure does NOT restart the container. It only removes the Pod from the Service endpoints so no new traffic is routed to it. The Pod keeps running. When the readiness probe passes again, the Pod is re-added to the endpoints.</em></p>
166
+
167
+ <p><strong>Q2:</strong> An application takes 3 minutes to start. Without a startupProbe, the livenessProbe with failureThreshold: 3 and periodSeconds: 10 would kill the container before it finishes starting. How should you configure a startupProbe to allow up to 5 minutes for startup?</p>
168
+ <ul>
169
+ <li>A) startupProbe with failureThreshold: 5 and periodSeconds: 60</li>
170
+ <li>B) startupProbe with failureThreshold: 30 and periodSeconds: 10 ✓</li>
171
+ <li>C) startupProbe with failureThreshold: 300 and periodSeconds: 1</li>
172
+ <li>D) startupProbe with initialDelaySeconds: 300</li>
173
+ </ul>
174
+ <p><em>Explanation: failureThreshold × periodSeconds = maximum startup time. 30 × 10s = 300s = 5 minutes. During this window, the liveness probe is disabled. Once the startup probe succeeds, both liveness and readiness probes activate.</em></p>
175
+
176
+ <p><strong>Q3:</strong> You need to debug a running Pod that uses a distroless container image (no shell available). How do you get a shell for debugging?</p>
177
+ <ul>
178
+ <li>A) kubectl exec -it podname -- /bin/sh</li>
179
+ <li>B) kubectl attach podname -it</li>
180
+ <li>C) kubectl debug -it podname --image=busybox --target=app ✓</li>
181
+ <li>D) kubectl run debug --image=busybox --attach</li>
182
+ </ul>
183
+ <p><em>Explanation: kubectl debug with an ephemeral container injects a debug container (busybox) into the running Pod with access to the same process namespace. The --target flag shares the process namespace with the specified container. This works even when the main container has no shell.</em></p>
@@ -0,0 +1,182 @@
1
+ ---
2
+ id: ckad-d4-l06
3
+ title: 'Bài 6: ConfigMaps & Secrets'
4
+ slug: 06-configmaps-secrets
5
+ description: >-
6
+ Tạo và consume ConfigMaps và Secrets trong Kubernetes. Inject qua env vars
7
+ (envFrom, valueFrom) và volume mounts. Secret types và security considerations.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 6
12
+ section_title: "Domain 4: Application Environment, Configuration and Security (25%)"
13
+ course:
14
+ id: lt-ckad-series-001
15
+ title: 'Luyện thi CKAD — Certified Kubernetes Application Developer'
16
+ slug: luyen-thi-ckad
17
+ ---
18
+
19
+ <img src="/storage/uploads/2026/04/k8s-cert-ckad-bai6-configmap-secret.png" alt="ConfigMap và Secret injection — envFrom, valueFrom và Volume Mount" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="configmap">1. ConfigMap</h2>
22
+
23
+ <p>ConfigMap lưu trữ cặp key-value non-sensitive. Không được mã hóa (plain text).</p>
24
+
25
+ <pre><code class="language-text"># Tạo ConfigMap — Imperative
26
+ kubectl create configmap app-config \
27
+ --from-literal=DB_HOST=mysql \
28
+ --from-literal=DB_PORT=3306
29
+
30
+ kubectl create configmap app-config --from-file=config.properties
31
+ kubectl create configmap app-config --from-env-file=.env
32
+
33
+ # Declarative YAML
34
+ apiVersion: v1
35
+ kind: ConfigMap
36
+ metadata:
37
+ name: app-config
38
+ data:
39
+ DB_HOST: mysql
40
+ DB_PORT: "3306"
41
+ config.properties: |
42
+ server.port=8080
43
+ debug=false</code></pre>
44
+
45
+ <h2 id="secret">2. Secret</h2>
46
+
47
+ <p>Secret lưu trữ sensitive data. Được <strong>base64 encode</strong> (không phải mã hóa — encode thôi!).</p>
48
+
49
+ <pre><code class="language-text"># Tạo Secret — Imperative
50
+ kubectl create secret generic db-secret \
51
+ --from-literal=username=admin \
52
+ --from-literal=password=mypassword
53
+
54
+ kubectl create secret generic db-secret --from-file=credentials.txt
55
+
56
+ # Declarative (base64 encode trước)
57
+ echo -n 'admin' | base64 # YWRtaW4=
58
+ echo -n 'mypassword' | base64 # bXlwYXNzd29yZA==
59
+
60
+ apiVersion: v1
61
+ kind: Secret
62
+ metadata:
63
+ name: db-secret
64
+ type: Opaque
65
+ data:
66
+ username: YWRtaW4=
67
+ password: bXlwYXNzd29yZA==</code></pre>
68
+
69
+ <table>
70
+ <thead><tr><th>Secret Type</th><th>Mục đích</th></tr></thead>
71
+ <tbody>
72
+ <tr><td><code>Opaque</code></td><td>Generic — default type, any key-value data</td></tr>
73
+ <tr><td><code>kubernetes.io/dockerconfigjson</code></td><td>Docker registry credentials</td></tr>
74
+ <tr><td><code>kubernetes.io/tls</code></td><td>TLS certificate và private key</td></tr>
75
+ <tr><td><code>kubernetes.io/service-account-token</code></td><td>ServiceAccount token (auto-created)</td></tr>
76
+ </tbody>
77
+ </table>
78
+
79
+ <blockquote><p><strong>Exam tip:</strong> Secret data là <strong>base64 encoded, không encrypted</strong>. Bất kỳ ai có quyền đọc Secret đều có thể decode: <code>echo 'YWRtaW4=' | base64 -d</code>. Để encrypt at rest, phải enable EncryptionConfiguration — nhưng CKAD không test điều này. Exam thường test: tạo secret và inject vào Pod.</p></blockquote>
80
+
81
+ <h2 id="inject-env">3. Inject qua Environment Variables</h2>
82
+
83
+ <pre><code class="language-text">spec:
84
+ containers:
85
+ - name: app
86
+ image: myapp
87
+
88
+ # Method 1: envFrom — load ALL keys as env vars
89
+ envFrom:
90
+ - configMapRef:
91
+ name: app-config
92
+ - secretRef:
93
+ name: db-secret
94
+
95
+ # Method 2: valueFrom — load SPECIFIC key
96
+ env:
97
+ - name: DATABASE_HOST
98
+ valueFrom:
99
+ configMapKeyRef:
100
+ name: app-config
101
+ key: DB_HOST
102
+ - name: DB_PASSWORD
103
+ valueFrom:
104
+ secretKeyRef:
105
+ name: db-secret
106
+ key: password</code></pre>
107
+
108
+ <h2 id="inject-volume">4. Inject qua Volume Mount</h2>
109
+
110
+ <pre><code class="language-text">spec:
111
+ volumes:
112
+ - name: config-vol
113
+ configMap:
114
+ name: app-config
115
+ - name: secret-vol
116
+ secret:
117
+ secretName: db-secret
118
+
119
+ containers:
120
+ - name: app
121
+ image: myapp
122
+ volumeMounts:
123
+ - name: config-vol
124
+ mountPath: /etc/config # Each key becomes a file
125
+ - name: secret-vol
126
+ mountPath: /etc/secrets
127
+ readOnly: true
128
+
129
+ # Result: /etc/config/DB_HOST contains "mysql"
130
+ # /etc/secrets/password contains "mypassword" (decoded)</code></pre>
131
+
132
+ <table>
133
+ <thead><tr><th>Method</th><th>Khi dùng</th><th>Auto-update khi CM/Secret đổi?</th></tr></thead>
134
+ <tbody>
135
+ <tr><td><code>envFrom</code> / <code>env.valueFrom</code></td><td>App đọc env vars</td><td>Không (cần restart pod)</td></tr>
136
+ <tr><td>Volume mount</td><td>App đọc từ files, hoặc cần auto-reload</td><td>Có (sau ~1-2 phút)</td></tr>
137
+ </tbody>
138
+ </table>
139
+
140
+ <blockquote><p><strong>Exam tip:</strong> Volume-mounted ConfigMaps/Secrets tự động update khi nguồn thay đổi (sau kubelet sync period ~1 phút). Env vars phải restart pod mới reflect changes. CKAD thường test cả 2 methods — nắm rõ syntax của <code>configMapKeyRef</code> vs <code>configMapRef</code> (có chữ "Key" thì là single key).</p></blockquote>
141
+
142
+ <h2 id="cheatsheet">5. Cheat Sheet</h2>
143
+
144
+ <table>
145
+ <thead><tr><th>Task</th><th>Command / YAML</th></tr></thead>
146
+ <tbody>
147
+ <tr><td>Tạo CM từ literals</td><td><code>kubectl create cm name --from-literal=k=v</code></td></tr>
148
+ <tr><td>Tạo Secret từ literals</td><td><code>kubectl create secret generic n --from-literal=k=v</code></td></tr>
149
+ <tr><td>Load all CM keys as env</td><td><code>envFrom: - configMapRef: name: ...</code></td></tr>
150
+ <tr><td>Load specific key</td><td><code>env: - valueFrom: configMapKeyRef: ...</code></td></tr>
151
+ <tr><td>Mount as files</td><td><code>volumes: configMap/secret + volumeMounts</code></td></tr>
152
+ </tbody>
153
+ </table>
154
+
155
+ <h2 id="practice">6. Practice Questions</h2>
156
+
157
+ <p><strong>Q1:</strong> A Pod needs to consume ALL key-value pairs from a ConfigMap named "app-settings" as environment variables. Which configuration is correct?</p>
158
+ <ul>
159
+ <li>A) <code>env: - name: APP_SETTINGS valueFrom: configMapRef: name: app-settings</code></li>
160
+ <li>B) <code>envFrom: - configMapRef: name: app-settings</code> ✓</li>
161
+ <li>C) <code>volumes: - configMap: name: app-settings</code></li>
162
+ <li>D) <code>env: - configMapKeyRef: name: app-settings key: "*"</code></li>
163
+ </ul>
164
+ <p><em>Explanation: envFrom with configMapRef loads ALL keys from the ConfigMap as environment variables. env with valueFrom configMapKeyRef only loads ONE specific key. The wildcard "*" syntax does not exist.</em></p>
165
+
166
+ <p><strong>Q2:</strong> You create a Secret with the command: kubectl create secret generic mysecret --from-literal=password=secret123. How is the data stored in etcd?</p>
167
+ <ul>
168
+ <li>A) Plain text: "password=secret123"</li>
169
+ <li>B) AES-256 encrypted</li>
170
+ <li>C) Base64 encoded ✓</li>
171
+ <li>D) SHA-256 hashed</li>
172
+ </ul>
173
+ <p><em>Explanation: By default, Kubernetes stores Secret data as base64 encoded values in etcd — NOT encrypted. Base64 is encoding, not encryption. Anyone with etcd access can decode it. To encrypt at rest, an EncryptionConfiguration must be configured separately.</em></p>
174
+
175
+ <p><strong>Q3:</strong> A ConfigMap is updated with new values. A Pod is using this ConfigMap mounted as a volume at /etc/config. What happens?</p>
176
+ <ul>
177
+ <li>A) The Pod fails immediately because the config changed</li>
178
+ <li>B) The files in /etc/config are automatically updated (with a short delay) ✓</li>
179
+ <li>C) Nothing happens — the Pod must be restarted to see changes</li>
180
+ <li>D) The Pod is restarted automatically by Kubernetes</li>
181
+ </ul>
182
+ <p><em>Explanation: Volume-mounted ConfigMaps are automatically updated when the ConfigMap changes, after the kubelet sync period (typically ~1 minute). Environment variables from ConfigMaps do NOT auto-update — the Pod must be recreated. Applications that watch for file changes can react to these updates without restarts.</em></p>
@@ -0,0 +1,168 @@
1
+ ---
2
+ id: ckad-d4-l07
3
+ title: 'Bài 7: SecurityContext, Capabilities & ServiceAccounts'
4
+ slug: 07-securitycontext-pod-security
5
+ description: >-
6
+ SecurityContext cho Pod và Container: runAsUser, runAsNonRoot, readOnlyRootFilesystem,
7
+ Linux capabilities. ServiceAccount binding và automountServiceAccountToken.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 7
12
+ section_title: "Domain 4: Application Environment, Configuration and Security (25%)"
13
+ course:
14
+ id: lt-ckad-series-001
15
+ title: 'Luyện thi CKAD — Certified Kubernetes Application Developer'
16
+ slug: luyen-thi-ckad
17
+ ---
18
+
19
+ <img src="/storage/uploads/2026/04/k8s-cert-ckad-bai7-security-context.png" alt="SecurityContext — Pod-level vs Container-level, Linux capabilities" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="securitycontext">1. SecurityContext</h2>
22
+
23
+ <p>SecurityContext định nghĩa các privilege và access control settings cho Pod hoặc Container.</p>
24
+
25
+ <pre><code class="language-text">apiVersion: v1
26
+ kind: Pod
27
+ spec:
28
+ securityContext: # Pod-level: applies to ALL containers
29
+ runAsUser: 1000 # UID để chạy containers
30
+ runAsGroup: 3000 # GID primary group
31
+ fsGroup: 2000 # GID cho mounted volumes
32
+ runAsNonRoot: true # Reject containers that run as root
33
+
34
+ containers:
35
+ - name: app
36
+ image: myapp
37
+ securityContext: # Container-level: overrides pod-level
38
+ allowPrivilegeEscalation: false
39
+ readOnlyRootFilesystem: true # Filesystem là read-only
40
+ capabilities:
41
+ add: ["NET_BIND_SERVICE"] # Add capability
42
+ drop: ["ALL"] # Drop all, add only what needed</code></pre>
43
+
44
+ <table>
45
+ <thead><tr><th>Setting</th><th>Level</th><th>Tác dụng</th></tr></thead>
46
+ <tbody>
47
+ <tr><td><code>runAsUser</code></td><td>Pod/Container</td><td>Chạy process với UID cụ thể</td></tr>
48
+ <tr><td><code>runAsNonRoot</code></td><td>Pod/Container</td><td>Từ chối chạy nếu UID = 0 (root)</td></tr>
49
+ <tr><td><code>readOnlyRootFilesystem</code></td><td>Container</td><td>Mount root filesystem read-only</td></tr>
50
+ <tr><td><code>allowPrivilegeEscalation</code></td><td>Container</td><td>Chặn privilege escalation (sudo etc.)</td></tr>
51
+ <tr><td><code>privileged</code></td><td>Container</td><td>Run as privileged (như root trên host)</td></tr>
52
+ <tr><td><code>fsGroup</code></td><td>Pod</td><td>GID cho volume files (shared volume access)</td></tr>
53
+ </tbody>
54
+ </table>
55
+
56
+ <blockquote><p><strong>Exam tip:</strong> Container-level <code>securityContext</code> <strong>override</strong> Pod-level settings. Nếu Pod có <code>runAsUser: 1000</code> và container có <code>runAsUser: 2000</code>, container đó chạy với UID 2000. Hay bị test: verify user bằng <code>kubectl exec pod -- id</code> hoặc <code>whoami</code>.</p></blockquote>
57
+
58
+ <h2 id="capabilities">2. Linux Capabilities</h2>
59
+
60
+ <pre><code class="language-text">Capabilities cho phép grant specific privileges mà không cần full root.
61
+
62
+ # Ví dụ thường gặp:
63
+ NET_BIND_SERVICE — Bind to port < 1024 (e.g., port 80)
64
+ NET_ADMIN — Network administration (ifconfig etc.)
65
+ SYS_TIME — Modify system clock
66
+ CHOWN — Change file ownership
67
+ SETUID/SETGID — Change user/group ID
68
+
69
+ securityContext:
70
+ capabilities:
71
+ drop: ["ALL"] # Best practice: drop all first
72
+ add: ["NET_BIND_SERVICE"] # Then re-add only what's needed</code></pre>
73
+
74
+ <h2 id="serviceaccount">3. ServiceAccounts</h2>
75
+
76
+ <p>Pod dùng <strong>ServiceAccount</strong> để authenticate với Kubernetes API.</p>
77
+
78
+ <pre><code class="language-text"># Tạo ServiceAccount
79
+ kubectl create serviceaccount my-sa
80
+
81
+ # Bind vào Role
82
+ kubectl create rolebinding my-binding \
83
+ --role=pod-reader \
84
+ --serviceaccount=default:my-sa
85
+
86
+ # Assign SA cho Pod
87
+ spec:
88
+ serviceAccountName: my-sa # Use specific SA
89
+ automountServiceAccountToken: false # Don't auto-mount SA token
90
+
91
+ # Mặc định: default SA được mount tại /var/run/secrets/kubernetes.io/serviceaccount/
92
+ # Token file có thể gọi K8s API từ container</code></pre>
93
+
94
+ <table>
95
+ <thead><tr><th>Concept</th><th>Mô tả</th></tr></thead>
96
+ <tbody>
97
+ <tr><td>Default SA</td><td>Mỗi namespace có sẵn <code>default</code> SA (ít quyền)</td></tr>
98
+ <tr><td>Token mount</td><td>Token tự động mount vào pod nếu không tắt</td></tr>
99
+ <tr><td><code>automountServiceAccountToken: false</code></td><td>Tắt việc mount token (best security practice)</td></tr>
100
+ </tbody>
101
+ </table>
102
+
103
+ <blockquote><p><strong>Exam tip:</strong> Khi Pod cần gọi Kubernetes API (ví dụ: operator pattern), cần ServiceAccount có quyền phù hợp. Nếu Pod không cần gọi API, best practice là set <code>automountServiceAccountToken: false</code>. CKAD thường test: tạo SA, bind role, và set SA trong Pod spec.</p></blockquote>
104
+
105
+ <h2 id="readonly-volume">4. readOnlyRootFilesystem với emptyDir</h2>
106
+
107
+ <pre><code class="language-text"># Khi dùng readOnlyRootFilesystem: true, app KHÔNG ghi vào root FS.
108
+ # Nhưng app vẫn cần ghi temp files → dùng emptyDir volume:
109
+
110
+ spec:
111
+ containers:
112
+ - name: app
113
+ image: myapp
114
+ securityContext:
115
+ readOnlyRootFilesystem: true
116
+ volumeMounts:
117
+ - name: tmp
118
+ mountPath: /tmp # App ghi temp files vào đây
119
+ - name: cache
120
+ mountPath: /app/cache
121
+ volumes:
122
+ - name: tmp
123
+ emptyDir: {}
124
+ - name: cache
125
+ emptyDir: {}</code></pre>
126
+
127
+ <h2 id="cheatsheet">5. Cheat Sheet</h2>
128
+
129
+ <table>
130
+ <thead><tr><th>Task</th><th>YAML / Command</th></tr></thead>
131
+ <tbody>
132
+ <tr><td>Run container as non-root</td><td><code>securityContext: runAsNonRoot: true</code></td></tr>
133
+ <tr><td>Run với specific UID</td><td><code>securityContext: runAsUser: 1000</code></td></tr>
134
+ <tr><td>Read-only filesystem</td><td><code>securityContext: readOnlyRootFilesystem: true</code></td></tr>
135
+ <tr><td>Drop all capabilities</td><td><code>capabilities: drop: ["ALL"]</code></td></tr>
136
+ <tr><td>Gán ServiceAccount</td><td><code>spec: serviceAccountName: my-sa</code></td></tr>
137
+ <tr><td>Verify user trong container</td><td><code>kubectl exec pod -- whoami</code></td></tr>
138
+ </tbody>
139
+ </table>
140
+
141
+ <h2 id="practice">6. Practice Questions</h2>
142
+
143
+ <p><strong>Q1:</strong> A Pod spec has securityContext.runAsUser: 1000 at the Pod level. One container within the Pod has securityContext.runAsUser: 2000. What UID does that container run with?</p>
144
+ <ul>
145
+ <li>A) 0 (root, because Pod-level overrides)</li>
146
+ <li>B) 1000 (Pod-level takes priority)</li>
147
+ <li>C) 2000 (Container-level overrides Pod-level) ✓</li>
148
+ <li>D) Both UIDs simultaneously</li>
149
+ </ul>
150
+ <p><em>Explanation: Container-level securityContext settings override Pod-level settings. The container runs with UID 2000. Other containers in the same Pod without a container-level securityContext.runAsUser would inherit the Pod-level UID of 1000.</em></p>
151
+
152
+ <p><strong>Q2:</strong> An application container needs to bind to port 80 (a privileged port below 1024) but should NOT run as root. How do you configure this?</p>
153
+ <ul>
154
+ <li>A) Set securityContext.privileged: true</li>
155
+ <li>B) Set securityContext.runAsUser: 0</li>
156
+ <li>C) Add NET_BIND_SERVICE capability while dropping ALL others ✓</li>
157
+ <li>D) Use a NodePort Service instead of port 80</li>
158
+ </ul>
159
+ <p><em>Explanation: Linux capabilities allow granular privilege grants. NET_BIND_SERVICE allows binding to ports below 1024 without full root. Best practice is to drop ALL capabilities first, then add only what's needed: capabilities: { drop: ["ALL"], add: ["NET_BIND_SERVICE"] }.</em></p>
160
+
161
+ <p><strong>Q3:</strong> A Pod is running with readOnlyRootFilesystem: true, but the application tries to write to /tmp and fails. What is the best solution?</p>
162
+ <ul>
163
+ <li>A) Remove readOnlyRootFilesystem: true</li>
164
+ <li>B) Set securityContext.privileged: true</li>
165
+ <li>C) Mount an emptyDir volume at /tmp ✓</li>
166
+ <li>D) Use a ConfigMap mounted at /tmp</li>
167
+ </ul>
168
+ <p><em>Explanation: readOnlyRootFilesystem prevents writes to the container's filesystem, but emptyDir volumes are separate writable mounts. By mounting an emptyDir at /tmp, the application can write temp files there while the root filesystem remains read-only — maintaining the security benefit.</em></p>