Docker hóa ra lại kỳ lạ đến vậy: Góc nhìn từ người tự viết container runtime

Công nghệ22 tháng 10, 2026·4 phút đọc

Một lập trình viên tự xây dựng container runtime để giải trí và phát hiện ra nhiều điều bất ngờ về Docker: container thực chất chỉ là tiến trình bị giới hạn, không có tính năng kernel Linux nào tên là "container", và runc phải dùng thủ thuật kỳ quặc vì Go không hỗ trợ fork đúng cách.

Docker hóa ra lại kỳ lạ đến vậy: Góc nhìn từ người tự viết container runtime

Docker được hàng triệu lập trình viên sử dụng mỗi ngày, nhưng ít ai thực sự hiểu nó hoạt động ra sao bên dưới lớp giao diện thân thiện. Một lập trình viên quyết định tự viết container runtime để giải trí và nhận ra Docker ẩn chứa nhiều điều kỳ lạ.

Dưới đây là những phát hiện thú vị được chia sẻ trên diễn đàn Hacker News, đáng để bất kỳ ai làm việc với DevOps hay container cũng nên biết.

Container không phải máy ảo — chúng chỉ là tiến trình

Khác với máy ảo (VM), container thực chất chỉ là các tiến trình bình thường bị áp đặt những giới hạn đặc biệt. Kernel của bạn vẫn đang chạy tiến trình đó thật sự.

Nếu biết tìm đúng chỗ, bạn hoàn toàn có thể thấy tiến trình container ngay trong thư mục /proc.

Điều này giải thích vì sao container khởi động nhanh đến vậy so với máy ảo — không có hệ điều hành nào được boot lại cả.

Không hề có tính năng kernel nào tên là "container"

Đây có lẽ là phát hiện gây sốc nhất. Linux không có một tính năng đơn lẻ nào được gọi là "container". Thay vào đó, container thực chất là sự kết hợp của khoảng 5 tính năng kernel Linux khác nhau khoác chung một lớp áo:

  • Namespaces: che giấu những gì host và container có thể nhìn thấy
  • Cgroups: giới hạn tài nguyên mà container được sử dụng
  • Networking: một mớ "phép thuật" mạng phức tạp để cô lập network của container
  • Và một số cơ chế bảo mật, phân quyền khác

Image chỉ là những thư mục

Một image Docker thực chất chỉ là một thư mục mà Docker đặt ở đâu đó, rồi gọi chroot (hoặc pivot_root) để biến thư mục đó thành thư mục gốc mới cho tiến trình container.

Khi bạn chạy lệnh docker run -it --rm ubuntu /bin/bash, Docker sẽ thực hiện một chuỗi thao tác: tải image, tạo namespace, thiết lập cgroup, chuyển root sang thư mục image và cuối cùng là chạy shell bên trong.

runc và những lựa chọn thiết kế "trái khoáy" của Go

Container runtime của Docker là runc, được viết bằng Go. Nhưng Go có những đặc điểm khiến nó không thực sự phù hợp với vai trò này:

  • Go runtime chạy đa luồng (multi-threaded) theo mặc định. Đây là tính năng hay, nhưng nhiều syscall Linux mà container runtime cần gọi lại phải được thực thi trong môi trường đơn luồng. Vì vậy runc phải có một module C "điên rồ" chạy trước khi Go runtime khởi tạo chỉ để gọi được những syscall đó.

  • Go không có fork thực sự. Lệnh fork trong Go chỉ nhân bản luồng chính, trở thành một cái bẫy nguy hiểm. Nhưng container runtime lại rất cần fork để thiết lập các giới hạn rồi mới exec tiến trình thật. Cách lách của runc là exec chính /proc/self/exe với một tham số dòng lệnh đặc biệt để giả lập hành vi fork.

Daemon chạy quyền root và câu chuyện bảo mật

Nếu bạn chạy Docker trên macOS, rất dễ bỏ qua chi tiết này: Docker daemon thường chạy với quyền root, vì nhiều API kernel Linux mà runtime cần dùng yêu cầu quyền cao nhất.

Điều này khiến bảo mật container trở thành một bài toán cực kỳ khó. Tình hình đã được cải thiện trong thời gian gần đây, nhưng vẫn còn một ngoại lệ lớn: networking. Nếu chạy container runtime không cần root (rootless), gần như phải tái triển khai toàn bộ network stack trong không gian người dùng mới có được các tính năng tương đương.

Bài học rút ra

Việc tự viết lại một phiên bản của công cụ mình dùng hàng ngày là cách học cực kỳ hiệu quả. Dù mới chỉ bắt đầu, tác giả đã hiểu về Docker nhiều hơn hẳn so với trước đây.

Với cộng đồng lập trình viên Việt Nam — những người ngày càng làm việc nhiều với Docker, Kubernetes và các nền tảng cloud — việc hiểu rõ bản chất bên dưới của container sẽ giúp debug hiệu quả hơn, cấu hình bảo mật tốt hơn và tránh được những cái bẫy tưởng chừng như vô hình.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗