Skip to main content

2. Kubernetes Concepts

Mục lục


1. Các cách thiết lập và truy cập Kubernetes Cluster

Có nhiều cách để thiết lập và truy cập một Kubernetes cluster. Có thể tự dựng từ đầu trên laptop/máy ảo của mình, dùng managed service có sẵn trên cloud provider, hoặc truy cập một playground công khai.

Với hệ thống local, các công cụ phổ biến là Docker Desktop, Minikube, và kubeadm:

  • Docker Desktop — dễ bắt đầu nhất vì đã có sẵn hỗ trợ Kubernetes tích hợp.
  • Minikube — công cụ dùng để dựng 1 instance Kubernetes duy nhất theo kiểu all-in-one.
  • kubeadm — công cụ dùng để cấu hình Kubernetes theo kiểu multi-node.

Ngoài ra còn có các phiên bản hosted sẵn trên cloud environment như GCP, AWS, hoặc Azure — chỉ cần one-click access, click 1 nút là có ngay 1 Kubernetes cluster đầy đủ để dùng, không cần tốn thời gian tự dựng.

Cuối cùng, nếu không có sẵn tài nguyên hoặc không muốn tốn công dựng riêng chỉ để học/thử nghiệm, lựa chọn tốt nhất là Playgrounds — cung cấp truy cập tức thì vào 1 Kubernetes cluster để chạy thử lệnh. Một trong số đó là KodeKloud Playgrounds, truy cập tại kodekloud.com/k8s.

💡 Hình dung như thế này: giống như chọn chỗ ở — tự dựng cluster local giống tự xây nhà (toàn quyền nhưng tốn công); dùng managed service trên cloud giống thuê nhà đã xây sẵn, chỉ việc dọn vào ở; còn Playground giống ở khách sạn vài đêm — có ngay phòng để dùng thử, không cần ký hợp đồng dài hạn.

2. Docker Desktop

Docker Desktop là giải pháp miễn phí đi kèm với Docker, có bản cài đặt cho:

  • Mac — cả chip Apple Silicon lẫn Intel.
  • Windows — cả AMD lẫn ARM.
  • Linux.

Sau khi cài và mở Docker Desktop, giao diện sẽ hiển thị toàn bộ container đang chạy cùng thông tin của chúng. Phần quan trọng nhất là Docker Desktop có sẵn Kubernetes tích hợp — chỉ cần vào Settings → mục Kubernetes, bật Kubernetes lên là có ngay một Kubernetes cluster để chạy thử ở backend.

3. Minikube

Nhắc lại các thành phần Kubernetes đã học trước đó: control plane gồm API server, etcd (key-value store), controllers, và scheduler; worker node gồm kubeletcontainer runtime.

Tự cài đặt từng thành phần này riêng lẻ trên nhiều hệ thống sẽ tốn rất nhiều thời gian và công sức. Đây là lý do Minikube gộp toàn bộ các thành phần này vào chung 1 image duy nhất, cho ra sẵn 1 Kubernetes cluster single-node đã cấu hình sẵn — giúp bắt đầu chỉ trong vài phút.

💡 Hình dung như thế này: tự cài từng thành phần Kubernetes riêng lẻ giống tự mua từng món đồ nội thất rồi tự lắp ráp; Minikube giống 1 bộ kit lắp sẵn — mọi thứ đã đóng gói chung, chỉ cần "mở hộp" là dùng được ngay.

Toàn bộ bundle này được đóng gói dưới dạng ISO image, có sẵn để tải online. Không cần tự tải ISO — Minikube cung cấp 1 executable command-line utility, tự động tải ISO image và deploy nó vào 1 virtualization platform, ví dụ Oracle VirtualBox hoặc VMware Fusion. Vì vậy máy cần có sẵn 1 hypervisor:

  • Windows → VirtualBox hoặc Hyper-V.
  • Linux → VirtualBox hoặc KVM.

Cuối cùng, để tương tác với Kubernetes cluster, cần có thêm kubectl — command-line tool bắt buộc.

Tóm lại, cần chuẩn bị đúng 3 thứ để dùng được Minikube: hypervisor đã cài, kubectl đã cài, và Minikube executable đã cài.

4. Demo: Cài đặt kubectl và Minikube

Bắt đầu tại trang kubernetes.io — vào mục Documentation, sau đó tới TasksInstall Tools. Trước khi cài Minikube, cần cài kubectl trước — command-line tool dùng để quản lý resource và cluster sau khi Minikube dựng xong. Cài kubectl trước giúp Minikube tự động cấu hình kubectl để làm việc với cluster ngay khi provision xong.

Cài kubectl trên Linux:

  • Tải bản kubectl mới nhất bằng lệnh download binary được cung cấp trên trang documentation.
  • Cấp quyền thực thi bằng chmod +x.
  • Di chuyển file vào đường dẫn /usr/local/bin để có thể gọi lệnh kubectl từ bất kỳ đâu trong hệ thống.
  • Kiểm tra bằng kubectl version — ví dụ cho ra bản 1.18.
chmod +x kubectl # cấp quyền thực thi cho file vừa tải
mv kubectl /usr/local/bin/ # đưa vào PATH — gọi được kubectl từ mọi nơi
kubectl version # xác nhận cài đúng
# Output minh họa (rút gọn)
Client Version: v1.18.0

Ngoài cách tải binary trực tiếp, còn có thể cài qua package manager tùy theo distro, hoặc theo hướng dẫn riêng cho Mac OS/Windows trên trang documentation.

Kiểm tra virtualization trước khi cài Minikube (áp dụng cho mọi OS — Linux, Windows, Mac): trên Linux, grep từ khóa VMX hoặc SVM trong file /proc/cpuinfo — nếu lệnh này cho ra output, nghĩa là virtualization đã được bật. Nếu không thấy gì, phải vào BIOS để bật thủ công (thường phải restart máy, vào BIOS tìm mục bật virtualization — có thể cần tra thêm hướng dẫn theo đúng model máy).

Cài Minikube: cần 2 điều kiện tiên quyết — đã có kubectl, và có sẵn 1 driver để chạy cluster: hoặc 1 hypervisor (như KVM/VirtualBox trên Linux), hoặc dùng thẳng Docker nếu máy đã cài sẵn — driver Docker hiện được khuyến nghị làm mặc định trên nhiều nền tảng vì khởi động nhanh hơn, không cần tốn tài nguyên dựng thêm 1 VM riêng. Demo này vẫn chọn phương án dựa trên virtual machine (VirtualBox) để minh họa: dễ xóa VM và làm lại nếu lỡ tay làm hỏng gì đó, đồng thời có thể chụp snapshot trước khi thay đổi lớn để restore lại nếu cần. VirtualBox hỗ trợ mọi hệ điều hành — Linux, Windows, OS X — và vẫn là lựa chọn hợp lý trên Windows Home, nơi không dùng được Hyper-V.

Sau khi tải và cài VirtualBox (bản Debian package trên Linux) và mở thử GUI (chưa có VM nào chạy — Minikube sẽ tự tạo VM khi cần), tiếp tục cài Minikube utility: tải bản mới nhất bằng curl, gán quyền thực thi, rồi thêm vào /usr/local/bin (tương tự bước cài kubectl).

Khởi tạo cluster: chạy lệnh minikube start kèm tham số chỉ định driver ảo hóa cần dùng — ở đây là virtualbox (tên driver đúng của VirtualBox). Khi chạy, Minikube sẽ:

  1. Tải ISO image của Minikube.
  2. Dùng ISO đó để provision 1 VM trên VirtualBox.
  3. Tải về Kubernetes version 1.18.3 cùng các binary cần thiết — đây là bản mới nhất tại thời điểm quay video; nếu bạn tự làm theo hôm nay, Minikube sẽ cài mặc định 1 bản Kubernetes mới hơn nhiều.
minikube start --driver=virtualbox # chỉ định rõ driver ảo hóa cần dùng
minikube status # kiểm tra cluster đã sẵn sàng chưa
# Output minh họa
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

Trong VirtualBox GUI có thể thấy 1 VM tên minikube đang chạy, cấu hình 2 CPU2 GB RAM. Output của minikube status xác nhận host, kubelet, apiserver, và kubeconfig đều đang ở trạng thái running/configured — nếu gặp vấn đề lúc cài, đây là lệnh đầu tiên nên chạy để kiểm tra.

Minikube Setup Architecturekubectl (your machine)minikube start --driver=...VirtualBox VM (used in this demo)Docker driver (recommended today)Single-node Cluster — node: minikubecontrol planekubelet + container runtimeBoth drivers lead to the same single-node cluster —the difference is whether a separate VM (VirtualBox) is needed or not (Docker).

Thử nghiệm nhanh cluster vừa dựng (theo tutorial "What's next" trên trang documentation).

Xác nhận node. Cluster phải là single-node, tên node minikube, trạng thái Ready, chạy Kubernetes 1.18:

kubectl get nodes
# Output minh họa
NAME STATUS ROLES AGE VERSION
minikube Ready master 9s v1.18.0

Tạo Deployment thử nghiệm.

kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
# Output minh họa
deployment.apps/hello-minikube created
kubectl get deployments
# Output minh họa
NAME READY UP-TO-DATE AVAILABLE AGE
hello-minikube 1/1 1 1 22s

Đủ 1/1 Pod ready, deployment đang chạy đúng như mong đợi.

Expose Deployment thành Service. Expose xong, lấy URL của service để mở thử trên trình duyệt, xác nhận ứng dụng truy cập được:

kubectl expose deployment hello-minikube --type=NodePort --port=8080
# Output minh họa
service/hello-minikube exposed

Dọn dẹp — xóa Service và xóa Deployment:

kubectl delete service hello-minikube
kubectl delete deployment hello-minikube
# Output minh họa
service "hello-minikube" deleted
deployment.apps "hello-minikube" deleted

Deployment sẽ ở trạng thái Terminating vài giây trước khi biến mất hẳn khỏi trang.

(Command/output ở mục này là minh họa theo đúng flow "What's next" của tài liệu Minikube chính thức — tên deployment/image cụ thể không được đọc thành lời trong video gốc, chỉ mô tả các bước ở mức khái quát.)

5. Pods là gì?

Giả định trước khi tìm hiểu Pod: ứng dụng đã được build thành Docker image và có sẵn trên 1 Docker repository (như Docker Hub) để Kubernetes kéo về; Kubernetes cluster (single-node hoặc multi-node đều được) đã dựng xong và mọi service đang chạy.

Kubernetes không deploy container trực tiếp lên worker node — container luôn được đóng gói bên trong 1 object gọi là Pod. Pod là object nhỏ nhất có thể tạo trong Kubernetes, và là 1 instance duy nhất của ứng dụng.

Trường hợp đơn giản nhất: cluster single-node với 1 Pod chứa 1 container ứng dụng. Khi lượng user tăng cần scale, không thêm container mới vào cùng Pod cũ — mà tạo hẳn 1 Pod mới chứa 1 instance mới của ứng dụng, chạy trên cùng node hoặc node khác nếu node hiện tại hết tài nguyên (lúc đó thêm node mới vào cluster). Nói cách khác: Pod và container thường có quan hệ 1-1 — scale lên = tạo Pod mới, scale xuống = xóa Pod, chứ không phải nhồi thêm container vào 1 Pod có sẵn.

Vậy có bị giới hạn chỉ 1 container mỗi Pod không? Không — 1 Pod có thể chứa nhiều container, nhưng thường không phải nhiều container cùng loại (dùng để scale). Trường hợp hay gặp hơn: 1 container phụ (helper container) làm nhiệm vụ hỗ trợ cho container ứng dụng chính (ví dụ xử lý dữ liệu người dùng nhập vào, xử lý file người dùng upload...). Khi đó 2 container này nằm chung 1 Pod — được tạo cùng lúc, chết cùng lúc (cùng "fate"), giao tiếp trực tiếp với nhau qua localhost vì dùng chung network namespace, và chia sẻ chung storage.

Anatomy of a PodWorker Node: minikubePodApp Container(e.g. nginx)Helper Container(optional)localhostShared Network NamespaceShared Storage VolumeContainers in the same Pod share network + storage, same "fate" —created together, destroyed together.

💡 Hình dung theo cách khác — nếu không có Kubernetes: giả sử chỉ dùng Docker thuần, chạy docker run để deploy app, cần thêm container phụ hỗ trợ khi app phức tạp lên. Lúc đó phải tự tay: giữ 1 bảng map container app nào nối với container helper nào, tự thiết lập network connectivity bằng link/custom network, tự tạo shareable volume và maintain map đó, tự theo dõi container app còn sống hay không để tắt helper theo, và tự deploy helper mới mỗi khi có container app mới. Với Pod, Kubernetes tự làm hết những việc này — chỉ cần khai báo Pod gồm những container nào, các container trong cùng Pod mặc định đã có sẵn chung storage, chung network namespace, và chung "fate" (tạo/hủy cùng lúc).

Ngay cả khi ứng dụng đơn giản, chỉ cần 1 container, Kubernetes vẫn yêu cầu tạo Pod — về lâu dài điều này giúp ứng dụng sẵn sàng cho thay đổi kiến trúc/scale sau này. Multi-container Pod là trường hợp hiếm gặp — khóa học này chủ yếu dùng 1 container / 1 Pod.

Cách deploy Pod: lệnh kubectl run (đã học trước đó) thực chất tạo 1 Pod rồi deploy 1 instance của Docker image chỉ định — ví dụ image NGINX — bằng tham số image. Image phải tồn tại trên Docker Hub (public) hoặc private repository trong tổ chức.

Xem danh sách Pod bằng kubectl get pods — Pod ở trạng thái ContainerCreating rồi chuyển sang Running. Lưu ý: ở bước này chưa cấu hình để user bên ngoài truy cập được NGINX web server — chỉ truy cập được nội bộ từ trong node; phần networking/services để làm việc này sẽ học ở lecture sau.

6. Demo: Deploy Pod đầu tiên

Deploy Pod đầu tiên lên Minikube cluster (giả định đã có sẵn kubectl từ demo cài đặt trước đó) bằng lệnh:

kubectl run nginx --image=nginx

Trong đó nginx đầu tiên là tên Pod (đặt tùy ý), còn --image=nginx chỉ định tên Docker image cần dùng — tên image bắt buộc phải tồn tại trên Docker Hub hoặc container registry khác (có thể kèm thêm tag, hoặc trỏ tới registry khác nếu image không nằm trên Docker Hub).

Kiểm tra bằng kubectl get pods.

kubectl get pods
# Output minh họa
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 18s
  • NAME: nginx.
  • STATUS: Running.
  • READY: 1/1 — số container đang ở trạng thái sẵn sàng trên tổng số container trong Pod.
  • RESTARTS/AGE: số lần restart và thời gian Pod đã chạy.

Xem chi tiết hơn bằng kubectl describe pod nginx — cung cấp nhiều thông tin hơn hẳn get:

kubectl describe pod nginx
# Output minh họa (rút gọn) — chỉ giữ lại field liên quan tới nội dung đang giải thích; output thật còn nhiều field khác như labels tự động, resource limits, volume mounts...
Name: nginx
Namespace: default
Node: minikube/192.168.99.100
Labels: run=nginx
Status: Running
IP: 172.16.0.3
Containers:
nginx:
Image: nginx
State: Running
Ready: True
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 20s default-scheduler Successfully assigned default/nginx to minikube
Normal Pulling 19s kubelet, minikube Pulling image "nginx"
Normal Pulled 14s kubelet, minikube Successfully pulled image "nginx"
Normal Created 14s kubelet, minikube Created container nginx
Normal Started 14s kubelet, minikube Started container nginx
  • Tên Pod, các label được gán tự động khi chạy kubectl run.
  • Node được gán vào — ở đây là node minikube (single-node cluster) — kèm địa chỉ IP của node.
  • Địa chỉ IP riêng của Pod — ví dụ 172.16.0.3 (chi tiết về IP sẽ học kỹ hơn ở phần networking).
  • Container đang chạy — chỉ 1 container dùng image nginx (Pod nhiều container sẽ liệt kê hết ở đây).
  • Mục Events ở cuối output: log các bước Pod đã trải qua — gán vào node minikube, vào phase Pulling (kéo image nginx thành công từ Docker Hub), rồi container nginx được tạo và khởi động.

Kiểm tra mở rộng bằng -o wide — cho thêm thông tin node đang chạy Pod và địa chỉ IP nội bộ của Pod (mỗi Pod có 1 IP nội bộ riêng trong cluster, chi tiết học sau):

kubectl get pods -o wide
# Output minh họa
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 45s 172.16.0.3 minikube <none> <none>

Đây là demo nhanh minh họa cách chạy 1 Pod trên môi trường Minikube. Lecture tiếp theo sẽ học cách tạo Pod bằng YAML definition file.

7. YAML là gì?

Phần còn lại của khóa học phụ thuộc hoàn toàn vào YAML, nên nếu chưa từng dùng YAML thì nên học kỹ phần này trước khi đi tiếp. Nếu đã quen các định dạng dữ liệu khác như XML hay JSON thì sẽ tiếp thu rất nhanh — còn nếu chưa quen cái nào trong số này cũng không sao, sẽ quen dần qua các bài thực hành đi kèm khóa học.

YAML dùng để biểu diễn dữ liệu — trong trường hợp này là configuration data. Cùng 1 dữ liệu có thể biểu diễn theo 3 định dạng khác nhau: XML, JSON, và YAML — nội dung giống nhau, chỉ khác cú pháp.

💡 Hình dung như thế này: YAML giống 1 bản dàn ý (outline) văn bản — mỗi cấp thụt vào tương ứng với 1 mục con thuộc về đúng mục cha ngay phía trên nó. Viết sai 1 cấp thụt trong dàn ý cũng y hệt việc gõ sai số khoảng trắng trong YAML: mục con bị "trôi" sang thuộc nhầm mục khác, dù nhìn qua vẫn tưởng đúng.

Key-value pair

Dạng đơn giản nhất trong YAML là key-value pair — key và value cách nhau bằng dấu hai chấm:

fruit: apple
vegetable: carrot
liquid: water
meat: chicken

Lưu ý bắt buộc: sau dấu : phải có 1 dấu cách để phân biệt key và value.

Array / List

Để biểu diễn 1 danh sách, khai báo key rồi dấu hai chấm, sau đó liệt kê từng phần tử trên dòng riêng, mỗi dòng bắt đầu bằng dấu -:

fruits:
- apple
- carrot

Dấu - cho biết đây là 1 phần tử của array.

Dictionary

Dictionary là tập hợp các property được gộp chung dưới 1 item. Ví dụ dictionary biểu diễn thông tin dinh dưỡng của quả chuối — gồm 3 property calories, fat, carbs:

banana:
calories: 105
fat: 0.4
carbs: 27

Khoảng trắng (indentation) là yếu tố sống còn trong dictionary: các property thuộc cùng 1 item phải thụt vào đúng số khoảng trắng bằng nhau để được coi là cùng cấp, thuộc về item đó.

Nếu thụt sai — ví dụ fatcarbs bị thụt thêm 1 cấp nữa so với calories — chúng sẽ bị hiểu nhầm là thuộc về calories chứ không phải thuộc banana nữa:

banana:
calories: 105
fat: 0.4
carbs: 27

calories đã có sẵn 1 giá trị trực tiếp (105), không thể vừa có giá trị trực tiếp vừa làm key cha cho 1 map con — kết quả là lỗi cú pháp "mapping values are not allowed here". Chỉ được chọn 1 trong 2: hoặc gán giá trị trực tiếp, hoặc làm map — không thể có cả hai. Chỉ 1 khoảng trắng thừa, cả ý nghĩa đổi khác hẳn.

Lồng nhiều cấp: list chứa dictionary chứa list

YAML có thể lồng sâu hơn nữa: 1 list các loại trái cây — ví dụ banana và grapes — nhưng mỗi phần tử trong list đó lại là 1 dictionary chứa thông tin dinh dưỡng riêng của loại trái cây đó.

Case study: biểu diễn dữ liệu về 1 chiếc xe

Tất cả các định dạng nói trên (XML, JSON, YAML) đều dùng để biểu diễn dữ liệu — có thể là dữ liệu về nhân viên trong 1 công ty, học sinh trong 1 trường học, hay xe trong 1 hãng sản xuất ô tô — bất kỳ loại dữ liệu nào.

Lấy ví dụ 1 chiếc xe: đây là 1 object đơn, có các property như color, model, transmission, price. Để lưu nhiều property của 1 object đơn, dùng dictionary:

color: white
model: mustang
transmission: manual
price: 20000

Có thể lồng sâu hơn: nếu cần tách model thành nameyear riêng, biến model từ 1 giá trị đơn thành 1 dictionary con:

color: white
model:
name: mustang
year: 2018
transmission: manual
price: 20000

Đây chính là dictionary lồng trong dictionary.

Giờ nếu muốn lưu tên của nhiều chiếc xe — cùng 1 loại object lặp lại nhiều lần — dùng list, vì chỉ lưu mỗi tên nên đây là list các string đơn giản:

cars:
- mustang
- camaro
- corvette

Nhưng nếu muốn lưu đầy đủ thông tin (color, model, transmission, price) của từng chiếc xe, chuyển từ list các string sang list các dictionary — mỗi phần tử trong array giờ là 1 dictionary đầy đủ thay vì chỉ 1 cái tên:

cars:
- name: mustang
color: white
transmission: manual
- name: camaro
color: red
transmission: automatic

Đây chính là cách biểu diễn thông tin của nhiều xe trong cùng 1 file YAML, bằng list of dictionaries.

Ghi nhớ trước khi vào bài thực hành

  • Dictionary là unordered collection, còn list là ordered collection. Nếu bạn khai báo 2 dictionary cùng property nhưng khác thứ tự (vd fat trước carbs, hay ngược lại), YAML vẫn coi 2 dictionary đó là giống nhau — miễn giá trị từng property khớp nhau, thứ tự không quan trọng.
  • Ngược lại, list/array có thứ tự[apple, banana][banana, apple]2 list khác nhau, vì vị trí phần tử khác nhau.
  • Dòng nào bắt đầu bằng dấu # sẽ tự động bị bỏ qua, được coi là comment.

Nguồn tham khảo

Nguồn gốc: Khóa "Kubernetes for the Absolute Beginners - Hands-on Tutorial" — bài "Kubernetes Setup - Introduction and Minikube", "Demo - Minikube-Setup", "Pods", "Demo - Pods" (module "Kubernetes Concepts"), và bài giới thiệu YAML (module "YAML Introduction"), nền tảng KodeKloud.

Đính chính/cập nhật (fact-check):

  • Driver Docker hiện được khuyến nghị làm mặc định cho Minikube trên hầu hết nền tảng (Linux/macOS); VirtualBox chỉ còn là lựa chọn thay thế, chủ yếu hữu ích trên Windows Home không dùng được Hyper-V — 2026, minikube drivers docs
  • Bản Kubernetes stable mới nhất hiện tại là 1.36.2 (09/06/2026); "1.18.3" trong video chỉ là bản mới nhất tại thời điểm quay — 2026, kubernetes.io/releases
  • kubectl run <name> --image=<image> chỉ tạo Pod (không tạo Deployment), không đổi kể từ Kubernetes 1.18 tới nay — 2026, kubectl run reference