Docker 101

Docker 101

Thế giới trước Docker: Kỷ nguyên của Virtualization (Ảo hóa)

Trước khi Docker ra đời, chúng ta hãy cùng nhìn lại cách mà thế giới công nghệ triển khai ứng dụng. Trước đây, công nghệ chủ đạo để chạy và quản lý ứng dụng là ảo hóa (Virtualization) thông qua Hypervisor. Virtualization, hay công nghệ ảo hóa, xuất hiện từ những năm 1960 và vẫn rất phổ biến cho đến ngày nay. Một ví dụ điển hình là việc thuê máy chủ GPU để train mô hình AI hoặc sử dụng các dịch vụ máy ảo như EC2 của AWS – tất cả đều dựa trên công nghệ ảo hóa.

Trong mô hình ảo hóa truyền thống, một server vật lý thường có ba thành phần chính: CPU, RAM và mạng (Network). Công nghệ ảo hóa cho phép chúng ta chia sẻ và tối ưu hóa các tài nguyên này, bằng cách tạo ra nhiều máy ảo (VMs) độc lập chạy trên cùng một máy chủ vật lý.

Cách hoạt động của Virtualization và những hạn chế

Trước đây, để triển khai ứng dụng, một server thường chạy nhiều máy ảo (Virtual Machines - VMs). Mỗi máy ảo được cấp phát một lượng tài nguyên riêng biệt, bao gồm CPU, RAM, và Network. Thông thường, mỗi máy ảo này sẽ phục vụ cho việc triển khai một ứng dụng duy nhất. Để đạt được điều này, công nghệ Hypervisor được sử dụng. Hypervisor là phần mềm chuyên dụng có nhiệm vụ quản lý và giám sát các máy ảo, phân chia tài nguyên một cách hợp lý.

Công nghệ này đem lại rất nhiều lợi ích vào lúc nó ra đời, giúp giảm chi phí vận hành đi rất nhiều. Tuy nhiên, mô hình này cũng tồn tại một nhược điểm: mỗi máy ảo mới đều yêu cầu cài đặt lại hệ điều hành, gây lãng phí tài nguyên đáng kể.

Sự ra đời của Containerization: Giải pháp tối ưu hơn

Để giải quyết vấn đề này, công nghệ Containerization ra đời, và Docker là một trong những nền tảng tiêu biểu. Containerization cho phép các ứng dụng chia sẻ cùng một hệ điều hành nhưng vẫn giữ được sự tách biệt giữa các môi trường, tiết kiệm tài nguyên hệ thống và tối ưu hóa hiệu quả triển khai.

Công nghệ cốt lõi: Linux Namespaces và Cgroups

Để triển khai Containerization, hai tính năng quan trọng của Linux được tận dụng là Linux Namespaces và Linux Cgroups.

Linux Namespaces

Linux Namespaces là một tính năng cốt lõi giúp các tiến trình (process) trong container hoạt động độc lập. Các namespaces giúp tạo ra các 'không gian riêng' cho từng loại tài nguyên, bao gồm:

  • PID namespace: Tạo các process tách biệt với PID riêng.
  • Network namespace: Cho phép các ứng dụng trong container sử dụng các port tùy ý mà không lo xung đột.
  • Mount namespace: Cho phép mỗi container có hệ thống file riêng (filesystem).

Để tạo một linux namespace, ta có thể dùng câu lệnh:

sudo unshare –fork –pid –mount-proc bash

Sau khi chạy, câu lệnh ps aux sẽ hiển thị một danh sách tiến trình hoàn toàn độc lập với hệ thống host.

Linux Cgroups (Control Groups)

Để kiểm soát và giới hạn tài nguyên (như CPU và bộ nhớ) cho mỗi container, chúng ta cần đến Cgroups. Cgroups là một tính năng của Linux cho phép giới hạn tài nguyên cho từng nhóm process, đảm bảo rằng mỗi container sử dụng lượng tài nguyên nằm trong mức quy định.

Docker: Đơn giản hóa tất cả

Docker thực chất là một công cụ giúp đơn giản hóa quy trình tạo và quản lý namespaces và Cgroups, làm cho việc tạo container trở nên dễ dàng và tự động. Chính vì vậy, Docker phụ thuộc vào những tính năng của Linux, và khi cài Docker trên Windows, một máy ảo Linux sẽ được tạo ra để hỗ trợ cho quá trình này.

Một ứng dụng phổ biến của Containerization mà nhiều người sử dụng là KaggleGoogle Colab. Thực chất, các notebook mà bạn sử dụng là các container chạy Jupyter Notebook, sử dụng tài nguyên từ các máy chủ GPU phía sau.