Bỏ qua điều hướng

Docker là gì? Giải thích container cho người mới bắt đầu

Docker là gì? Công cụ đóng gói ứng dụng vào container giúp vận hành ổn định trên mọi môi trường, tối ưu tài nguyên so với máy ảo.

Tuan Tran Van
10 phút đọc
Mục lục (7 phần)
  1. Docker sinh ra để giải quyết vấn đề gì?
  2. Container là gì và khác máy ảo ở chỗ nào?
  3. Image, container và registry: ba khái niệm dễ nhầm
  4. Dockerfile: công thức tạo ra một image
  5. Docker chạy như thế nào? Client, daemon và nhân Linux
  6. Khi nào nên và chưa nên dùng Docker?
  7. Tài liệu tham khảo

Docker là nền tảng mã nguồn mở đóng gói mã nguồn cùng toàn bộ phụ thuộc (dependencies) của một ứng dụng vào một đơn vị nhẹ gọi là container, để ứng dụng chạy giống hệt nhau trên mọi hạ tầng.

Trả lời thẳng câu hỏi Docker là gì: nó tách ứng dụng khỏi cơ sở hạ tầng bên dưới, giúp bạn tập trung vào logic thay vì cấu hình server.

Cách đóng gói này (containerization) mang lại tính di động cao, cho phép chạy cùng một bản build trên máy cá nhân, server staging hoặc các đám mây công cộng mà không gặp xung đột môi trường.

Một ứng dụng được đóng gói gọn trong container và chuyển nguyên vẹn giữa các môi trường khác nhau

Docker sinh ra để giải quyết vấn đề gì?

Thách thức lớn nhất trong quy trình triển khai phần mềm là sự sai lệch giữa các môi trường ứng dụng (application environment). Một hệ thống có thể vận hành tốt trên Linux của lập trình viên nhưng phát sinh lỗi khi chuyển sang Windows của kiểm thử viên do thiếu thư viện hoặc sai lệch phiên bản. Sự không nhất quán này dẫn đến tình trạng "chạy tốt trên máy tôi nhưng lỗi trên server", gây lãng phí nguồn lực cho các tác vụ cấu hình thủ công lặp lại và làm giảm hiệu suất làm việc của toàn đội ngũ.

Docker giải quyết vấn đề này bằng cách đóng gói mã nguồn và dependencies vào một đơn vị duy nhất. Hãy hình dung ứng dụng như một phi hành gia. Thay vì cố gắng thay đổi bầu khí quyển của một hành tinh xa lạ để giống Trái Đất, kỹ sư chỉ cần trang bị cho phi hành gia một bộ đồ du hành (spacesuit) chứa đầy đủ các yếu tố sinh tồn. Docker hoạt động tương tự: nó cung cấp "bộ đồ" đó, cho phép ứng dụng sống và hoạt động ổn định ở bất kỳ đâu mà không cần tái lập môi trường hệ thống bên dưới. Nhưng Docker không làm cho môi trường của bạn đúng hơn, nó chỉ làm cho môi trường đó giống nhau ở mọi nơi: một Dockerfile sai thì vẫn sai y hệt trên cả trăm máy chủ.

Container là gì và khác máy ảo ở chỗ nào?

Về mặt kỹ thuật, container là một gói phần mềm chứa mã nguồn, thư viện và mọi thành phần phụ thuộc cần thiết để ứng dụng khởi chạy. Sự khác biệt cốt lõi giữa container và máy ảo (Virtual Machine, VM) nằm ở lớp trừu tượng hóa. VM sử dụng hypervisor (phần mềm chia một máy vật lý thành nhiều máy ảo) để trừu tượng hóa phần cứng và chạy một hệ điều hành (OS) khách hoàn chỉnh trên mỗi máy ảo. Điều này khiến VM có kích thước lớn (tính bằng GB) và khởi động chậm do phải tải toàn bộ nhân hệ điều hành.

So sánh hai kiến trúc: máy ảo chạy nhiều hệ điều hành khách đầy đủ trên hypervisor, còn container dùng chung một nhân hệ điều hành của máy chủ

Ngược lại, container trừu tượng hóa ở lớp hệ điều hành: nó dùng chung nhân (kernel) của máy chủ nhưng vẫn biệt lập ở lớp người dùng. Nhờ lược bỏ OS khách, container chỉ nặng vài MB và khởi động gần như tức thì.

Tiêu chíContainerMáy ảo (Virtual Machine)
Định nghĩaGói mã chứa ứng dụng và phụ thuộcBản sao kỹ thuật số của máy vật lý
Cơ chế ảo hóaẢo hóa ở cấp độ hệ điều hànhẢo hóa hạ tầng phần cứng vật lý
Thành phần quản lýContainer Engine (Docker)Hypervisor
Kích thướcRất nhẹ (tính bằng MB)Nặng (tính bằng GB)
Khả năng mở rộngRất cao, phù hợp với microservicesThấp hơn, tốn kém tài nguyên

Trong khi hypervisor điều phối tài nguyên phần cứng cho các OS khách, container engine như Docker đóng vai trò trung gian quản lý và cấp phát tài nguyên hệ thống từ OS chủ cho các container đang thực thi. Cái giá của sự nhẹ nhàng đó nằm ngay trong chữ "dùng chung": vì mọi container xài chung một nhân, ranh giới giữa chúng mỏng hơn ranh giới giữa hai máy ảo. Đổi lại tốc độ, bạn nhận về một lớp cô lập yếu hơn.

Image, container và registry: ba khái niệm dễ nhầm

Mối quan hệ giữa image, container và registry là cốt lõi của quy trình vận hành. Docker image đóng vai trò là một bản thiết kế tĩnh, ở trạng thái chỉ đọc (read-only) và có cấu trúc phân tầng (layers) — mỗi lần bạn sửa ứng dụng, chỉ layer bị ảnh hưởng phải dựng lại. Image chứa toàn bộ mã nguồn, các cài đặt môi trường và thư viện cần thiết. Tính bất biến (immutable) của image đảm bảo rằng một khi bạn đã xây dựng thành công, nội dung của nó sẽ không thay đổi, giúp loại bỏ các lỗi phát sinh do sai lệch cấu hình giữa những lần triển khai trên các server khác nhau.

Quan hệ giữa image, container và registry: image là bản thiết kế chỉ đọc nhiều lớp, container là thực thể chạy tạo ra từ image, registry là kho để push và pull image

Container chính là thực thể thực thi (runnable instance) được khởi tạo từ một image. Nếu image là lớp dữ liệu tĩnh thì container là trạng thái động của ứng dụng. Khi một container được khởi chạy, Docker Engine sẽ thêm một lớp ghi (write layer) lên phía trên các lớp chỉ đọc của image. Lớp này cho phép container xử lý dữ liệu và thực hiện các thay đổi trong quá trình vận hành mà không làm ảnh hưởng đến bản thiết kế gốc bên dưới. Một image có thể tạo ra vô số container giống hệt nhau trên bất kỳ hạ tầng nào có cài Docker.

Để quản lý và phân phối các bản thiết kế này, bạn cần một registry. Đây là kho lưu trữ tập trung nơi các image được đẩy lên (push) hoặc kéo về (pull) phục vụ việc triển khai. Docker Hub hiện là registry mặc định, chứa các image phổ biến từ hệ điều hành đến cơ sở dữ liệu. Quy trình tiêu chuẩn thường bắt đầu bằng việc pull một image từ registry, sau đó khởi tạo nó thành một container hoạt động thực tế trên máy chủ đích.

Dockerfile: công thức tạo ra một image

Dockerfile là tệp văn bản chứa các chỉ thị để tự động hóa quá trình xây dựng một Docker image. Mỗi chỉ thị trong tệp này sẽ tạo ra một layer tương ứng trong image cuối cùng. Việc quản lý hạ tầng qua mã (Infrastructure as Code) giúp quy trình build trở nên minh bạch và dễ tái lặp.

Các chỉ thị cơ bản bao gồm: FROM (chọn base image), ENV (thiết lập biến môi trường), COPY (sao chép tệp vào image), RUN (thực thi lệnh cài đặt), EXPOSE (khai báo cổng mạng) và CMD (lệnh mặc định khi container khởi động).

dockerfile
# Sử dụng base image Alpine Linux siêu nhẹ
FROM alpine
# Thiết lập đường dẫn ứng dụng
ENV APP_HOME=/app
# Sao chép mã nguồn vào image
COPY . $APP_HOME
# Cài đặt Python 3
RUN apk add --no-cache python3
# Mở cổng 8080 cho ứng dụng
EXPOSE 8080
# Lệnh khởi chạy ứng dụng
CMD ["python3", "/app/app.py"]

Ví dụ trên cài Python vào một base image tối giản rồi chỉ định lệnh khởi chạy. Quy trình chuyển đổi từ Dockerfile sang image được thực hiện qua lệnh docker build:

bash
# Build image từ Dockerfile và gắn tag tên my-app bản v1
docker build -t my-app:v1 .

Docker chạy như thế nào? Client, daemon và nhân Linux

Docker vận hành theo kiến trúc client-server. Khi bạn thực thi lệnh qua Docker Client, tức giao diện dòng lệnh (CLI) bạn gõ vào, yêu cầu này được gửi dưới dạng REST API tới Docker Daemon (dockerd). Daemon là tiến trình chạy nền trên máy chủ, chịu trách nhiệm quản lý vòng đời của image, container, network và volume.

Kiến trúc Docker theo tầng: client gửi lệnh tới daemon, daemon quản lý image và container, bên dưới là nhân Linux với namespaces và cgroups

Dưới tầng kernel, Docker tận dụng các tính năng cô lập của nhân Linux để vận hành:

  • Namespaces: cung cấp lớp cô lập tài nguyên cho các tiến trình. Docker sử dụng các không gian tên như PID (tiến trình), Network (mạng) và Mount (hệ thống tệp) để đảm bảo container này không nhìn thấy tài nguyên của container khác.
  • Control Groups (cgroups): chịu trách nhiệm giới hạn và giám sát tài nguyên phần cứng. Tính năng này ngăn một container chiếm dụng quá mức CPU, RAM hoặc I/O, gây ảnh hưởng đến hiệu suất chung của máy chủ.

Ở phiên bản Docker Engine 29 hiện hành, kiến trúc có vài cập nhật đáng chú ý. Tính năng embedded-containerd (đang ở trạng thái thực nghiệm) cho phép chạy containerd trực tiếp bên trong tiến trình daemon. Bên cạnh đó, mount kiểu image đã thoát khỏi trạng thái thử nghiệm, và containerd image store trở thành lựa chọn mặc định cho các cài đặt mới.

Khi nào nên và chưa nên dùng Docker?

Bạn nên triển khai Docker khi xây dựng kiến trúc vi dịch vụ (microservices), nơi mỗi dịch vụ chạy độc lập để dễ mở rộng. Docker cũng đáng dùng khi cần nhất quán môi trường từ dev đến production trong một quy trình DevOps, hoặc muốn xếp nhiều ứng dụng hơn lên cùng một server để tiết kiệm chi phí tài nguyên.

Chưa nên dùng Docker nếu ứng dụng cần truy cập trực tiếp vào phần cứng đặc thù, hoặc khi sự cô lập ở mức nhân hệ điều hành của máy ảo là bắt buộc để đảm bảo an ninh.

Trong những kịch bản đó, máy ảo truyền thống cho bạn khả năng kiểm soát sâu hơn với các cấu hình OS đặc thù. Nếu phải chốt một câu cho người mới, tôi sẽ nói thế này: học Docker không phải để bỏ máy ảo, mà để bạn thôi phải dựng lại môi trường bằng tay mỗi lần đổi máy.

Tài liệu tham khảo

Chia sẻ bài viết

X / TwitterFacebookLinkedIn