@xdev-asia/xdev-knowledge-mcp 1.0.52 → 1.0.54
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.
- package/content/blog/ai/con-duong-tro-thanh-ai-solution-architect.md +826 -0
- package/content/pages/ve-toi.md +62 -0
- package/data/quizzes/cka.json +319 -0
- package/data/quizzes/ckad.json +318 -0
- package/data/quizzes/gcp-ml-engineer.json +608 -100
- package/data/quizzes/kcna.json +317 -0
- package/data/quizzes.json +49 -4
- package/package.json +1 -1
- package/content/pages/gioi-thieu.md +0 -23
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ckad",
|
|
3
|
+
"title": "CKAD — Certified Kubernetes Application Developer",
|
|
4
|
+
"slug": "ckad",
|
|
5
|
+
"description": "Practice exam for CKAD — 20 questions covering all 5 domains",
|
|
6
|
+
"icon": "award",
|
|
7
|
+
"provider": "CNCF",
|
|
8
|
+
"level": "Professional",
|
|
9
|
+
"duration_minutes": 45,
|
|
10
|
+
"passing_score": 66,
|
|
11
|
+
"questions_count": 20,
|
|
12
|
+
"tags": ["Kubernetes", "CKAD", "CNCF", "DevOps", "Linux Foundation"],
|
|
13
|
+
"series_slug": "luyen-thi-ckad",
|
|
14
|
+
"domains": [
|
|
15
|
+
{
|
|
16
|
+
"name": "Domain 1: Application Design and Build",
|
|
17
|
+
"weight": 20,
|
|
18
|
+
"lessons": [
|
|
19
|
+
{ "title": "Bài 1: Container Images & Multi-stage Builds", "slug": "01-container-images-multi-stage" },
|
|
20
|
+
{ "title": "Bài 2: Pod Design — Labels, Selectors, Annotations", "slug": "02-pod-design-labels-selectors" }
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "Domain 2: Application Deployment",
|
|
25
|
+
"weight": 20,
|
|
26
|
+
"lessons": [
|
|
27
|
+
{ "title": "Bài 3: Deployments, Rolling Updates & Rollbacks", "slug": "03-deployments-rolling-updates" },
|
|
28
|
+
{ "title": "Bài 4: Helm Basics — Charts, Releases, Repositories", "slug": "04-helm-basics" }
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "Domain 3: Application Observability and Maintenance",
|
|
33
|
+
"weight": 15,
|
|
34
|
+
"lessons": [
|
|
35
|
+
{ "title": "Bài 5: Probes — Liveness, Readiness, Startup", "slug": "05-probes-liveness-readiness" },
|
|
36
|
+
{ "title": "Bài 6: Logging, Monitoring & Debugging", "slug": "06-logging-monitoring-debugging" }
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "Domain 4: Application Environment, Configuration and Security",
|
|
41
|
+
"weight": 25,
|
|
42
|
+
"lessons": [
|
|
43
|
+
{ "title": "Bài 7: ConfigMaps & Secrets", "slug": "07-configmaps-secrets" },
|
|
44
|
+
{ "title": "Bài 8: ServiceAccounts & Security Contexts", "slug": "08-serviceaccounts-security" },
|
|
45
|
+
{ "title": "Bài 9: Resource Requests, Limits & LimitRanges", "slug": "09-resource-requests-limits" }
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "Domain 5: Services and Networking",
|
|
50
|
+
"weight": 20,
|
|
51
|
+
"lessons": [
|
|
52
|
+
{ "title": "Bài 10: Services, Ingress & Network Policies", "slug": "10-services-ingress-networkpolicies" }
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"questions": [
|
|
57
|
+
{
|
|
58
|
+
"id": 1,
|
|
59
|
+
"domain": "Domain 1: Application Design and Build",
|
|
60
|
+
"question": "Which Dockerfile instruction is used to set the command that runs when the container starts, and CAN be overridden by the user at runtime?",
|
|
61
|
+
"options": [
|
|
62
|
+
"ENTRYPOINT",
|
|
63
|
+
"CMD",
|
|
64
|
+
"RUN",
|
|
65
|
+
"EXPOSE"
|
|
66
|
+
],
|
|
67
|
+
"correct": 1,
|
|
68
|
+
"explanation": "CMD sets the default command for the container, which can be overridden by passing arguments to docker run or in the Kubernetes pod spec's command/args fields. ENTRYPOINT sets the main executable and is harder to override."
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": 2,
|
|
72
|
+
"domain": "Domain 1: Application Design and Build",
|
|
73
|
+
"question": "What is the benefit of a multi-stage Docker build?",
|
|
74
|
+
"options": [
|
|
75
|
+
"It allows running multiple containers in a single pod",
|
|
76
|
+
"It reduces the final image size by separating build-time dependencies from runtime",
|
|
77
|
+
"It enables horizontal pod autoscaling",
|
|
78
|
+
"It automatically creates Kubernetes manifests"
|
|
79
|
+
],
|
|
80
|
+
"correct": 1,
|
|
81
|
+
"explanation": "Multi-stage builds use multiple FROM instructions. Build tools and dependencies stay in earlier stages while only the compiled artifact is copied to the final, minimal runtime image — significantly reducing image size."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": 3,
|
|
85
|
+
"domain": "Domain 1: Application Design and Build",
|
|
86
|
+
"question": "You want to select all pods with label 'app=web' AND 'tier=frontend'. Which label selector syntax is correct?",
|
|
87
|
+
"options": [
|
|
88
|
+
"app=web || tier=frontend",
|
|
89
|
+
"app=web,tier=frontend",
|
|
90
|
+
"app=web AND tier=frontend",
|
|
91
|
+
"app=web;tier=frontend"
|
|
92
|
+
],
|
|
93
|
+
"correct": 1,
|
|
94
|
+
"explanation": "In Kubernetes, multiple label selectors are comma-separated. 'app=web,tier=frontend' selects pods that have BOTH labels. This is used in kubectl: 'kubectl get pods -l app=web,tier=frontend'."
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": 4,
|
|
98
|
+
"domain": "Domain 1: Application Design and Build",
|
|
99
|
+
"question": "How do you create a CronJob that runs every day at 3:00 AM?",
|
|
100
|
+
"options": [
|
|
101
|
+
"schedule: '3 0 * * *'",
|
|
102
|
+
"schedule: '0 3 * * *'",
|
|
103
|
+
"schedule: '* * 3 * *'",
|
|
104
|
+
"schedule: 'daily 3:00'"
|
|
105
|
+
],
|
|
106
|
+
"correct": 1,
|
|
107
|
+
"explanation": "Cron format is: minute hour day-of-month month day-of-week. '0 3 * * *' means at minute 0, hour 3 (3:00 AM), every day of month, every month, every day of week."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": 5,
|
|
111
|
+
"domain": "Domain 2: Application Deployment",
|
|
112
|
+
"question": "A Deployment with 4 replicas uses the RollingUpdate strategy with maxSurge=1 and maxUnavailable=0. How many pods exist during an update?",
|
|
113
|
+
"options": [
|
|
114
|
+
"Exactly 4 pods at all times",
|
|
115
|
+
"Up to 5 pods (4 desired + 1 surge)",
|
|
116
|
+
"Between 3 and 5 pods",
|
|
117
|
+
"Up to 8 pods (doubled)"
|
|
118
|
+
],
|
|
119
|
+
"correct": 1,
|
|
120
|
+
"explanation": "maxSurge=1 allows one extra pod above the desired count (4+1=5). maxUnavailable=0 means all 4 desired pods must remain available. So Kubernetes creates a new pod first, waits for it to be ready, then terminates an old one."
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"id": 6,
|
|
124
|
+
"domain": "Domain 2: Application Deployment",
|
|
125
|
+
"question": "How do you rollback a Deployment named 'web-app' to its previous version?",
|
|
126
|
+
"options": [
|
|
127
|
+
"kubectl rollback deployment web-app",
|
|
128
|
+
"kubectl rollout undo deployment web-app",
|
|
129
|
+
"kubectl revert deployment web-app",
|
|
130
|
+
"kubectl apply --previous deployment web-app"
|
|
131
|
+
],
|
|
132
|
+
"correct": 1,
|
|
133
|
+
"explanation": "kubectl rollout undo deployment <name> rolls back to the previous revision. You can also specify a revision with --to-revision=N. Use 'kubectl rollout history' to view available revisions."
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": 7,
|
|
137
|
+
"domain": "Domain 2: Application Deployment",
|
|
138
|
+
"question": "You installed a Helm chart with 'helm install my-release bitnami/nginx'. How do you update the release with new values?",
|
|
139
|
+
"options": [
|
|
140
|
+
"helm update my-release bitnami/nginx -f values.yaml",
|
|
141
|
+
"helm upgrade my-release bitnami/nginx -f values.yaml",
|
|
142
|
+
"helm apply my-release bitnami/nginx -f values.yaml",
|
|
143
|
+
"helm install --upgrade my-release bitnami/nginx -f values.yaml"
|
|
144
|
+
],
|
|
145
|
+
"correct": 1,
|
|
146
|
+
"explanation": "helm upgrade is used to update an existing release with new chart versions or values. The -f flag specifies a custom values file. Use --install flag to install if the release doesn't exist yet."
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": 8,
|
|
150
|
+
"domain": "Domain 2: Application Deployment",
|
|
151
|
+
"question": "What does a Blue-Green deployment strategy ensure?",
|
|
152
|
+
"options": [
|
|
153
|
+
"Traffic is gradually shifted from old to new version",
|
|
154
|
+
"Two complete environments exist, and traffic is switched entirely from one to the other",
|
|
155
|
+
"Only one pod is updated at a time",
|
|
156
|
+
"The deployment is paused until manually approved"
|
|
157
|
+
],
|
|
158
|
+
"correct": 1,
|
|
159
|
+
"explanation": "Blue-Green deployment maintains two identical environments (Blue=current, Green=new). Once the Green environment is verified, traffic is switched entirely to Green. This enables instant rollback by switching back to Blue."
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"id": 9,
|
|
163
|
+
"domain": "Domain 3: Application Observability and Maintenance",
|
|
164
|
+
"question": "A pod's readinessProbe fails. What is the consequence?",
|
|
165
|
+
"options": [
|
|
166
|
+
"The pod is restarted",
|
|
167
|
+
"The pod is removed from the Service's endpoints (stops receiving traffic)",
|
|
168
|
+
"The pod is deleted and a new one is created",
|
|
169
|
+
"The node is marked as NotReady"
|
|
170
|
+
],
|
|
171
|
+
"correct": 1,
|
|
172
|
+
"explanation": "When a readinessProbe fails, the pod is removed from Service endpoints and stops receiving traffic. Unlike livenessProbe, a failed readinessProbe does NOT restart the pod — it just marks it as not ready to serve."
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"id": 10,
|
|
176
|
+
"domain": "Domain 3: Application Observability and Maintenance",
|
|
177
|
+
"question": "Which probe type should you use for a container that takes a long time to start up?",
|
|
178
|
+
"options": [
|
|
179
|
+
"livenessProbe with a high initialDelaySeconds",
|
|
180
|
+
"readinessProbe with failureThreshold=100",
|
|
181
|
+
"startupProbe",
|
|
182
|
+
"execProbe"
|
|
183
|
+
],
|
|
184
|
+
"correct": 2,
|
|
185
|
+
"explanation": "startupProbe is specifically designed for slow-starting containers. When defined, it disables liveness and readiness checks until the container starts successfully. This prevents premature restarts by the livenessProbe."
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"id": 11,
|
|
189
|
+
"domain": "Domain 3: Application Observability and Maintenance",
|
|
190
|
+
"question": "How do you view real-time logs from multiple pods of a Deployment named 'api'?",
|
|
191
|
+
"options": [
|
|
192
|
+
"kubectl logs deployment/api --all",
|
|
193
|
+
"kubectl logs -l app=api --follow",
|
|
194
|
+
"kubectl exec deployment/api -- tail -f /var/log/app.log",
|
|
195
|
+
"kubectl describe deployment api | grep logs"
|
|
196
|
+
],
|
|
197
|
+
"correct": 1,
|
|
198
|
+
"explanation": "kubectl logs -l <label-selector> streams logs from all pods matching the label. --follow (-f) enables real-time streaming. This is useful for debugging across multiple replicas simultaneously."
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"id": 12,
|
|
202
|
+
"domain": "Domain 4: Application Environment, Configuration and Security",
|
|
203
|
+
"question": "How do you create a ConfigMap from a file named 'app.properties'?",
|
|
204
|
+
"options": [
|
|
205
|
+
"kubectl create configmap my-config --from-file=app.properties",
|
|
206
|
+
"kubectl apply configmap my-config --file=app.properties",
|
|
207
|
+
"kubectl create secret generic my-config --from-file=app.properties",
|
|
208
|
+
"kubectl create configmap my-config --data=app.properties"
|
|
209
|
+
],
|
|
210
|
+
"correct": 0,
|
|
211
|
+
"explanation": "kubectl create configmap --from-file=<filename> creates a ConfigMap with the file's content. The key defaults to the filename. Use --from-file=<key>=<filename> to specify a custom key."
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"id": 13,
|
|
215
|
+
"domain": "Domain 4: Application Environment, Configuration and Security",
|
|
216
|
+
"question": "What is the difference between a ConfigMap and a Secret in terms of data storage?",
|
|
217
|
+
"options": [
|
|
218
|
+
"Secrets are encrypted at rest by default, ConfigMaps are not",
|
|
219
|
+
"Secrets store data as base64-encoded strings, ConfigMaps store plain text",
|
|
220
|
+
"ConfigMaps can only store key-value pairs, Secrets can store files",
|
|
221
|
+
"There is no difference, they are interchangeable"
|
|
222
|
+
],
|
|
223
|
+
"correct": 1,
|
|
224
|
+
"explanation": "Secrets store data as base64-encoded strings (not encrypted by default). etcd encryption at rest must be configured separately. ConfigMaps store plain text data. Both can be mounted as volumes or used as environment variables."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"id": 14,
|
|
228
|
+
"domain": "Domain 4: Application Environment, Configuration and Security",
|
|
229
|
+
"question": "A pod's SecurityContext has 'runAsNonRoot: true'. What happens if the container image runs as root by default?",
|
|
230
|
+
"options": [
|
|
231
|
+
"The container runs as root anyway",
|
|
232
|
+
"The pod fails to start with a security validation error",
|
|
233
|
+
"Kubernetes automatically assigns a random non-root UID",
|
|
234
|
+
"The runAsNonRoot setting is ignored"
|
|
235
|
+
],
|
|
236
|
+
"correct": 1,
|
|
237
|
+
"explanation": "With runAsNonRoot: true, if the container's image is configured to run as root (UID 0) and no runAsUser is specified, the pod will fail to start. You must either set runAsUser to a non-root UID or use an image that runs as non-root."
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"id": 15,
|
|
241
|
+
"domain": "Domain 4: Application Environment, Configuration and Security",
|
|
242
|
+
"question": "What happens when a container exceeds its memory LIMIT?",
|
|
243
|
+
"options": [
|
|
244
|
+
"The container is throttled to the limit",
|
|
245
|
+
"The container is OOMKilled (Out of Memory Killed)",
|
|
246
|
+
"A warning event is generated but the container continues",
|
|
247
|
+
"The pod is rescheduled to a node with more memory"
|
|
248
|
+
],
|
|
249
|
+
"correct": 1,
|
|
250
|
+
"explanation": "When a container exceeds its memory limit, the kernel's OOM killer terminates it (OOMKilled). This is different from CPU limits, where the container is throttled rather than killed. Kubernetes then restarts the container based on restartPolicy."
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"id": 16,
|
|
254
|
+
"domain": "Domain 4: Application Environment, Configuration and Security",
|
|
255
|
+
"question": "How do you mount a specific key from a ConfigMap as a file in a pod?",
|
|
256
|
+
"options": [
|
|
257
|
+
"Use volumeMounts with subPath matching the key name",
|
|
258
|
+
"Use env.valueFrom.configMapKeyRef",
|
|
259
|
+
"ConfigMaps can only be mounted as entire directories",
|
|
260
|
+
"Use configMap.items with key and path in the volume definition"
|
|
261
|
+
],
|
|
262
|
+
"correct": 3,
|
|
263
|
+
"explanation": "In the volume definition, use configMap.items to specify which keys to include and their file paths. For example: items: [{key: 'app.conf', path: 'app.conf'}]. SubPath can also be used in volumeMounts for single-key mounting."
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"id": 17,
|
|
267
|
+
"domain": "Domain 5: Services and Networking",
|
|
268
|
+
"question": "What is the difference between a ClusterIP and a NodePort Service?",
|
|
269
|
+
"options": [
|
|
270
|
+
"ClusterIP exposes the service externally, NodePort is internal only",
|
|
271
|
+
"ClusterIP is accessible only within the cluster, NodePort exposes the service on each node's IP at a static port",
|
|
272
|
+
"ClusterIP uses TCP, NodePort uses UDP",
|
|
273
|
+
"ClusterIP requires an Ingress, NodePort does not"
|
|
274
|
+
],
|
|
275
|
+
"correct": 1,
|
|
276
|
+
"explanation": "ClusterIP (default) creates an internal-only virtual IP. NodePort exposes the service on each node's IP at a port in the range 30000-32767, making it accessible from outside the cluster via <NodeIP>:<NodePort>."
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"id": 18,
|
|
280
|
+
"domain": "Domain 5: Services and Networking",
|
|
281
|
+
"question": "An Ingress resource routes '/api' to service 'api-svc' and '/web' to service 'web-svc'. Which annotation controls URL rewriting in nginx ingress?",
|
|
282
|
+
"options": [
|
|
283
|
+
"nginx.ingress.kubernetes.io/rewrite-target: /",
|
|
284
|
+
"nginx.ingress.kubernetes.io/url-rewrite: true",
|
|
285
|
+
"nginx.ingress.kubernetes.io/path-redirect: /",
|
|
286
|
+
"nginx.ingress.kubernetes.io/backend-path: /"
|
|
287
|
+
],
|
|
288
|
+
"correct": 0,
|
|
289
|
+
"explanation": "nginx.ingress.kubernetes.io/rewrite-target controls the URL rewriting. Setting it to '/' rewrites the matched path to '/'. For example, a request to '/api/users' would be forwarded to the backend as '/users'."
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"id": 19,
|
|
293
|
+
"domain": "Domain 5: Services and Networking",
|
|
294
|
+
"question": "A NetworkPolicy allows ingress only from pods with label 'role=frontend' on port 8080. A pod with label 'role=backend' tries to connect on port 8080. What happens?",
|
|
295
|
+
"options": [
|
|
296
|
+
"The connection is allowed because port 8080 is open",
|
|
297
|
+
"The connection is denied because the source pod doesn't match the ingress rule",
|
|
298
|
+
"The NetworkPolicy is ignored because it only affects egress",
|
|
299
|
+
"The connection times out only if the CNI plugin doesn't support NetworkPolicy"
|
|
300
|
+
],
|
|
301
|
+
"correct": 1,
|
|
302
|
+
"explanation": "NetworkPolicy ingress rules specify both 'from' (source pods/namespaces) and 'ports'. Even though port 8080 matches, the source pod doesn't have label 'role=frontend', so the connection is denied."
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"id": 20,
|
|
306
|
+
"domain": "Domain 5: Services and Networking",
|
|
307
|
+
"question": "Which Service type automatically provisions a cloud load balancer?",
|
|
308
|
+
"options": [
|
|
309
|
+
"ClusterIP",
|
|
310
|
+
"NodePort",
|
|
311
|
+
"LoadBalancer",
|
|
312
|
+
"ExternalName"
|
|
313
|
+
],
|
|
314
|
+
"correct": 2,
|
|
315
|
+
"explanation": "LoadBalancer type automatically provisions an external load balancer (e.g., AWS ELB, GCP Load Balancer). It builds on NodePort, which builds on ClusterIP. ExternalName maps a Service to a DNS name without any proxy."
|
|
316
|
+
}
|
|
317
|
+
]
|
|
318
|
+
}
|