@xdev-asia/xdev-knowledge-mcp 1.0.43 → 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 (61) hide show
  1. package/content/pages/xoa-du-lieu-nguoi-dung.md +68 -0
  2. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/01-phan-1-data-engineering/lessons/01-bai-1-data-repositories-ingestion.md +5 -0
  3. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/01-phan-1-data-engineering/lessons/02-bai-2-data-transformation.md +5 -0
  4. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/01-phan-1-data-engineering/lessons/03-bai-3-data-analysis.md +159 -0
  5. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/02-phan-2-modeling/lessons/04-bai-4-sagemaker-built-in-algorithms.md +186 -0
  6. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/02-phan-2-modeling/lessons/05-bai-5-training-hyperparameter-tuning.md +159 -0
  7. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/02-phan-2-modeling/lessons/06-bai-6-model-evaluation.md +169 -0
  8. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/03-phan-3-implementation-operations/lessons/07-bai-7-model-deployment.md +193 -0
  9. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/03-phan-3-implementation-operations/lessons/08-bai-8-model-monitoring-mlops.md +184 -0
  10. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/03-phan-3-implementation-operations/lessons/09-bai-9-security-cost.md +166 -0
  11. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/04-phan-4-on-tap/lessons/10-bai-10-bai-toan-thuong-gap.md +181 -0
  12. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/04-phan-4-on-tap/lessons/11-bai-11-cheat-sheet.md +110 -0
  13. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/chapters/04-phan-4-on-tap/lessons/12-bai-12-chien-luoc-thi.md +113 -0
  14. package/content/series/luyen-thi/luyen-thi-aws-ml-specialty/index.md +1 -1
  15. package/content/series/luyen-thi/luyen-thi-cka/chapters/01-cluster-architecture/lessons/01-kien-truc-cka-kubeadm.md +133 -0
  16. package/content/series/luyen-thi/luyen-thi-cka/chapters/01-cluster-architecture/lessons/02-cluster-upgrade-kubeadm.md +147 -0
  17. package/content/series/luyen-thi/luyen-thi-cka/chapters/01-cluster-architecture/lessons/03-rbac-cka.md +152 -0
  18. package/content/series/luyen-thi/luyen-thi-cka/chapters/02-workloads-scheduling/lessons/04-deployments-daemonsets-statefulsets.md +186 -0
  19. package/content/series/luyen-thi/luyen-thi-cka/chapters/02-workloads-scheduling/lessons/05-scheduling-taints-affinity.md +163 -0
  20. package/content/series/luyen-thi/luyen-thi-cka/chapters/03-services-networking/lessons/06-services-endpoints-coredns.md +145 -0
  21. package/content/series/luyen-thi/luyen-thi-cka/chapters/03-services-networking/lessons/07-ingress-networkpolicies-cni.md +172 -0
  22. package/content/series/luyen-thi/luyen-thi-cka/chapters/04-storage/lessons/08-persistent-volumes-storageclass.md +159 -0
  23. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/09-etcd-backup-restore.md +149 -0
  24. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/10-troubleshooting-nodes.md +153 -0
  25. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/11-troubleshooting-workloads.md +146 -0
  26. package/content/series/luyen-thi/luyen-thi-cka/chapters/05-troubleshooting/lessons/12-troubleshooting-networking-exam.md +170 -0
  27. package/content/series/luyen-thi/luyen-thi-cka/index.md +217 -0
  28. package/content/series/luyen-thi/luyen-thi-ckad/chapters/01-app-design-build/lessons/01-multi-container-pods.md +146 -0
  29. package/content/series/luyen-thi/luyen-thi-ckad/chapters/01-app-design-build/lessons/02-jobs-cronjobs-resources.md +174 -0
  30. package/content/series/luyen-thi/luyen-thi-ckad/chapters/02-app-deployment/lessons/03-rolling-updates-rollbacks.md +148 -0
  31. package/content/series/luyen-thi/luyen-thi-ckad/chapters/02-app-deployment/lessons/04-helm-kustomize.md +181 -0
  32. package/content/series/luyen-thi/luyen-thi-ckad/chapters/03-app-observability/lessons/05-probes-logging-debugging.md +183 -0
  33. package/content/series/luyen-thi/luyen-thi-ckad/chapters/04-app-environment-config/lessons/06-configmaps-secrets.md +182 -0
  34. package/content/series/luyen-thi/luyen-thi-ckad/chapters/04-app-environment-config/lessons/07-securitycontext-pod-security.md +168 -0
  35. package/content/series/luyen-thi/luyen-thi-ckad/chapters/04-app-environment-config/lessons/08-resources-qos.md +168 -0
  36. package/content/series/luyen-thi/luyen-thi-ckad/chapters/05-services-networking/lessons/09-services-ingress.md +182 -0
  37. package/content/series/luyen-thi/luyen-thi-ckad/chapters/05-services-networking/lessons/10-networkpolicies-exam-strategy.md +236 -0
  38. package/content/series/luyen-thi/luyen-thi-ckad/index.md +199 -0
  39. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/01-phan-1-problem-framing/lessons/01-bai-1-framing-ml-problems.md +136 -0
  40. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/01-phan-1-problem-framing/lessons/02-bai-2-gcp-ai-ml-ecosystem.md +160 -0
  41. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/02-phan-2-data-engineering/lessons/03-bai-3-data-pipeline.md +174 -0
  42. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/02-phan-2-data-engineering/lessons/04-bai-4-feature-engineering.md +156 -0
  43. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/03-phan-3-model-development/lessons/05-bai-5-vertex-ai-training.md +155 -0
  44. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/03-phan-3-model-development/lessons/06-bai-6-bigquery-ml-tensorflow.md +141 -0
  45. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/04-phan-4-deployment-mlops/lessons/07-bai-7-model-deployment.md +134 -0
  46. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/04-phan-4-deployment-mlops/lessons/08-bai-8-vertex-ai-pipelines-mlops.md +149 -0
  47. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/05-phan-5-responsible-ai/lessons/09-bai-9-responsible-ai.md +128 -0
  48. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/chapters/05-phan-5-responsible-ai/lessons/10-bai-10-cheat-sheet-chien-luoc-thi.md +108 -0
  49. package/content/series/luyen-thi/luyen-thi-gcp-ml-engineer/index.md +1 -1
  50. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/01-kien-truc-kubernetes.md +137 -0
  51. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/02-pods-workloads-controllers.md +142 -0
  52. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/03-services-networking-storage.md +155 -0
  53. package/content/series/luyen-thi/luyen-thi-kcna/chapters/01-kubernetes-fundamentals/lessons/04-rbac-security.md +137 -0
  54. package/content/series/luyen-thi/luyen-thi-kcna/chapters/02-container-orchestration/lessons/05-container-runtimes-oci.md +137 -0
  55. package/content/series/luyen-thi/luyen-thi-kcna/chapters/02-container-orchestration/lessons/06-orchestration-patterns.md +147 -0
  56. package/content/series/luyen-thi/luyen-thi-kcna/chapters/03-cloud-native-architecture/lessons/07-cloud-native-architecture.md +143 -0
  57. package/content/series/luyen-thi/luyen-thi-kcna/chapters/04-observability-delivery/lessons/08-observability.md +143 -0
  58. package/content/series/luyen-thi/luyen-thi-kcna/chapters/04-observability-delivery/lessons/09-helm-gitops-cicd.md +162 -0
  59. package/content/series/luyen-thi/luyen-thi-kcna/index.md +168 -0
  60. package/data/quizzes.json +1059 -0
  61. package/package.json +1 -1
@@ -0,0 +1,155 @@
1
+ ---
2
+ id: kcna-d1-l03
3
+ title: 'Bài 3: Services, Networking & Storage'
4
+ slug: 03-services-networking-storage
5
+ description: >-
6
+ Service types (ClusterIP, NodePort, LoadBalancer, ExternalName). CoreDNS
7
+ và service discovery. PersistentVolume, PVC, ConfigMap, Secret.
8
+ duration_minutes: 60
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 3
12
+ section_title: "Domain 1: Kubernetes Fundamentals (46%)"
13
+ course:
14
+ id: lt-kcna-series-001
15
+ title: 'Luyện thi KCNA — Kubernetes and Cloud Native Associate'
16
+ slug: luyen-thi-kcna
17
+ ---
18
+
19
+ <img src="/storage/uploads/2026/04/k8s-cert-kcna-bai3-services-networking.png" alt="Kubernetes Services và Networking — ClusterIP, NodePort, LoadBalancer" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="services">1. Service Types</h2>
22
+
23
+ <p>Pods có IP tạm thời, bị xóa khi restart. <strong>Service</strong> cung cấp stable Virtual IP (ClusterIP) và load-balancing đến một nhóm Pods qua label selector.</p>
24
+
25
+ <table>
26
+ <thead><tr><th>Type</th><th>Reachable From</th><th>Use Case</th><th>Real-world Example</th></tr></thead>
27
+ <tbody>
28
+ <tr><td><strong>ClusterIP</strong></td><td>Cluster internal only</td><td>Backend microservices</td><td>Payment service → DB</td></tr>
29
+ <tr><td><strong>NodePort</strong></td><td>External via NodeIP:Port (30000-32767)</td><td>Dev/test access</td><td>Demo app on bare metal</td></tr>
30
+ <tr><td><strong>LoadBalancer</strong></td><td>External via cloud LB</td><td>Production apps on cloud</td><td>AWS/GCP internet traffic</td></tr>
31
+ <tr><td><strong>ExternalName</strong></td><td>CNAME alias for external service</td><td>Integrate external DNS</td><td>legacy-db.company.com</td></tr>
32
+ </tbody>
33
+ </table>
34
+
35
+ <pre><code class="language-text">External Traffic
36
+
37
+
38
+ [LoadBalancer] ← cloud provider LB (AWS ELB, GCP)
39
+
40
+ [NodePort :30080] ← all nodes expose port 30080
41
+
42
+ [ClusterIP 10.96.5.3] ← virtual IP, iptables/IPVS routing
43
+
44
+ ┌────┴────┐
45
+ [Pod A] [Pod B] ← matched by label selector</code></pre>
46
+
47
+ <blockquote><p><strong>Exam tip:</strong> <strong>NodePort</strong> tự động tạo thêm <strong>ClusterIP</strong>. <strong>LoadBalancer</strong> tự động tạo thêm <strong>NodePort + ClusterIP</strong>. Mỗi type kế thừa type nhỏ hơn.</p></blockquote>
48
+
49
+ <h2 id="coredns">2. CoreDNS & Service Discovery</h2>
50
+
51
+ <p><strong>CoreDNS</strong> là DNS server mặc định trong Kubernetes cluster. Mỗi Service được đăng ký DNS record tự động.</p>
52
+
53
+ <pre><code class="language-text">DNS format: {service}.{namespace}.svc.cluster.local
54
+
55
+ Ví dụ:
56
+ Service "api" trong namespace "production":
57
+ → api.production.svc.cluster.local
58
+ → api.production.svc
59
+ → api.production
60
+ → api (chỉ trong cùng namespace)</code></pre>
61
+
62
+ <table>
63
+ <thead><tr><th>DNS Query</th><th>Resolves To</th><th>Works From</th></tr></thead>
64
+ <tbody>
65
+ <tr><td><code>api</code></td><td>Service ClusterIP</td><td>Same namespace only</td></tr>
66
+ <tr><td><code>api.production</code></td><td>Service ClusterIP</td><td>Any namespace</td></tr>
67
+ <tr><td><code>api.production.svc.cluster.local</code></td><td>Service ClusterIP</td><td>Any namespace (FQDN)</td></tr>
68
+ </tbody>
69
+ </table>
70
+
71
+ <h2 id="storage">3. Storage: PV, PVC, StorageClass</h2>
72
+
73
+ <pre><code class="language-text">Storage lifecycle:
74
+ STATIC DYNAMIC
75
+ ───── ───────
76
+ Admin creates → PersistentVolume StorageClass (provision template)
77
+ App requests → PersistentVolumeClaim → SC auto-provisions PV
78
+ Pod mounts → PVC as volume</code></pre>
79
+
80
+ <table>
81
+ <thead><tr><th>Concept</th><th>Vai trò</th><th>Ai tạo</th></tr></thead>
82
+ <tbody>
83
+ <tr><td><strong>PersistentVolume (PV)</strong></td><td>Tài nguyên storage thực tế (NFS, EBS, GCE Disk)</td><td>Admin hoặc dynamic provisioner</td></tr>
84
+ <tr><td><strong>PersistentVolumeClaim (PVC)</strong></td><td>Request storage với size + access mode</td><td>Developer / App</td></tr>
85
+ <tr><td><strong>StorageClass</strong></td><td>Template tự động tạo PV khi có PVC</td><td>Admin</td></tr>
86
+ </tbody>
87
+ </table>
88
+
89
+ <h3 id="access-modes">Access Modes</h3>
90
+
91
+ <table>
92
+ <thead><tr><th>Mode</th><th>Abbrev</th><th>Ý nghĩa</th><th>Ví dụ</th></tr></thead>
93
+ <tbody>
94
+ <tr><td>ReadWriteOnce</td><td><strong>RWO</strong></td><td>1 node đọc+ghi</td><td>EBS volume, local disk</td></tr>
95
+ <tr><td>ReadOnlyMany</td><td><strong>ROX</strong></td><td>Nhiều nodes đọc</td><td>Static files on NFS</td></tr>
96
+ <tr><td>ReadWriteMany</td><td><strong>RWX</strong></td><td>Nhiều nodes đọc+ghi</td><td>NFS, EFS, GlusterFS</td></tr>
97
+ <tr><td>ReadWriteOncePod</td><td><strong>RWOP</strong></td><td>Chỉ 1 Pod (v1.22+)</td><td>Exclusive access needed</td></tr>
98
+ </tbody>
99
+ </table>
100
+
101
+ <blockquote><p><strong>Exam tip:</strong> AWS EBS chỉ hỗ trợ <strong>RWO</strong>. Nếu câu hỏi yêu cầu nhiều Pods ghi đồng thời, cần dùng NFS (RWX). StatefulSet thường dùng RWO với mỗi Pod có PVC riêng.</p></blockquote>
102
+
103
+ <h2 id="configmap-secret">4. ConfigMap & Secret</h2>
104
+
105
+ <table>
106
+ <thead><tr><th>Resource</th><th>Dùng cho</th><th>Encoding</th><th>Inject vào Pod</th></tr></thead>
107
+ <tbody>
108
+ <tr><td><strong>ConfigMap</strong></td><td>Config không nhạy cảm (URLs, flags, env files)</td><td>Plain text</td><td>Env var, volume file, CLI args</td></tr>
109
+ <tr><td><strong>Secret</strong></td><td>Data nhạy cảm (passwords, API keys, TLS certs)</td><td>Base64 (NOT encrypted by default)</td><td>Env var (không khuyến khích), volume mount</td></tr>
110
+ </tbody>
111
+ </table>
112
+
113
+ <blockquote><p><strong>Exam tip:</strong> Secret chỉ là base64 encoded, <strong>KHÔNG phải encrypted</strong>. Để encrypt Secret at rest, cần bật <strong>Encryption Configuration</strong> ở API Server. Câu hỏi hay dùng "encrypted" như distractor sai.</p></blockquote>
114
+
115
+ <h2 id="cheatsheet">5. Cheat Sheet</h2>
116
+
117
+ <table>
118
+ <thead><tr><th>Câu hỏi exam</th><th>Đáp án</th></tr></thead>
119
+ <tbody>
120
+ <tr><td>Expose app ra ngoài cluster trên cloud?</td><td><strong>LoadBalancer</strong> (hoặc Ingress)</td></tr>
121
+ <tr><td>DNS name cho Service "db" trong ns "backend"?</td><td><code>db.backend.svc.cluster.local</code></td></tr>
122
+ <tr><td>Cần storage shared giữa nhiều Pods?</td><td>PV với access mode <strong>RWX</strong></td></tr>
123
+ <tr><td>Tự động provision storage khi deploy?</td><td><strong>StorageClass</strong> + PVC</td></tr>
124
+ <tr><td>Secret có bị encrypt by default?</td><td><strong>Không</strong>, chỉ base64</td></tr>
125
+ </tbody>
126
+ </table>
127
+
128
+ <h2 id="practice">6. Practice Questions</h2>
129
+
130
+ <p><strong>Q1:</strong> A developer wants to access a backend database Service named "orders-db" from a different namespace called "frontend". Which DNS name should they use?</p>
131
+ <ul>
132
+ <li>A) orders-db</li>
133
+ <li>B) orders-db.default.svc.cluster.local</li>
134
+ <li>C) orders-db.backend.svc.cluster.local ✓</li>
135
+ <li>D) backend.orders-db.cluster.local</li>
136
+ </ul>
137
+ <p><em>Explanation: Cross-namespace DNS requires the full format: {service}.{namespace}.svc.cluster.local. Short name "orders-db" only works within the same namespace.</em></p>
138
+
139
+ <p><strong>Q2:</strong> Which Service type automatically creates a ClusterIP AND a NodePort?</p>
140
+ <ul>
141
+ <li>A) ClusterIP</li>
142
+ <li>B) NodePort</li>
143
+ <li>C) LoadBalancer ✓</li>
144
+ <li>D) ExternalName</li>
145
+ </ul>
146
+ <p><em>Explanation: LoadBalancer is a superset — it creates ClusterIP + NodePort + cloud load balancer. NodePort includes ClusterIP, but ClusterIP is standalone with no external access.</em></p>
147
+
148
+ <p><strong>Q3:</strong> A Secret contains a database password. A developer claims the password is "encrypted". Is this claim accurate?</p>
149
+ <ul>
150
+ <li>A) Yes, Kubernetes Secrets are encrypted with AES</li>
151
+ <li>B) No, Secrets are only base64 encoded unless Encryption Configuration is enabled ✓</li>
152
+ <li>C) Yes, Secrets are encrypted using etcd's built-in encryption</li>
153
+ <li>D) No, Secrets are stored in plain text</li>
154
+ </ul>
155
+ <p><em>Explanation: By default, Secrets are stored as base64-encoded strings in etcd — which is NOT encryption. Administrators must configure EncryptionConfiguration on the API server to enable encryption at rest.</em></p>
@@ -0,0 +1,137 @@
1
+ ---
2
+ id: kcna-d1-l04
3
+ title: 'Bài 4: RBAC & Kubernetes Security'
4
+ slug: 04-rbac-security
5
+ description: >-
6
+ Role-Based Access Control (RBAC), ServiceAccounts, Network Policies,
7
+ Pod Security Standards và Security Context. Bảo mật Kubernetes cluster.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 4
12
+ section_title: "Domain 1: Kubernetes Fundamentals (46%)"
13
+ course:
14
+ id: lt-kcna-series-001
15
+ title: 'Luyện thi KCNA — Kubernetes and Cloud Native Associate'
16
+ slug: luyen-thi-kcna
17
+ ---
18
+
19
+ <img src="/storage/uploads/2026/04/k8s-cert-kcna-bai4-rbac.png" alt="RBAC Authorization Model — Subject, RoleBinding, Role, Rules" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="rbac">1. RBAC — Role-Based Access Control</h2>
22
+
23
+ <p><strong>RBAC</strong> kiểm soát ai (User, Group, ServiceAccount) được làm gì (verbs) với tài nguyên nào (resources) trong namespace hoặc cluster.</p>
24
+
25
+ <pre><code class="language-text">RBAC Flow:
26
+ Subject (Who?) → Role/ClusterRole (What?) → RoleBinding (Links)
27
+
28
+ User "alice" Role "pod-reader" RoleBinding
29
+ ServiceAccount - get pods alice → pod-reader
30
+ Group "devs" - list pods (in namespace "dev")
31
+ - watch pods</code></pre>
32
+
33
+ <table>
34
+ <thead><tr><th>Object</th><th>Scope</th><th>Dùng khi</th></tr></thead>
35
+ <tbody>
36
+ <tr><td><strong>Role</strong></td><td>Namespace</td><td>Quyền trong 1 namespace</td></tr>
37
+ <tr><td><strong>ClusterRole</strong></td><td>Cluster-wide</td><td>Quyền trên toàn cluster hoặc non-namespaced resources (nodes)</td></tr>
38
+ <tr><td><strong>RoleBinding</strong></td><td>Namespace</td><td>Gán Role or ClusterRole cho Subject trong 1 namespace</td></tr>
39
+ <tr><td><strong>ClusterRoleBinding</strong></td><td>Cluster-wide</td><td>Gán ClusterRole cho Subject trên toàn cluster</td></tr>
40
+ </tbody>
41
+ </table>
42
+
43
+ <blockquote><p><strong>Exam tip:</strong> Có thể dùng <strong>RoleBinding</strong> để gán <strong>ClusterRole</strong> vào 1 namespace cụ thể — đây là cách tái sử dụng permission template mà không cấp quyền toàn cluster. Rất hay xuất hiện trong exam!</p></blockquote>
44
+
45
+ <h2 id="serviceaccounts">2. ServiceAccounts</h2>
46
+
47
+ <p>Mỗi Pod có thể gắn một <strong>ServiceAccount</strong>. Token của ServiceAccount được mount tự động vào <code>/var/run/secrets/kubernetes.io/serviceaccount/</code>. Pods dùng token này để gọi Kubernetes API.</p>
48
+
49
+ <pre><code class="language-text">Default ServiceAccount flow:
50
+ Pod → ServiceAccount → RBAC Role → API Server
51
+
52
+ Ví dụ: Prometheus cần đọc Pod metrics:
53
+ ServiceAccount: prometheus-sa
54
+ ClusterRole: pod-metrics-reader (verbs: get, list, watch)
55
+ ClusterRoleBinding: prometheus-sa → pod-metrics-reader</code></pre>
56
+
57
+ <h2 id="network-policies">3. Network Policies</h2>
58
+
59
+ <p>Mặc định, tất cả Pods trong cluster có thể communicate với nhau. <strong>NetworkPolicy</strong> cho phép giới hạn traffic ingress/egress dựa trên Pod selector, namespace selector, hoặc IP block.</p>
60
+
61
+ <pre><code class="language-text">❌ Default (no NetworkPolicy): All pods talk to all pods
62
+ ✅ With NetworkPolicy:
63
+ frontend → backend (allowed)
64
+ frontend → database (BLOCKED)
65
+ backend → database (allowed)</code></pre>
66
+
67
+ <blockquote><p><strong>Exam tip:</strong> NetworkPolicy chỉ có tác dụng khi <strong>CNI plugin hỗ trợ</strong> (Calico, Cilium, Weave). Flannel không hỗ trợ NetworkPolicy. Nếu không có policy nào → allow all. Nếu có ít nhất 1 policy → default deny cho traffic được select.</p></blockquote>
68
+
69
+ <h2 id="pod-security">4. Pod Security Standards</h2>
70
+
71
+ <p>Kubernetes định nghĩa 3 <strong>Pod Security Standards</strong> (thay thế PodSecurityPolicy từ v1.25):</p>
72
+
73
+ <table>
74
+ <thead><tr><th>Profile</th><th>Mức độ hạn chế</th><th>Dùng cho</th></tr></thead>
75
+ <tbody>
76
+ <tr><td><strong>Privileged</strong></td><td>Không hạn chế</td><td>System/infra workloads (kube-system)</td></tr>
77
+ <tr><td><strong>Baseline</strong></td><td>Ngăn escalation rõ ràng</td><td>Workloads thông thường</td></tr>
78
+ <tr><td><strong>Restricted</strong></td><td>Tuân thủ hardening tối đa</td><td>Security-sensitive apps</td></tr>
79
+ </tbody>
80
+ </table>
81
+
82
+ <h2 id="security-context">5. SecurityContext</h2>
83
+
84
+ <p><strong>SecurityContext</strong> cấu hình bảo mật ở cấp Pod hoặc Container:</p>
85
+
86
+ <table>
87
+ <thead><tr><th>Security setting</th><th>Ý nghĩa</th></tr></thead>
88
+ <tbody>
89
+ <tr><td><code>runAsNonRoot: true</code></td><td>Container không được chạy với UID 0</td></tr>
90
+ <tr><td><code>runAsUser: 1000</code></td><td>Chạy container với UID 1000</td></tr>
91
+ <tr><td><code>readOnlyRootFilesystem: true</code></td><td>Filesystem read-only (write phải dùng volume)</td></tr>
92
+ <tr><td><code>allowPrivilegeEscalation: false</code></td><td>Không cho process leo thang đặc quyền</td></tr>
93
+ <tr><td><code>capabilities.drop: ["ALL"]</code></td><td>Bỏ tất cả Linux capabilities</td></tr>
94
+ </tbody>
95
+ </table>
96
+
97
+ <h2 id="cheatsheet">6. Cheat Sheet</h2>
98
+
99
+ <table>
100
+ <thead><tr><th>Câu hỏi exam</th><th>Đáp án</th></tr></thead>
101
+ <tbody>
102
+ <tr><td>Pod cần gọi K8s API, dùng gì?</td><td><strong>ServiceAccount</strong></td></tr>
103
+ <tr><td>Giới hạn quyền user trong 1 namespace?</td><td><strong>Role</strong> + <strong>RoleBinding</strong></td></tr>
104
+ <tr><td>Giới hạn network traffic giữa Pods?</td><td><strong>NetworkPolicy</strong></td></tr>
105
+ <tr><td>NetworkPolicy cần gì để hoạt động?</td><td>CNI plugin hỗ trợ (Calico, Cilium)</td></tr>
106
+ <tr><td>Privileged → Restricted, Pod Security cần?</td><td><strong>Pod Security Admission</strong></td></tr>
107
+ </tbody>
108
+ </table>
109
+
110
+ <h2 id="practice">7. Practice Questions</h2>
111
+
112
+ <p><strong>Q1:</strong> An application Pod needs to access the Kubernetes API to list Pods in its own namespace. What should a cluster administrator create?</p>
113
+ <ul>
114
+ <li>A) ClusterRole with ClusterRoleBinding for all namespaces</li>
115
+ <li>B) ServiceAccount with Role (list pods) and RoleBinding ✓</li>
116
+ <li>C) Service with type LoadBalancer for API Server</li>
117
+ <li>D) ConfigMap with API Server credentials</li>
118
+ </ul>
119
+ <p><em>Explanation: The Pod needs a ServiceAccount, a Role granting "list pods" in its namespace, and a RoleBinding linking them. Using ClusterRole would over-grant access across all namespaces.</em></p>
120
+
121
+ <p><strong>Q2:</strong> A NetworkPolicy is applied to a Pod. What is the default behavior for traffic not explicitly matched by any rule?</p>
122
+ <ul>
123
+ <li>A) All traffic is allowed (default allow)</li>
124
+ <li>B) Traffic is logged but not blocked</li>
125
+ <li>C) Traffic that matches the Pod selector is denied; all other traffic passes ✓</li>
126
+ <li>D) All traffic to/from the Pod is denied</li>
127
+ </ul>
128
+ <p><em>Explanation: Once a NetworkPolicy selects a Pod (via podSelector), all traffic not explicitly allowed is denied for that policy type (ingress/egress). Non-selected Pods remain unaffected and have full connectivity.</em></p>
129
+
130
+ <p><strong>Q3:</strong> Which Pod Security Standard profile should be used for a system-level component that requires privileged access to the host?</p>
131
+ <ul>
132
+ <li>A) Restricted</li>
133
+ <li>B) Baseline</li>
134
+ <li>C) Privileged ✓</li>
135
+ <li>D) SystemAdmin</li>
136
+ </ul>
137
+ <p><em>Explanation: The Privileged profile places no restrictions on Pods, allowing all capabilities. It's intended for system/infrastructure components. Baseline prevents known privilege escalations; Restricted enforces maximum hardening.</em></p>
@@ -0,0 +1,137 @@
1
+ ---
2
+ id: kcna-d2-l05
3
+ title: 'Bài 5: Container Runtimes & OCI Standards'
4
+ slug: 05-container-runtimes-oci
5
+ description: >-
6
+ OCI (Open Container Initiative), container runtime interface (CRI).
7
+ Docker, containerd, CRI-O. Image layers, registries và image lifecycle.
8
+ duration_minutes: 50
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 5
12
+ section_title: "Domain 2: Container Orchestration (22%)"
13
+ course:
14
+ id: lt-kcna-series-001
15
+ title: 'Luyện thi KCNA — Kubernetes and Cloud Native Associate'
16
+ slug: luyen-thi-kcna
17
+ ---
18
+
19
+ <img src="/storage/uploads/2026/04/k8s-cert-kcna-bai5-oci-runtimes.png" alt="OCI Container Runtime Stack — CRI, containerd, runc" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="oci">1. OCI — Open Container Initiative</h2>
22
+
23
+ <p><strong>OCI</strong> là tổ chức mở (thuộc Linux Foundation) định nghĩa các chuẩn mở cho containers:</p>
24
+
25
+ <table>
26
+ <thead><tr><th>Specification</th><th>Định nghĩa</th><th>Ví dụ implement</th></tr></thead>
27
+ <tbody>
28
+ <tr><td><strong>OCI Image Spec</strong></td><td>Định dạng container image (layers, manifest)</td><td>Docker image, OCI image</td></tr>
29
+ <tr><td><strong>OCI Runtime Spec</strong></td><td>Cách chạy container từ image (lifecycle, filesystem)</td><td>runc, crun, kata-containers</td></tr>
30
+ <tr><td><strong>OCI Distribution Spec</strong></td><td>API để push/pull image từ registry</td><td>DockerHub, ECR, GCR</td></tr>
31
+ </tbody>
32
+ </table>
33
+
34
+ <blockquote><p><strong>Exam tip:</strong> OCI standards đảm bảo <strong>interoperability</strong>: image build bằng Docker có thể chạy với containerd hoặc CRI-O mà không cần thay đổi. KCNA thường hỏi về vai trò của OCI trong cloud native ecosystem.</p></blockquote>
35
+
36
+ <h2 id="container-runtime">2. Container Runtime Interface (CRI)</h2>
37
+
38
+ <p>Kubernetes không giao tiếp trực tiếp với Docker hay containerd. Thay vào đó, kubelet dùng <strong>CRI (Container Runtime Interface)</strong> — một gRPC API chuẩn.</p>
39
+
40
+ <pre><code class="language-text">Kubernetes Architecture (Runtime Layer):
41
+
42
+ kubelet
43
+ │ CRI (gRPC)
44
+ ├─── containerd ─── runc ─── container
45
+ ├─── CRI-O ─── runc ─── container
46
+ └─── (Docker) ─── (deprecated v1.24+)
47
+
48
+ OCI Runtime (runc, crun):
49
+ - Đọc OCI runtime bundle
50
+ - Gọi Linux kernel (namespaces, cgroups)
51
+ - Tạo container process</code></pre>
52
+
53
+ <h2 id="runtimes-comparison">3. Container Runtimes Comparison</h2>
54
+
55
+ <table>
56
+ <thead><tr><th>Runtime</th><th>Loại</th><th>Đặc điểm</th><th>Dùng trong</th></tr></thead>
57
+ <tbody>
58
+ <tr><td><strong>containerd</strong></td><td>High-level (CRI)</td><td>Nhẹ, stable, CNCF graduated</td><td>Default Kubernetes 1.24+</td></tr>
59
+ <tr><td><strong>CRI-O</strong></td><td>High-level (CRI)</td><td>Tối ưu cho Kubernetes, lightweight</td><td>OpenShift, Kubernetes</td></tr>
60
+ <tr><td><strong>Docker Engine</strong></td><td>High-level (non-CRI)</td><td>Deprecated từ K8s 1.24 (dùng dockershim)</td><td>Dev environments</td></tr>
61
+ <tr><td><strong>runc</strong></td><td>Low-level (OCI)</td><td>Reference OCI implementation</td><td>Backend của containerd/CRI-O</td></tr>
62
+ <tr><td><strong>gVisor (runsc)</strong></td><td>Low-level (sandbox)</td><td>Security sandbox, intercepts syscalls</td><td>GKE sandbox, untrusted workloads</td></tr>
63
+ <tr><td><strong>Kata Containers</strong></td><td>Low-level (VM-based)</td><td>VM isolation per container</td><td>Multi-tenant, high security</td></tr>
64
+ </tbody>
65
+ </table>
66
+
67
+ <blockquote><p><strong>Exam tip:</strong> Docker bị deprecated như Kubernetes runtime từ v1.24, nhưng Docker images (OCI-compatible) vẫn chạy được trên containerd/CRI-O. "Docker deprecated" ≠ "Docker images deprecated".</p></blockquote>
68
+
69
+ <h2 id="image-layers">4. Container Image Layers</h2>
70
+
71
+ <pre><code class="language-text">Layer architecture:
72
+ ┌──────────────────────────────┐
73
+ │ Layer 4: App code (5 MB) │ ← Writeable (container layer)
74
+ ├──────────────────────────────┤
75
+ │ Layer 3: npm packages │ ← Read-only
76
+ ├──────────────────────────────┤
77
+ │ Layer 2: Node.js runtime │ ← Read-only
78
+ ├──────────────────────────────┤
79
+ │ Layer 1: Ubuntu base image │ ← Read-only (shared across images)
80
+ └──────────────────────────────┘
81
+
82
+ Cache benefit: nếu Layer 1-2 giống nhau, chỉ download Layer 3-4</code></pre>
83
+
84
+ <h2 id="registries">5. Container Registries</h2>
85
+
86
+ <table>
87
+ <thead><tr><th>Registry</th><th>Provider</th><th>Đặc điểm</th></tr></thead>
88
+ <tbody>
89
+ <tr><td>Docker Hub</td><td>Docker Inc.</td><td>Public default, rate-limited pulls</td></tr>
90
+ <tr><td>ECR (Elastic Container Registry)</td><td>AWS</td><td>Private, IAM integrated</td></tr>
91
+ <tr><td>GCR / Artifact Registry</td><td>GCP</td><td>Private, Workload Identity</td></tr>
92
+ <tr><td>GHCR (GitHub Container Registry)</td><td>GitHub</td><td>Package-linked, Actions CI</td></tr>
93
+ <tr><td>Harbor</td><td>CNCF (open source)</td><td>Self-hosted, vulnerability scanning</td></tr>
94
+ </tbody>
95
+ </table>
96
+
97
+ <h2 id="cheatsheet">6. Cheat Sheet</h2>
98
+
99
+ <table>
100
+ <thead><tr><th>Câu hỏi exam</th><th>Đáp án</th></tr></thead>
101
+ <tbody>
102
+ <tr><td>OCI định nghĩa chuẩn gì?</td><td>Image Spec, Runtime Spec, Distribution Spec</td></tr>
103
+ <tr><td>Default runtime K8s 1.24+?</td><td><strong>containerd</strong></td></tr>
104
+ <tr><td>CRI là gì?</td><td>Container Runtime Interface — gRPC API giữa kubelet và runtime</td></tr>
105
+ <tr><td>Docker deprecated trong K8s?</td><td><strong>Từ v1.24</strong> (dockershim removed)</td></tr>
106
+ <tr><td>Runtime cho untrusted workloads?</td><td><strong>gVisor</strong> hoặc <strong>Kata Containers</strong></td></tr>
107
+ </tbody>
108
+ </table>
109
+
110
+ <h2 id="practice">7. Practice Questions</h2>
111
+
112
+ <p><strong>Q1:</strong> A Kubernetes cluster uses containerd as the container runtime. A developer pushes a Docker image to Docker Hub. Can this image run on the cluster?</p>
113
+ <ul>
114
+ <li>A) No, Docker images are incompatible with containerd</li>
115
+ <li>B) Yes, because Docker images follow OCI Image Spec and are compatible ✓</li>
116
+ <li>C) Only if the cluster installs a Docker compatibility shim</li>
117
+ <li>D) No, containerd only supports images from CNCF registries</li>
118
+ </ul>
119
+ <p><em>Explanation: Docker images follow the OCI Image Specification, making them interoperable with any OCI-compliant runtime including containerd and CRI-O. The "Docker deprecated" refers to the runtime, not the image format.</em></p>
120
+
121
+ <p><strong>Q2:</strong> What is the primary purpose of the Container Runtime Interface (CRI)?</p>
122
+ <ul>
123
+ <li>A) Define image layer formats</li>
124
+ <li>B) Provide a gRPC API for kubelet to communicate with container runtimes ✓</li>
125
+ <li>C) Manage container image distribution between registries</li>
126
+ <li>D) Schedule containers across cluster nodes</li>
127
+ </ul>
128
+ <p><em>Explanation: CRI gives kubelet a stable API to interact with different runtimes (containerd, CRI-O) without knowing implementation details. This decoupling enables switching runtimes without changing kubelet code.</em></p>
129
+
130
+ <p><strong>Q3:</strong> Which container runtime provides VM-level isolation per container for high-security multi-tenant workloads?</p>
131
+ <ul>
132
+ <li>A) containerd</li>
133
+ <li>B) CRI-O</li>
134
+ <li>C) Kata Containers ✓</li>
135
+ <li>D) runc</li>
136
+ </ul>
137
+ <p><em>Explanation: Kata Containers runs each container inside a lightweight VM, providing stronger isolation than standard Linux namespace-based containers. gVisor provides user-space isolation via syscall interception, also strong but different approach.</em></p>
@@ -0,0 +1,147 @@
1
+ ---
2
+ id: kcna-d2-l06
3
+ title: 'Bài 6: Container Orchestration Patterns'
4
+ slug: 06-orchestration-patterns
5
+ description: >-
6
+ Scheduling, auto-scaling (HPA, VPA, Cluster Autoscaler), resource requests
7
+ và limits, namespaces, multi-tenancy và Kubernetes upgrade strategies.
8
+ duration_minutes: 55
9
+ is_free: true
10
+ video_url: null
11
+ sort_order: 6
12
+ section_title: "Domain 2: Container Orchestration (22%)"
13
+ course:
14
+ id: lt-kcna-series-001
15
+ title: 'Luyện thi KCNA — Kubernetes and Cloud Native Associate'
16
+ slug: luyen-thi-kcna
17
+ ---
18
+
19
+ <img src="/storage/uploads/2026/04/k8s-cert-kcna-bai6-scheduling.png" alt="Kubernetes Scheduling Pipeline và Autoscaling (HPA, VPA, Cluster Autoscaler)" style="max-width: 800px; width: 100%; border-radius: 12px;" />
20
+
21
+ <h2 id="scheduling">1. Kubernetes Scheduling</h2>
22
+
23
+ <p>Khi Pod được tạo, <strong>kube-scheduler</strong> chọn node phù hợp qua 2 bước:</p>
24
+
25
+ <pre><code class="language-text">Scheduling Pipeline:
26
+ New Pod
27
+
28
+
29
+ 1. FILTERING: Loại bỏ nodes không đủ điều kiện
30
+ - Không đủ CPU/Memory
31
+ - Taint không match Toleration
32
+ - Node Affinity không match
33
+
34
+
35
+ 2. SCORING: Chấm điểm nodes còn lại
36
+ - Resource balance
37
+ - Affinity preferences
38
+
39
+
40
+ Bind Pod → Highest score Node</code></pre>
41
+
42
+ <table>
43
+ <thead><tr><th>Cơ chế</th><th>Mục đích</th><th>Ví dụ</th></tr></thead>
44
+ <tbody>
45
+ <tr><td><strong>NodeSelector</strong></td><td>Schedule Pod lên node có label</td><td><code>disktype: ssd</code></td></tr>
46
+ <tr><td><strong>Affinity/Anti-affinity</strong></td><td>Preferred/required node rules</td><td>Prefer zone-a, avoid same node as another pod</td></tr>
47
+ <tr><td><strong>Taints & Tolerations</strong></td><td>Repel Pods trừ khi Pod có Toleration</td><td>Node dành riêng cho GPU workloads</td></tr>
48
+ <tr><td><strong>Resource requests</strong></td><td>Minimum CPU/memory để schedule</td><td>requests.cpu: 500m</td></tr>
49
+ </tbody>
50
+ </table>
51
+
52
+ <blockquote><p><strong>Exam tip:</strong> <strong>Taints</strong> áp lên Node (repel pods). <strong>Tolerations</strong> áp lên Pod (accept taint). Taint có effect: <strong>NoSchedule</strong> (không schedule mới), <strong>PreferNoSchedule</strong> (ưu tiên không schedule), <strong>NoExecute</strong> (evict pods đang chạy).</p></blockquote>
53
+
54
+ <h2 id="resources">2. Resource Requests & Limits</h2>
55
+
56
+ <table>
57
+ <thead><tr><th>Setting</th><th>Ảnh hưởng đến</th><th>Nếu vượt quá</th></tr></thead>
58
+ <tbody>
59
+ <tr><td><strong>requests.cpu</strong></td><td>Scheduling (scheduler dùng để chọn node)</td><td>Throttled (không bị kill)</td></tr>
60
+ <tr><td><strong>limits.cpu</strong></td><td>Cgroups CPU quota</td><td>CPU throttled</td></tr>
61
+ <tr><td><strong>requests.memory</strong></td><td>Scheduling</td><td>OOM Kill nếu vượt limit</td></tr>
62
+ <tr><td><strong>limits.memory</strong></td><td>Cgroups memory limit</td><td>Container bị <strong>OOM Kill</strong></td></tr>
63
+ </tbody>
64
+ </table>
65
+
66
+ <pre><code class="language-text">QoS Classes:
67
+ Guaranteed: requests == limits (best quality, last to be evicted)
68
+ Burstable: requests < limits (middle)
69
+ BestEffort: no requests, no limits (first to be evicted)</code></pre>
70
+
71
+ <h2 id="autoscaling">3. Auto-scaling</h2>
72
+
73
+ <table>
74
+ <thead><tr><th>Scaler</th><th>Scale gì</th><th>Metric</th></tr></thead>
75
+ <tbody>
76
+ <tr><td><strong>HPA</strong> (Horizontal Pod Autoscaler)</td><td>Số lượng Pod replicas</td><td>CPU%, Memory%, custom metrics</td></tr>
77
+ <tr><td><strong>VPA</strong> (Vertical Pod Autoscaler)</td><td>CPU/Memory requests của Pod</td><td>Actual usage history</td></tr>
78
+ <tr><td><strong>Cluster Autoscaler</strong></td><td>Số lượng nodes trong cluster</td><td>Pending Pods (unschedulable)</td></tr>
79
+ <tr><td><strong>KEDA</strong></td><td>Số replicas (to 0)</td><td>Event-driven (queue depth, Kafka)</td></tr>
80
+ </tbody>
81
+ </table>
82
+
83
+ <pre><code class="language-text">HPA integration:
84
+ metrics-server → kubelet → Node/Pod metrics
85
+
86
+ HPA controller (checks every 15s)
87
+
88
+ Scale up: replicas++ (traffic spike)
89
+ Scale down: replicas-- (traffic drops, 5 min cooldown)</code></pre>
90
+
91
+ <blockquote><p><strong>Exam tip:</strong> HPA cần <strong>metrics-server</strong> để hoạt động. VPA và HPA có thể conflict khi cùng manage một Deployment — không nên dùng cùng lúc trên cùng resource (trừ KEDA với nhiều dimension).</p></blockquote>
92
+
93
+ <h2 id="namespaces">4. Namespaces & Multi-tenancy</h2>
94
+
95
+ <p><strong>Namespaces</strong> cung cấp virtual cluster isolation: scope RBAC, ResourceQuota, NetworkPolicy, và DNS resolution.</p>
96
+
97
+ <table>
98
+ <thead><tr><th>Namespace</th><th>Purpose</th><th>Ghi chú</th></tr></thead>
99
+ <tbody>
100
+ <tr><td><code>default</code></td><td>Objects không chỉ định namespace</td><td>Dùng trong dev, không dùng prod</td></tr>
101
+ <tr><td><code>kube-system</code></td><td>Kubernetes system components</td><td>CoreDNS, kube-proxy, metrics-server</td></tr>
102
+ <tr><td><code>kube-public</code></td><td>Public, readable by all</td><td>Cluster info ConfigMap</td></tr>
103
+ <tr><td><code>kube-node-lease</code></td><td>Node heartbeat leases</td><td>Kubelet heartbeat performance</td></tr>
104
+ </tbody>
105
+ </table>
106
+
107
+ <h2 id="cheatsheet">5. 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>Scale số Pod dựa trên CPU?</td><td><strong>HPA</strong></td></tr>
113
+ <tr><td>Scale số Node trong cluster?</td><td><strong>Cluster Autoscaler</strong></td></tr>
114
+ <tr><td>Node dành riêng cho GPU, dùng gì?</td><td><strong>Taint</strong> + Pod <strong>Toleration</strong></td></tr>
115
+ <tr><td>Container bị OOM Kill, do gì?</td><td>Vượt <strong>limits.memory</strong></td></tr>
116
+ <tr><td>QoS class nào bị evict đầu tiên?</td><td><strong>BestEffort</strong></td></tr>
117
+ </tbody>
118
+ </table>
119
+
120
+ <h2 id="practice">6. Practice Questions</h2>
121
+
122
+ <p><strong>Q1:</strong> A node is tainted with <code>key=gpu:NoSchedule</code>. Which Pods can be scheduled on this node?</p>
123
+ <ul>
124
+ <li>A) Any Pod in the cluster</li>
125
+ <li>B) Pods with matching Toleration for the taint ✓</li>
126
+ <li>C) Pods in the kube-system namespace only</li>
127
+ <li>D) Pods created by cluster administrators only</li>
128
+ </ul>
129
+ <p><em>Explanation: NoSchedule taint prevents any new Pod from being scheduled on the node UNLESS the Pod specifies a matching toleration. Existing Pods are not evicted (use NoExecute for that).</em></p>
130
+
131
+ <p><strong>Q2:</strong> An application's Pods keep getting OOM-killed during traffic spikes. What is the most appropriate solution?</p>
132
+ <ul>
133
+ <li>A) Increase Pod CPU requests</li>
134
+ <li>B) Configure HPA to scale based on memory usage ✓</li>
135
+ <li>C) Move the app to a new namespace</li>
136
+ <li>D) Use a StatefulSet instead of Deployment</li>
137
+ </ul>
138
+ <p><em>Explanation: OOM kills mean memory demand exceeds limits. HPA scaling out (more Pod replicas) distributes the load, reducing per-pod memory pressure. Alternatively, increase memory limits or use VPA.</em></p>
139
+
140
+ <p><strong>Q3:</strong> Which Kubernetes component provides CPU and memory metrics that HPA uses for scaling decisions?</p>
141
+ <ul>
142
+ <li>A) kube-proxy</li>
143
+ <li>B) kube-scheduler</li>
144
+ <li>C) metrics-server ✓</li>
145
+ <li>D) etcd</li>
146
+ </ul>
147
+ <p><em>Explanation: metrics-server is an optional cluster add-on that collects resource metrics (CPU, memory) from kubelets. The HPA controller queries the metrics API exposed by metrics-server to make scaling decisions.</em></p>