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

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 +7 -7
  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 +7 -7
  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,146 @@
1
+ ---
2
+ id: ckad-d1-l01
3
+ title: 'Bài 1: Multi-container Pods & Init Containers'
4
+ slug: 01-multi-container-pods
5
+ description: >-
6
+ Multi-container Pod patterns: Sidecar, Ambassador, Adapter. Init Containers
7
+ cho prerequisites. Shared volumes giữa containers. CKAD hands-on tasks.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 1
12
+ section_title: "Domain 1: Application Design and Build (20%)"
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-bai1-multicontainer.png" alt="Multi-Container Pod Patterns — Sidecar, Ambassador, Adapter và Init Containers" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="multi-container">1. Multi-container Pod Patterns</h2>
22
+
23
+ <p>Containers trong cùng một Pod chia sẻ: network (same IP), IPC, và có thể chia sẻ storage volumes. Dùng nhiều containers khi chúng cần phối hợp chặt chẽ.</p>
24
+
25
+ <table>
26
+ <thead><tr><th>Pattern</th><th>Vai trò</th><th>Ví dụ thực tế</th></tr></thead>
27
+ <tbody>
28
+ <tr><td><strong>Sidecar</strong></td><td>Extend/enhance container chính (cùng lifecycle)</td><td>Log shipper, service mesh proxy (Envoy), config reloader</td></tr>
29
+ <tr><td><strong>Ambassador</strong></td><td>Proxy traffic đến/từ container chính</td><td>Local proxy cache, connection multiplexer</td></tr>
30
+ <tr><td><strong>Adapter</strong></td><td>Transform output của container chính</td><td>Metrics format converter (app → Prometheus format)</td></tr>
31
+ </tbody>
32
+ </table>
33
+
34
+ <pre><code class="language-text">Sidecar Pattern:
35
+ ┌─────────────────────────────────────────────┐
36
+ │ POD │
37
+ │ ┌──────────────┐ ┌─────────────────┐ │
38
+ │ │ App │ │ Log Sidecar │ │
39
+ │ │ Container │ │ (Fluentd) │ │
40
+ │ └──────┬───────┘ └────────┬────────┘ │
41
+ │ │ │ │
42
+ │ └──── Shared Volume ──┘ │
43
+ │ /var/log/app │
44
+ └─────────────────────────────────────────────┘</code></pre>
45
+
46
+ <h2 id="multi-container-yaml">2. Multi-container Pod YAML</h2>
47
+
48
+ <pre><code class="language-text">apiVersion: v1
49
+ kind: Pod
50
+ metadata:
51
+ name: web-with-sidecar
52
+ spec:
53
+ containers:
54
+ - name: web
55
+ image: nginx:1.21
56
+ volumeMounts:
57
+ - name: shared-logs
58
+ mountPath: /var/log/nginx
59
+
60
+ - name: log-shipper
61
+ image: fluent/fluentd:v1.14
62
+ volumeMounts:
63
+ - name: shared-logs
64
+ mountPath: /var/log/nginx
65
+ readOnly: true # Sidecar reads, doesn't write
66
+
67
+ volumes:
68
+ - name: shared-logs
69
+ emptyDir: {} # Ephemeral, lost when pod deleted</code></pre>
70
+
71
+ <blockquote><p><strong>Exam tip:</strong> CKAD thường cho task tạo Pod với sidecar container. Key điểm: cần shared volume để containers communicate, và cả 2 containers phải mount volume đúng path. Sidecar thường mount <code>readOnly: true</code>.</p></blockquote>
72
+
73
+ <h2 id="init-containers">3. Init Containers</h2>
74
+
75
+ <p><strong>Init Containers</strong> chạy trước main containers, phải hoàn thành thành công trước khi Pod start. Dùng cho: DB migration, wait for dependency, pre-populate volume.</p>
76
+
77
+ <pre><code class="language-text">apiVersion: v1
78
+ kind: Pod
79
+ metadata:
80
+ name: app-with-init
81
+ spec:
82
+ initContainers:
83
+ - name: wait-for-db
84
+ image: busybox
85
+ command: ['sh', '-c', 'until nc -z postgres-service 5432; do sleep 2; done']
86
+
87
+ - name: db-migrate
88
+ image: myapp:1.0
89
+ command: ['python', 'manage.py', 'migrate']
90
+
91
+ containers:
92
+ - name: app
93
+ image: myapp:1.0
94
+ ports:
95
+ - containerPort: 8000</code></pre>
96
+
97
+ <table>
98
+ <thead><tr><th>Property</th><th>Init Container</th><th>Regular Container</th></tr></thead>
99
+ <tbody>
100
+ <tr><td>Execution order</td><td>Sequential, all before app</td><td>Parallel start</td></tr>
101
+ <tr><td>Must complete?</td><td>Yes (exit 0)</td><td>Runs continuously</td></tr>
102
+ <tr><td>Liveness probe</td><td>Not supported</td><td>Supported</td></tr>
103
+ <tr><td>Resources</td><td>Counted separately</td><td>Normal requests/limits</td></tr>
104
+ </tbody>
105
+ </table>
106
+
107
+ <h2 id="cheatsheet">4. Cheat Sheet</h2>
108
+
109
+ <table>
110
+ <thead><tr><th>Câu hỏi exam</th><th>Đáp án</th></tr></thead>
111
+ <tbody>
112
+ <tr><td>Log collection từ app container?</td><td><strong>Sidecar</strong> với shared volume</td></tr>
113
+ <tr><td>Wait for service before starting?</td><td><strong>Init Container</strong></td></tr>
114
+ <tr><td>Run DB migration before app?</td><td><strong>Init Container</strong> với migration command</td></tr>
115
+ <tr><td>Shared storage giữa containers?</td><td><strong>emptyDir</strong> volume</td></tr>
116
+ </tbody>
117
+ </table>
118
+
119
+ <h2 id="practice">5. Practice Questions</h2>
120
+
121
+ <p><strong>Q1:</strong> You need to ensure a Pod's main application only starts after a config file is downloaded from an external URL. What is the best approach?</p>
122
+ <ul>
123
+ <li>A) Use a Sidecar container to download the file</li>
124
+ <li>B) Use an Init Container that runs wget and completes before the main container starts ✓</li>
125
+ <li>C) Use a DaemonSet to pre-populate config on all nodes</li>
126
+ <li>D) Mount a ConfigMap as the initial configuration</li>
127
+ </ul>
128
+ <p><em>Explanation: Init Containers run sequentially before main containers and must complete (exit 0). They're perfect for "prerequisites" like downloading config, waiting for services, or running migrations. Sidecar runs in parallel alongside the main container.</em></p>
129
+
130
+ <p><strong>Q2:</strong> Two containers in the same Pod need to share data. Container A writes to /tmp/data, Container B reads from /tmp/data. What should you configure?</p>
131
+ <ul>
132
+ <li>A) ExternalDNS shared volume</li>
133
+ <li>B) emptyDir volume mounted at /tmp/data in both containers ✓</li>
134
+ <li>C) A PersistentVolumeClaim for each container</li>
135
+ <li>D) ConfigMap mounted as a volume</li>
136
+ </ul>
137
+ <p><em>Explanation: emptyDir is created when a Pod is assigned to a Node, and deleted when the Pod is removed. It's perfect for sharing ephemeral data between containers in the same Pod. Both containers mount it at the same path.</em></p>
138
+
139
+ <p><strong>Q3:</strong> A Pod has a single Init Container that keeps failing (exit code 1). What happens to the main application container?</p>
140
+ <ul>
141
+ <li>A) The main container starts after a timeout</li>
142
+ <li>B) The main container is skipped and the Pod succeeds</li>
143
+ <li>C) The main container never starts; Pod shows Init:Error or Init:CrashLoopBackOff ✓</li>
144
+ <li>D) The init container failure is ignored if main container is defined</li>
145
+ </ul>
146
+ <p><em>Explanation: Init Containers MUST exit with code 0. If they fail, Kubernetes restarts them based on Pod's restartPolicy. The main container never starts until all init containers complete successfully.</em></p>
@@ -0,0 +1,174 @@
1
+ ---
2
+ id: ckad-d1-l02
3
+ title: 'Bài 2: Jobs, CronJobs & Resource Management'
4
+ slug: 02-jobs-cronjobs-resources
5
+ description: >-
6
+ Jobs (batch tasks), CronJobs (scheduled tasks). Resource requests và limits,
7
+ LimitRange, ResourceQuota. QoS classes cho CKAD exam.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 2
12
+ section_title: "Domain 1: Application Design and Build (20%)"
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-bai2-jobs.png" alt="Jobs và CronJobs — completions, parallelism, concurrencyPolicy" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="jobs">1. Jobs</h2>
22
+
23
+ <p>Một <strong>Job</strong> tạo một hoặc nhiều Pods và đảm bảo chúng hoàn thành thành công. Khi Job hoàn thành, Pods không bị xóa (cho log inspection).</p>
24
+
25
+ <pre><code class="language-text">apiVersion: batch/v1
26
+ kind: Job
27
+ metadata:
28
+ name: data-processor
29
+ spec:
30
+ completions: 3 # Run 3 successful completions
31
+ parallelism: 2 # Run 2 pods at a time
32
+ backoffLimit: 4 # Retry up to 4 times on failure
33
+ template:
34
+ spec:
35
+ restartPolicy: Never # OnFailure or Never (required for Job)
36
+ containers:
37
+ - name: processor
38
+ image: busybox
39
+ command: ['sh', '-c', 'echo Processing; sleep 5']</code></pre>
40
+
41
+ <table>
42
+ <thead><tr><th>Field</th><th>Ý nghĩa</th><th>Default</th></tr></thead>
43
+ <tbody>
44
+ <tr><td><code>completions</code></td><td>Số lần phải hoàn thành</td><td>1</td></tr>
45
+ <tr><td><code>parallelism</code></td><td>Số Pods chạy concurrent</td><td>1</td></tr>
46
+ <tr><td><code>backoffLimit</code></td><td>Số lần retry khi fail</td><td>6</td></tr>
47
+ <tr><td><code>activeDeadlineSeconds</code></td><td>Timeout tổng thể của Job</td><td>Unlimited</td></tr>
48
+ </tbody>
49
+ </table>
50
+
51
+ <blockquote><p><strong>Exam tip:</strong> Job Pods phải có <code>restartPolicy: Never</code> hoặc <code>OnFailure</code>. Không thể dùng <code>Always</code> (default cho regular Pods). CKAD hay test việc tạo Job và kiểm tra completion status.</p></blockquote>
52
+
53
+ <h2 id="cronjobs">2. CronJobs</h2>
54
+
55
+ <pre><code class="language-text">apiVersion: batch/v1
56
+ kind: CronJob
57
+ metadata:
58
+ name: nightly-backup
59
+ spec:
60
+ schedule: "0 2 * * *" # Cron syntax: minute hour day month weekday
61
+ concurrencyPolicy: Forbid # Allow | Forbid | Replace
62
+ successfulJobsHistoryLimit: 3
63
+ failedJobsHistoryLimit: 1
64
+ jobTemplate:
65
+ spec:
66
+ template:
67
+ spec:
68
+ restartPolicy: OnFailure
69
+ containers:
70
+ - name: backup
71
+ image: backup-tool:1.0
72
+ command: ['./backup.sh']</code></pre>
73
+
74
+ <table>
75
+ <thead><tr><th>concurrencyPolicy</th><th>Hành vi</th></tr></thead>
76
+ <tbody>
77
+ <tr><td><strong>Allow</strong></td><td>Cho phép Jobs chạy concurrent (default)</td></tr>
78
+ <tr><td><strong>Forbid</strong></td><td>Skip new Job nếu previous chưa xong</td></tr>
79
+ <tr><td><strong>Replace</strong></td><td>Cancel previous Job, start new one</td></tr>
80
+ </tbody>
81
+ </table>
82
+
83
+ <h2 id="resources">3. Resource Requests & Limits</h2>
84
+
85
+ <pre><code class="language-text">spec:
86
+ containers:
87
+ - name: app
88
+ image: myapp
89
+ resources:
90
+ requests:
91
+ cpu: "250m" # 0.25 CPU core (minimum guaranteed)
92
+ memory: "128Mi" # 128 MiB minimum
93
+ limits:
94
+ cpu: "500m" # Max 0.5 CPU core
95
+ memory: "256Mi" # Max 256 MiB (OOM if exceeded)</code></pre>
96
+
97
+ <pre><code class="language-text">QoS Classes (dựa trên requests/limits):
98
+
99
+ Guaranteed: requests == limits (both CPU and memory)
100
+ → Last to be evicted under pressure
101
+
102
+ Burstable: requests < limits (or only one set)
103
+ → Middle priority for eviction
104
+
105
+ BestEffort: NO requests, NO limits
106
+ → First to be evicted under pressure</code></pre>
107
+
108
+ <blockquote><p><strong>Exam tip:</strong> Để Pod có QoS class <strong>Guaranteed</strong>: phải set cả <code>cpu</code> và <code>memory</code> trong cả <code>requests</code> và <code>limits</code>, và chúng phải bằng nhau. Mỗi container trong Pod đều phải thỏa mãn điều kiện này.</p></blockquote>
109
+
110
+ <h2 id="limitrange">4. LimitRange & ResourceQuota</h2>
111
+
112
+ <table>
113
+ <thead><tr><th>Object</th><th>Scope</th><th>Mục đích</th></tr></thead>
114
+ <tbody>
115
+ <tr><td><strong>LimitRange</strong></td><td>Namespace</td><td>Set default requests/limits cho Pods/Containers trong namespace</td></tr>
116
+ <tr><td><strong>ResourceQuota</strong></td><td>Namespace</td><td>Giới hạn tổng resources namespace được dùng</td></tr>
117
+ </tbody>
118
+ </table>
119
+
120
+ <pre><code class="language-text">ResourceQuota example:
121
+ apiVersion: v1
122
+ kind: ResourceQuota
123
+ metadata:
124
+ name: dev-quota
125
+ namespace: development
126
+ spec:
127
+ hard:
128
+ requests.cpu: "4"
129
+ requests.memory: "8Gi"
130
+ limits.cpu: "8"
131
+ limits.memory: "16Gi"
132
+ pods: "20"</code></pre>
133
+
134
+ <h2 id="cheatsheet">5. Cheat Sheet</h2>
135
+
136
+ <table>
137
+ <thead><tr><th>Câu hỏi exam</th><th>Đáp án</th></tr></thead>
138
+ <tbody>
139
+ <tr><td>Job cần restartPolicy gì?</td><td><code>Never</code> hoặc <code>OnFailure</code></td></tr>
140
+ <tr><td>CronJob mỗi 5 phút?</td><td><code>*/5 * * * *</code></td></tr>
141
+ <tr><td>Container bị OOM Kill do gì?</td><td>Vượt <code>limits.memory</code></td></tr>
142
+ <tr><td>QoS Guaranteed cần gì?</td><td>requests == limits (cả CPU và Memory)</td></tr>
143
+ <tr><td>Giới hạn resources của namespace?</td><td><strong>ResourceQuota</strong></td></tr>
144
+ </tbody>
145
+ </table>
146
+
147
+ <h2 id="practice">6. Practice Questions</h2>
148
+
149
+ <p><strong>Q1:</strong> A Job is configured with completions: 5 and parallelism: 2. How does it execute?</p>
150
+ <ul>
151
+ <li>A) Creates 5 Pods simultaneously until all complete</li>
152
+ <li>B) Runs 2 Pods at a time, creating new ones as old ones complete, until 5 total completions ✓</li>
153
+ <li>C) Runs 5 Pods sequentially one by one</li>
154
+ <li>D) Creates 2 Pods, each completing 2.5 times</li>
155
+ </ul>
156
+ <p><em>Explanation: completions=5 means 5 PODs must exit successfully. parallelism=2 means at most 2 run at once. As each Pod completes, a new one starts until completion count is reached. Total Pods created could be more if some fail.</em></p>
157
+
158
+ <p><strong>Q2:</strong> A Pod has no resource requests or limits set. What QoS class is it assigned and how does this affect eviction?</p>
159
+ <ul>
160
+ <li>A) Guaranteed — it will be last to be evicted</li>
161
+ <li>B) Burstable — it has medium eviction priority</li>
162
+ <li>C) BestEffort — it will be first to be evicted under resource pressure ✓</li>
163
+ <li>D) NoQoS — it has no eviction priority</li>
164
+ </ul>
165
+ <p><em>Explanation: Pods with no resource requests or limits get BestEffort QoS class. When nodes face resource pressure, Kubernetes evicts BestEffort Pods first to free resources for higher-priority workloads.</em></p>
166
+
167
+ <p><strong>Q3:</strong> A CronJob is scheduled every hour. A previous job is still running when the next scheduled time arrives. With concurrencyPolicy: Forbid, what happens?</p>
168
+ <ul>
169
+ <li>A) The running job is cancelled; the new one starts</li>
170
+ <li>B) Both jobs run concurrently</li>
171
+ <li>C) The new job is skipped; the running job continues ✓</li>
172
+ <li>D) The CronJob is suspended until the running job completes</li>
173
+ </ul>
174
+ <p><em>Explanation: Forbid policy prevents a new job from starting if the previous job is still running. The scheduled run is skipped. Use Allow to permit concurrent runs or Replace to cancel the old and start the new one.</em></p>
@@ -0,0 +1,148 @@
1
+ ---
2
+ id: ckad-d2-l03
3
+ title: 'Bài 3: Rolling Updates, Rollbacks & Deployment Strategies'
4
+ slug: 03-rolling-updates-rollbacks
5
+ description: >-
6
+ Deployment strategies: RollingUpdate vs Recreate. Kubectl rollout commands,
7
+ maxUnavailable/maxSurge. Revision history và rollback kỹ thuật cho CKAD.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 3
12
+ section_title: "Domain 2: Application Deployment (20%)"
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-bai3-rolling-update.png" alt="Rolling Update và Rollback — maxUnavailable, maxSurge, ReplicaSet history" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="strategies">1. Deployment Strategies</h2>
22
+
23
+ <table>
24
+ <thead><tr><th>Strategy</th><th>Cách hoạt động</th><th>Downtime?</th><th>Khi dùng</th></tr></thead>
25
+ <tbody>
26
+ <tr><td><strong>RollingUpdate</strong></td><td>Replace pods dần dần, maintain availability</td><td>Không</td><td>Default, production</td></tr>
27
+ <tr><td><strong>Recreate</strong></td><td>Kill tất cả pods cũ, tạo mới</td><td>Có</td><td>Dev/test, breaking changes</td></tr>
28
+ </tbody>
29
+ </table>
30
+
31
+ <pre><code class="language-text">spec:
32
+ strategy:
33
+ type: RollingUpdate
34
+ rollingUpdate:
35
+ maxUnavailable: 1 # OR "25%" — Max pods unavailable during update
36
+ maxSurge: 1 # OR "25%" — Max extra pods above desired count
37
+
38
+ ┌─────────────────────────────────────────────────┐
39
+ │ Desired: 4 pods │
40
+ │ │
41
+ │ maxUnavailable: 1 → min 3 pods must be running │
42
+ │ maxSurge: 1 → max 5 pods total at once │
43
+ │ │
44
+ │ Step 1: Create 1 new pod (5 total = desired+surge)│
45
+ │ Step 2: Terminate 1 old pod (4 total) │
46
+ │ Step 3: Repeat until all replaced │
47
+ └─────────────────────────────────────────────────┘</code></pre>
48
+
49
+ <blockquote><p><strong>Exam tip:</strong> <code>maxUnavailable</code> và <code>maxSurge</code> KHÔNG thể cùng lúc là 0. Nếu cần zero-downtime update: set <code>maxUnavailable: 0</code> và <code>maxSurge: 1</code> (hoặc cao hơn).</p></blockquote>
50
+
51
+ <h2 id="rollout">2. kubectl rollout Commands</h2>
52
+
53
+ <pre><code class="language-text"># Xem trạng thái rollout
54
+ kubectl rollout status deployment/myapp
55
+
56
+ # Xem revision history
57
+ kubectl rollout history deployment/myapp
58
+ kubectl rollout history deployment/myapp --revision=2
59
+
60
+ # Rollback về version trước
61
+ kubectl rollout undo deployment/myapp
62
+
63
+ # Rollback về revision cụ thể
64
+ kubectl rollout undo deployment/myapp --to-revision=2
65
+
66
+ # Tạm dừng rollout
67
+ kubectl rollout pause deployment/myapp
68
+
69
+ # Resume rollout
70
+ kubectl rollout resume deployment/myapp</code></pre>
71
+
72
+ <table>
73
+ <thead><tr><th>Command</th><th>Tác dụng</th></tr></thead>
74
+ <tbody>
75
+ <tr><td><code>rollout status</code></td><td>Wait/show current rollout progress</td></tr>
76
+ <tr><td><code>rollout history</code></td><td>List revision history</td></tr>
77
+ <tr><td><code>rollout undo</code></td><td>Rollback to previous (or specific) revision</td></tr>
78
+ <tr><td><code>rollout pause/resume</code></td><td>Pause để canary test, rồi resume</td></tr>
79
+ <tr><td><code>rollout restart</code></td><td>Force restart tất cả pods (rolling)</td></tr>
80
+ </tbody>
81
+ </table>
82
+
83
+ <blockquote><p><strong>Exam tip:</strong> Để lưu <code>CHANGE-CAUSE</code> trong revision history, thêm annotation: <code>kubectl annotate deployment/myapp kubernetes.io/change-cause="Updated image to v2"</code> TRƯỚC khi update. Hoặc dùng <code>--record</code> flag (deprecated nhưng vẫn hoạt động trong exam).</p></blockquote>
84
+
85
+ <h2 id="trigger">3. Trigger & Monitor Update</h2>
86
+
87
+ <pre><code class="language-text"># Update image (trigger rolling update)
88
+ kubectl set image deployment/myapp container-name=nginx:1.25
89
+
90
+ # Xem ReplicaSet history (mỗi update tạo mới 1 RS)
91
+ kubectl get rs
92
+ # NAME DESIRED CURRENT READY
93
+ # myapp-7d9b8c 4 4 4 ← current
94
+ # myapp-6f5a2b 0 0 0 ← old (kept for rollback)
95
+
96
+ # Scale deployment
97
+ kubectl scale deployment/myapp --replicas=6
98
+
99
+ # Edit deployment trực tiếp
100
+ kubectl edit deployment/myapp</code></pre>
101
+
102
+ <h2 id="revisionhistory">4. Revision History Limit</h2>
103
+
104
+ <pre><code class="language-text">spec:
105
+ revisionHistoryLimit: 10 # Default: 10 old RS kept for rollback
106
+ # Set to 0 to disable rollback capability</code></pre>
107
+
108
+ <h2 id="cheatsheet">5. Cheat Sheet</h2>
109
+
110
+ <table>
111
+ <thead><tr><th>Tình huống exam</th><th>Command</th></tr></thead>
112
+ <tbody>
113
+ <tr><td>Update image</td><td><code>kubectl set image deploy/app c=image:v2</code></td></tr>
114
+ <tr><td>Check rollout</td><td><code>kubectl rollout status deploy/app</code></td></tr>
115
+ <tr><td>Rollback nhanh</td><td><code>kubectl rollout undo deploy/app</code></td></tr>
116
+ <tr><td>Rollback về rev 3</td><td><code>kubectl rollout undo deploy/app --to-revision=3</code></td></tr>
117
+ <tr><td>Zero-downtime config</td><td><code>maxUnavailable: 0, maxSurge: 1</code></td></tr>
118
+ </tbody>
119
+ </table>
120
+
121
+ <h2 id="practice">6. Practice Questions</h2>
122
+
123
+ <p><strong>Q1:</strong> A Deployment with 10 replicas is configured with maxUnavailable: 2 and maxSurge: 3. During a rolling update, what is the maximum number of pods that can exist at any given time?</p>
124
+ <ul>
125
+ <li>A) 10</li>
126
+ <li>B) 12</li>
127
+ <li>C) 13 ✓</li>
128
+ <li>D) 15</li>
129
+ </ul>
130
+ <p><em>Explanation: maxSurge=3 means up to 3 extra pods above the desired count (10) can exist simultaneously. So maximum = 10 + 3 = 13 pods. Meanwhile, maxUnavailable=2 means at least 8 pods must be available.</em></p>
131
+
132
+ <p><strong>Q2:</strong> You updated a Deployment and then realized the new version has a bug. Which command quickly reverts to the previous working version?</p>
133
+ <ul>
134
+ <li>A) <code>kubectl delete deployment myapp && kubectl apply -f old.yaml</code></li>
135
+ <li>B) <code>kubectl rollout undo deployment/myapp</code> ✓</li>
136
+ <li>C) <code>kubectl rollout history deployment/myapp</code></li>
137
+ <li>D) <code>kubectl set image deployment/myapp container=old-image</code></li>
138
+ </ul>
139
+ <p><em>Explanation: rollout undo is the fastest way to revert to the previous revision. It creates a new rolling update back to the previous ReplicaSet. Option D also works but requires knowing the exact old image name.</em></p>
140
+
141
+ <p><strong>Q3:</strong> A Deployment uses Recreate strategy. What is the expected behavior during an update?</p>
142
+ <ul>
143
+ <li>A) Pods are replaced one at a time with no downtime</li>
144
+ <li>B) All existing pods are terminated before new pods are created, causing downtime ✓</li>
145
+ <li>C) Half the pods are updated at once while the other half serve traffic</li>
146
+ <li>D) New pods are created first, then old pods are terminated</li>
147
+ </ul>
148
+ <p><em>Explanation: Recreate strategy terminates ALL existing pods at once (scale to 0), then creates the new pods. This causes downtime but ensures no two versions run simultaneously — suitable when old and new versions cannot coexist.</em></p>
@@ -0,0 +1,181 @@
1
+ ---
2
+ id: ckad-d2-l04
3
+ title: 'Bài 4: Helm & Kustomize'
4
+ slug: 04-helm-kustomize
5
+ description: >-
6
+ Helm charts, releases, values.yaml và upgrade/rollback workflow. Kustomize
7
+ overlays và bases. Phân biệt khi nào dùng Helm vs Kustomize cho CKAD.
8
+ duration_minutes: 50
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 4
12
+ section_title: "Domain 2: Application Deployment (20%)"
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-bai4-helm-kustomize.png" alt="Helm vs Kustomize — Chart structure, template engine, overlays" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="helm-concepts">1. Helm Core Concepts</h2>
22
+
23
+ <p><strong>Helm</strong> là Kubernetes package manager. Nó đóng gói các Kubernetes manifests vào <strong>Charts</strong> và quản lý deployments dưới dạng <strong>Releases</strong>.</p>
24
+
25
+ <pre><code class="language-text">Helm Architecture:
26
+
27
+ values.yaml Chart templates
28
+ │ │
29
+ ▼ ▼
30
+ ┌──────────────────────────────┐
31
+ │ Helm Template Engine │
32
+ │ Renders YAML manifests │
33
+ └──────────────┬───────────────┘
34
+
35
+ ▼ kubectl apply
36
+ Kubernetes Cluster
37
+ (stored as Release)</code></pre>
38
+
39
+ <table>
40
+ <thead><tr><th>Term</th><th>Định nghĩa</th></tr></thead>
41
+ <tbody>
42
+ <tr><td><strong>Chart</strong></td><td>Package của Helm — bao gồm templates + default values</td></tr>
43
+ <tr><td><strong>Release</strong></td><td>Instance của Chart đã được deploy lên cluster</td></tr>
44
+ <tr><td><strong>Repository</strong></td><td>Nơi lưu trữ Charts (như artifact hub, bitnami)</td></tr>
45
+ <tr><td><strong>Values</strong></td><td>Configuration parameters để customize Chart</td></tr>
46
+ <tr><td><strong>Revision</strong></td><td>Mỗi install/upgrade tạo ra một revision mới</td></tr>
47
+ </tbody>
48
+ </table>
49
+
50
+ <h2 id="helm-commands">2. Helm Commands</h2>
51
+
52
+ <pre><code class="language-text"># Add repository
53
+ helm repo add bitnami https://charts.bitnami.com/bitnami
54
+ helm repo update
55
+
56
+ # Search charts
57
+ helm search repo bitnami/nginx
58
+ helm search hub wordpress
59
+
60
+ # Install chart
61
+ helm install my-release bitnami/nginx
62
+ helm install my-release bitnami/nginx --values custom-values.yaml
63
+ helm install my-release bitnami/nginx --set image.tag=1.25
64
+
65
+ # List releases
66
+ helm list
67
+ helm list -n production
68
+
69
+ # Upgrade release
70
+ helm upgrade my-release bitnami/nginx --set replicaCount=3
71
+
72
+ # Rollback to previous revision
73
+ helm rollback my-release 1 # rollback to revision 1
74
+ helm rollback my-release # rollback to previous revision
75
+
76
+ # Uninstall
77
+ helm uninstall my-release
78
+
79
+ # View rendered templates (dry-run)
80
+ helm template my-release bitnami/nginx
81
+ helm install my-release bitnami/nginx --dry-run</code></pre>
82
+
83
+ <blockquote><p><strong>Exam tip:</strong> CKAD thường test <code>helm install</code> với flag <code>--set</code> (override values trực tiếp) và <code>--values file.yaml</code> (override từ file). Cũng test <code>helm upgrade</code> và <code>helm rollback</code>. Nhớ rằng <code>--set</code> override trumps <code>--values</code> file.</p></blockquote>
84
+
85
+ <h2 id="kustomize">3. Kustomize</h2>
86
+
87
+ <p><strong>Kustomize</strong> là tool built vào kubectl cho phép customize Kubernetes manifests mà không cần templates hoặc parameters. Dùng overlay pattern.</p>
88
+
89
+ <pre><code class="language-text">Kustomize Structure:
90
+ base/
91
+ ├── kustomization.yaml # Base kustomization
92
+ ├── deployment.yaml
93
+ └── service.yaml
94
+
95
+ overlays/
96
+ ├── development/
97
+ │ ├── kustomization.yaml # Patches for dev
98
+ │ └── replica-patch.yaml
99
+ └── production/
100
+ ├── kustomization.yaml # Patches for prod
101
+ └── replica-patch.yaml</code></pre>
102
+
103
+ <pre><code class="language-text"># base/kustomization.yaml
104
+ apiVersion: kustomize.config.k8s.io/v1beta1
105
+ kind: Kustomization
106
+ resources:
107
+ - deployment.yaml
108
+ - service.yaml
109
+
110
+ # overlays/production/kustomization.yaml
111
+ apiVersion: kustomize.config.k8s.io/v1beta1
112
+ kind: Kustomization
113
+ bases:
114
+ - ../../base
115
+ patches:
116
+ - path: replica-patch.yaml
117
+ images:
118
+ - name: myapp
119
+ newTag: "2.0"</code></pre>
120
+
121
+ <pre><code class="language-text"># Apply với kustomize
122
+ kubectl apply -k overlays/production/
123
+
124
+ # Preview rendered output
125
+ kubectl kustomize overlays/production/</code></pre>
126
+
127
+ <h2 id="comparison">4. Helm vs Kustomize</h2>
128
+
129
+ <table>
130
+ <thead><tr><th>Tiêu chí</th><th>Helm</th><th>Kustomize</th></tr></thead>
131
+ <tbody>
132
+ <tr><td>Approach</td><td>Template-based (Go templates)</td><td>Overlay/patching (plain YAML)</td></tr>
133
+ <tr><td>Learning curve</td><td>Cao hơn (template syntax)</td><td>Thấp hơn (YAML patches)</td></tr>
134
+ <tr><td>Package mgmt</td><td>Có (charts, repos, versioning)</td><td>Không</td></tr>
135
+ <tr><td>Release history</td><td>Có (upgrade/rollback)</td><td>Không built-in</td></tr>
136
+ <tr><td>Built into kubectl</td><td>Không (separate binary)</td><td>Có (<code>kubectl apply -k</code>)</td></tr>
137
+ <tr><td>Best for</td><td>Phân phối (distribute) apps</td><td>Env-specific customization</td></tr>
138
+ </tbody>
139
+ </table>
140
+
141
+ <h2 id="cheatsheet">5. Cheat Sheet</h2>
142
+
143
+ <table>
144
+ <thead><tr><th>Task</th><th>Command</th></tr></thead>
145
+ <tbody>
146
+ <tr><td>Install chart với custom values</td><td><code>helm install rel chart --values f.yaml</code></td></tr>
147
+ <tr><td>Override một value</td><td><code>helm install rel chart --set key=val</code></td></tr>
148
+ <tr><td>Rollback Helm release</td><td><code>helm rollback release-name 2</code></td></tr>
149
+ <tr><td>Apply kustomize overlay</td><td><code>kubectl apply -k overlays/prod/</code></td></tr>
150
+ <tr><td>Preview kustomize output</td><td><code>kubectl kustomize overlays/prod/</code></td></tr>
151
+ </tbody>
152
+ </table>
153
+
154
+ <h2 id="practice">6. Practice Questions</h2>
155
+
156
+ <p><strong>Q1:</strong> You need to deploy a Helm chart from the "stable" repo with a custom replica count of 5. Which command accomplishes this?</p>
157
+ <ul>
158
+ <li>A) <code>helm deploy myapp stable/nginx --replicas=5</code></li>
159
+ <li>B) <code>helm install myapp stable/nginx --set replicaCount=5</code> ✓</li>
160
+ <li>C) <code>helm install myapp stable/nginx -e replicaCount=5</code></li>
161
+ <li>D) <code>helm apply myapp stable/nginx --values replicaCount=5</code></li>
162
+ </ul>
163
+ <p><em>Explanation: helm install uses --set flag to override values. The syntax is --set key=value. The exact key name (replicaCount) depends on the chart's values.yaml, but --set is the correct flag for inline value overrides.</em></p>
164
+
165
+ <p><strong>Q2:</strong> A team uses Kustomize with a base configuration and production/staging overlays. Which command applies the production overlay?</p>
166
+ <ul>
167
+ <li>A) <code>kubectl apply -f overlays/production/</code></li>
168
+ <li>B) <code>kubectl kustomize overlays/production/ | kubectl apply -f -</code></li>
169
+ <li>C) <code>kubectl apply -k overlays/production/</code> ✓</li>
170
+ <li>D) <code>kustomize apply overlays/production/</code></li>
171
+ </ul>
172
+ <p><em>Explanation: kubectl apply -k (note -k not -f) is the built-in way to apply a kustomization directory. Option B also works but is more verbose. The -k flag tells kubectl to process the directory as a Kustomize configuration.</em></p>
173
+
174
+ <p><strong>Q3:</strong> After a Helm upgrade introduces a bug, you need to revert to the previous working state. What is the correct approach?</p>
175
+ <ul>
176
+ <li>A) kubectl rollout undo deployment/myapp</li>
177
+ <li>B) helm install --replace myapp stable/nginx</li>
178
+ <li>C) helm rollback myapp ✓</li>
179
+ <li>D) helm upgrade myapp --version=previous</li>
180
+ </ul>
181
+ <p><em>Explanation: helm rollback reverts a release to a previous revision. Without specifying a revision number, it rolls back to the previous one. This undoes all the changes made by the failed upgrade, including ConfigMaps, Secrets, and other resources managed by the chart.</em></p>