Docker for Backend & AI Engineers
Trang chủ / Module 1
📦 Module 1 / 12 · 1 tuần

Container Fundamentals — Vì sao Container, Kiến trúc Docker

Container khác VM thế nào, namespaces/cgroups là gì, kiến trúc client-daemon-registry của Docker, image vs container.

ContainerKiến trúc
📌 Vì sao module này quan trọng

Docker đã trở thành hạ tầng mặc định cho gần như mọi thứ trong 3 khoá học trước (FastAPI service, Airflow, cluster giả lập, model serving) — nhưng nếu chỉ copy-paste Dockerfile mà không hiểu container thực chất là gì, bạn sẽ luôn gặp khó khi debug một container "chạy được trên máy tôi nhưng không chạy trên server". Module này xây nền tảng khái niệm đúng trước khi chạm vào bất kỳ câu lệnh nào.

🎯 Mục tiêu học tập

  • Giải thích được sự khác nhau giữa container và máy ảo (VM) ở mức kiến trúc hệ điều hành
  • Hiểu vai trò của Linux namespaces và cgroups — cơ chế thực sự đứng sau "container"
  • Mô tả được kiến trúc Docker: Client, Daemon (dockerd), Registry, Image, Container
  • Phân biệt rõ Image (bản thiết kế bất biến) và Container (thực thể đang chạy từ image)

Container vs Máy ảo (VM) — khác nhau ở đâu

Máy ảo ảo hoá toàn bộ phần cứng, mỗi VM chạy một hệ điều hành khách (guest OS) đầy đủ riêng — nặng (hàng GB), khởi động chậm (phút). Container chia sẻ chung kernel của hệ điều hành host, chỉ đóng gói riêng ứng dụng và các thư viện phụ thuộc — nhẹ (thường vài chục-vài trăm MB), khởi động gần như tức thì (giây, đôi khi mili-giây). Đây là lý do bạn có thể chạy hàng chục container trên cùng một máy mà một máy chỉ chạy được vài VM.

Đặc điểmMáy ảo (VM)Container
Ảo hoáToàn bộ phần cứng (qua hypervisor)Tiến trình hệ điều hành (qua kernel host)
Kích thướcHàng GB (cả 1 OS)Hàng chục-trăm MB
Thời gian khởi độngPhútGiây hoặc nhanh hơn
Cô lập (isolation)Mạnh (kernel riêng)Yếu hơn (chung kernel host)

Namespaces & cgroups — cơ chế thật đứng sau "container"

Docker không phát minh ra công nghệ container — nó đóng gói và làm dễ dùng 2 tính năng đã có sẵn trong Linux kernel:

  • Namespaces: cô lập "góc nhìn" của một tiến trình về hệ thống — mỗi container có namespace riêng cho process ID (PID), network (địa chỉ IP/port riêng), mount point (hệ thống file riêng), hostname (UTS)... khiến tiến trình bên trong container "tưởng" nó đang chạy một mình trên cả hệ thống, dù thực tế đang chia sẻ kernel với các container khác.
  • cgroups (control groups): giới hạn và đo lường tài nguyên (CPU, memory, I/O) mà mỗi container được phép dùng — đây là cơ chế đứng sau các tham số quen thuộc như --memory, --cpus khi chạy container.

Hiểu điều này giải thích một hệ quả quan trọng: vì chung kernel với host, một container trên Linux không thể chạy image được build cho kernel Windows và ngược lại — khác hẳn VM, vốn ảo hoá hoàn toàn nên chạy được bất kỳ OS nào.

Kiến trúc Docker: Client — Daemon — Registry

  • Docker Client (CLI): công cụ dòng lệnh bạn gõ lệnh docker run, docker build — gửi yêu cầu tới daemon qua REST API (thường qua Unix socket local).
  • Docker Daemon (dockerd): tiến trình nền thực sự quản lý image, container, network, volume — đây là nơi công việc thật diễn ra, Client chỉ là giao diện gửi lệnh.
  • Registry: kho lưu trữ và phân phối image (Docker Hub là registry công khai mặc định; Module 9 sẽ nói về registry riêng cho công ty/dự án).

Trên macOS/Windows, "Docker Desktop" thực chất chạy 1 máy ảo Linux nhẹ ẩn bên dưới để có kernel Linux cho daemon hoạt động — vì bản chất container Linux cần kernel Linux, dù bạn đang dùng hệ điều hành khác.

Image vs Container — bản thiết kế và thực thể đang chạy

Image là một bản snapshot chỉ-đọc (read-only), bất biến, chứa toàn bộ file hệ thống cần thiết để chạy ứng dụng (giống một "class" trong lập trình hướng đối tượng). Container là một thực thể đang chạy được tạo ra từ image, có thêm một lớp ghi-được (writable layer) nằm trên các lớp chỉ-đọc của image (giống một "instance" được khởi tạo từ class) — nhiều container có thể chạy đồng thời từ cùng 1 image, mỗi container có lớp ghi riêng, không ảnh hưởng lẫn nhau.

# Image là "bản thiết kế" — liệt kê các image đã tải về
docker images

# Container là "thực thể đang chạy" (hoặc đã dừng) — liệt kê container
docker ps -a

# Tạo và chạy 1 container mới từ image nginx
docker run -d --name my-nginx -p 8080:80 nginx:latest

🏋️ Bài tập thực hành

Khảo sát vòng đời Container đầu tiên

Cài đặt Docker Desktop (hoặc Docker Engine trên Linux). Chạy 1 container từ image nginx, dùng docker ps xem nó đang chạy, docker exec -it vào bên trong container để khảo sát hệ thống file, sau đó dừng và xoá container. Chạy lệnh docker inspect trên container đó (trước khi xoá) và tìm phần "State" và "NetworkSettings" — ghi lại 3 thông tin bạn thấy hữu ích nhất khi debug sau này.

📚 Tài nguyên học tập

✅ Tự đánh giá hoàn thành

  • Giải thích được sự khác nhau giữa container và VM cho người khác nghe hiểu
  • Mô tả được vai trò của namespaces và cgroups
  • Vẽ được sơ đồ kiến trúc Client-Daemon-Registry
  • Phân biệt rõ Image và Container, biết khi nào dùng từ nào cho đúng