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.
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ểm | Má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ước | Hàng GB (cả 1 OS) | Hàng chục-trăm MB |
| Thời gian khởi động | Phút | Giâ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,--cpuskhi 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
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
-
Docker — Documentation (tổng)Cổng tài liệu chính thức DockerDocs
-
Docker — What is a container?Giải thích chính thức khái niệm containerBài viết
-
Docker — Docker overview & architectureTổng quan kiến trúc Docker (client/daemon/registry)Docs
✅ 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