Giao diện
Module 4: Persistence & Networking (Lưu trữ và Mạng lưới)
🎓 Instructor Profile
Kỹ sư Raizo (Phó CTO HPN) - Chuyên gia hệ thống Linux & Storage. Sẽ giải thích vì sao dữ liệu của bạn "bay màu" và cách giữ nó lại vĩnh viễn với Giáo sư Tom.
Xin chào! Nếu Container là "Vô thường" (Ephemeral) - sinh ra rồi mất đi như những đám mây, thì Dữ liệu (Networking & Storage) chính là mặt đất vững chãi. Để xây dựng hệ thống bền vững, bạn phải biết cách "khoan lỗ" kết nối Container với thế giới bên ngoài.
☁️ Phần 1: The Ephemeral Problem (Vấn đề "Phù du")
Mặc định, mọi dữ liệu sinh ra bên trong Container đều được lưu ở một lớp gọi là Writable Layer.
- Khi bạn
docker stopcontainer: Dữ liệu vẫn còn. - Khi bạn
docker rmcontainer: Toàn bộ dữ liệu BIẾN MẤT vĩnh viễn. 💀
Kiến trúc Layers
Hãy hình dung Container giống như một chồng bánh kếp:
- Image Layers (Read-only): Là phần cốt lõi bất biến (Ubuntu, Node.js binaries...).
- Container Layer (Read-write): Là lớp mỏng trên cùng nơi ứng dụng ghi log, tạo file tạm. Khi xóa container, lớp này bị hủy.
👉 Nhu cầu: Chúng ta cần một cơ chế lưu trữ độc lập với vòng đời của Container.
💾 Phần 2: The Storage Trinity (Bộ ba Lưu trữ)
Docker cung cấp 3 cách để "mount" (gắn) dữ liệu vào container.
1. Volumes (Khuyên dùng cho Database) 🏆
Là khu vực được Docker quản lý và isolat hóa hoàn toàn trên máy Host (/var/lib/docker/volumes/...).
- Ưu điểm:
- Hiệu năng cao nhất (Tư duy @[/db-expert]): Vượt qua layers của filesystem ảo.
- An toàn: Các tiến trình khác trên Host khó can thiệp bậy bạ.
- Dễ dàng backup/migration.
- Best Practice: Dùng cho Database (Postgres, MySQL, Redis data).
2. Bind Mounts (Khuyên dùng cho Dev) 🛠️
Ánh xạ trực tiếp một thư mục từ máy Host vào Container.
- Ví dụ: Map thư mục code
./srccủa bạn vào/app/srcbên trong container. - Tính năng: Hot-reload. Bạn sửa code trên VS Code -> Container nhận thấy thay đổi và cập nhật ngay lập tức.
- Nhược điểm: Hiệu năng thấp hơn Volumes, phụ thuộc vào cấu trúc file của Host OS.
🚫 Production Warning
Tuyệt đối KHÔNG dùng Bind Mount cho Database khi chạy trên Production. Sự khác biệt về File System (NTFS vs ext4) có thể gây lỗi corrupt dữ liệu cực kỳ nguy hiểm.
3. tmpfs Mounts (Bộ nhớ tạm) ⚡
Lưu trữ trực tiếp trên RAM của máy Host.
- Đặc điểm: Siêu nhanh, nhưng mất dữ liệu khi tắt container (hoặc restart máy).
- Ứng dụng: Lưu cache session, lưu mật khẩu tạm thời (security purpose).
🛡️ Phần 3: The Permission Nightmare (Cơn ác mộng phân quyền)
Đây là kiến thức Deep Tech mà ít tutorial nhắc tới.
Vấn đề:
- Container thường chạy với user
root(UID 0). - Máy Host của bạn (đặc biệt là Linux) chạy với user thường (UID 1000).
Khi bạn dùng Bind Mount, container (UID 0) ghi file ra Host -> File đó sẽ thuộc quyền sở hữu của root. 👉 Hậu quả: Bạn (UID 1000) không thể sửa/xóa file log/data do container tạo ra. Bị lỗi Permission Denied.
Giải pháp (Tư duy @[/security-scan]):
- User Remapping: Cấu hình Docker Daemon để map UID 0 trong container thành UID 1000 ngoài Host.
- Entrypoint
chown: Viết script khởi động container tự độngchownquyền sở hữu thư mục data về đúng user mong muốn.
🔌 Phần 4: Networking Modes (Các chế độ mạng)
Làm sao các container nói chuyện với nhau và với Internet?
1. Bridge Network (Mặc định) 🌉
Mỗi container được cấp một IP riêng trong dải mạng ảo (VD: 172.17.0.2, 172.17.0.3). Chúng giao tiếp qua một "cây cầu ảo" (docker0).
- Ưu điểm: Cô lập tốt.
- Kết nối: Cần dùng Port Mapping (
-p 8080:80) để Host truy cập được.
2. Host Network 🚀
Container dùng chung card mạng với máy Host.
- Ưu điểm: Hiệu năng mạng cực cao (Tư duy @[/performance]), loại bỏ overhead của NAT/Bridge.
- Nhược điểm: Dễ bị đụng độ Port. Nếu máy Host đã chạy Nginx port 80, container không thể chạy port 80 nữa.
- Lưu ý: Chỉ hoạt động trên Linux.
3. None Network 🔒
Cắt đứt toàn bộ kết nối mạng. Container "tự kỷ".
- Ứng dụng: Các tác vụ xử lý dữ liệu nhạy cảm cần bảo mật tuyệt đối, không cần Internet.
📝 Phần 5: Syntax & Practice (Cú pháp & Thực hành)
Ví dụ cấu hình docker-compose.yml chuẩn mực:
yaml
version: "3.8"
services:
# --- Database (Dùng Named Volume) ---
db:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
volumes:
- db_data:/var/lib/mysql # 📦 Persist Data an toàn
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASS}
# --- Backend API (Dùng Bind Mount) ---
api:
build: .
volumes:
- ./src:/app/src # 🛠️ Hot-reload code
ports:
- "3000:3000"
# Khai báo Volume
volumes:
db_data:So sánh -v và --mount
-v ./src:/app: Cú pháp cũ, ngắn gọn. Rất phổ biến.--mount type=bind,source=./src,target=/app: Cú pháp mới, dài dòng nhưng rõ ràng (explicit).
👉 Lời khuyên: Dùng -v cho gọn, trừ khi bạn làm cho Docker Swarm.
🏆 Challenge: The Immortal Data (Dữ liệu Bất tử)
Nhiệm vụ: Chứng minh sức mạnh của Volume.
- Chạy container MySQL với volume:
docker run -d -v my-sql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret --name db-test mysql:8. - Vào container tạo bảng
Users, thêm dòng tên bạn vào (INSERT INTO Users...). - Xóa sạch container:
docker rm -f db-test. - Chạy lại container mới, gắn đúng volume cũ (
my-sql-data). - Query lại dữ liệu. Nếu tên bạn vẫn còn đó -> Chúc mừng, bạn đã nắm giữ sự vĩnh hằng! 🎉