Chia sẻ đam mê công nghệ
Giải thích

Docker mặc định chạy bằng quyền root: khi nào nên chuyển sang Rootless?

Docker tiện cho homelab, nhưng daemon mặc định có quyền root trên Linux. Rootless mode thu hẹp hậu quả nếu container gặp sự cố, đổi lại một số cổng mạng và tính năng quản lý tài nguyên cần cấu hình thêm.

Tóm tắt nhanh

  • Trên Linux, Docker daemon mặc định chạy với quyền root; container do daemon này quản lý cũng có thể chạy bằng root nếu image không đặt người dùng khác.
  • Container chia sẻ kernel với máy chủ, nên cấu hình sai hoặc lỗ hổng có thể khiến ảnh hưởng vượt khỏi container.
  • Rootless mode chạy cả daemon lẫn container trong user namespace của tài khoản thường, nhưng có giới hạn về cổng dưới 1024, lưu trữ và một số tính năng.

Docker mặc định vận hành daemon bằng quyền root trên Linux, khiến một container bị cấu hình sai có thể gây hậu quả lớn hơn nhiều so với phạm vi ứng dụng bên trong nó. Với máy homelab thường xuyên thử image từ nhiều dự án, Rootless mode giảm quyền của cả daemon lẫn container; đổi lại, một số dịch vụ mạng và tính năng hệ thống phải được cân nhắc trước.

Container dùng chung kernel nên quyền của daemon rất quan trọng

Cài Docker trên Debian bằng dòng lệnh
Các lệnh cài Docker trên Debian là điểm khởi đầu trước khi chọn daemon rootful hay Rootless. Ảnh: XDA Developers

Máy ảo thường chạy một hệ điều hành với kernel riêng trong môi trường ảo hóa; container thì chia sẻ kernel Linux của host. Vì thế, ranh giới cách ly của container không giống một máy tính độc lập. Docker daemon rootful có quyền cao trên host, và quyền truy cập socket điều khiển daemon cũng cần được xem như một quyền quản trị hệ thống.

Nếu container được cấp quyền mount thư mục nhạy cảm của host, hoặc phần mềm bên trong khai thác được lỗ hổng để thoát khỏi container, hậu quả có thể chạm tới dữ liệu và dịch vụ ở máy chủ. Việc chạy ứng dụng trong container bằng user không phải root vẫn hữu ích, nhưng riêng thay đổi đó không hạ quyền của dockerd hay tự bảo vệ socket Docker.

Rootless giảm phạm vi ảnh hưởng nhưng không biến container thành máy ảo

Lệnh cài đặt Rootless Docker trên Linux
Màn hình lệnh cài Rootless Docker minh họa lựa chọn giảm quyền daemon trên máy Linux. Ảnh: XDA Developers

Rootless mode của Docker chạy daemon và container trong user namespace, dưới một tài khoản không có quyền root trên host. Docker phân biệt chế độ này với userns-remap: ở chế độ remap, daemon vẫn chạy bằng root; còn Rootless thì cả daemon lẫn container đều không chạy bằng quyền đó.

Đây là lớp giảm thiểu rủi ro, không phải lời bảo đảm rằng container không thể bị xâm nhập hoặc host không thể bị ảnh hưởng. Kernel vẫn được chia sẻ; cấu hình mount, quyền truy cập socket, bản cập nhật image và mức đặc quyền cấp cho container vẫn quan trọng. Bởi vậy, Rootless phù hợp để giảm hậu quả của sai sót, chứ không thay thế việc kiểm tra image và giới hạn quyền cần thiết.

Đổi lại, cổng dịch vụ và một số tính năng cần xử lý riêng

Trở ngại dễ gặp nhất là các cổng đặc quyền dưới 1024. Rootless Docker không thể mặc định publish cổng host như 80 hoặc 53; tài liệu Docker gợi ý dùng cổng không đặc quyền, chẳng hạn 8080, hoặc cấu hình hệ thống để cho phép cổng thấp. Với dịch vụ web, có thể đặt reverse proxy ở phía trước để nhận lưu lượng cổng 80/443 rồi chuyển tiếp tới cổng cao hơn. Pi-hole lại cần cổng 53 cho DNS, nên cách bố trí mạng cần được tính trước thay vì đổi chế độ rồi mới phát hiện dịch vụ không lên.

Còn có các giới hạn phụ thuộc kernel và cấu hình máy. Docker nêu các driver lưu trữ được hỗ trợ gồm overlay2 trên kernel 5.11 trở lên, fuse-overlayfs trên kernel 4.18 trở lên khi đã cài gói tương ứng, btrfs và vfs. Giới hạn tài nguyên bằng cgroups cần cgroup v2 cùng systemd; AppArmor, checkpoint, overlay network và SCTP không được hỗ trợ trong Rootless mode theo tài liệu xử lý sự cố của Docker. Mạng cũng có thể chậm hơn do dùng ngăn xếp TCP/IP chạy ở user space.

Để cài đặt, Docker yêu cầu có newuidmap, newgidmap và mỗi người dùng cần ít nhất 65.536 subordinate UID/GID trong /etc/subuid và /etc/subgid. Các yêu cầu này có nghĩa Rootless không phải lúc nào cũng là lựa chọn bật lên rồi quên; máy chủ chạy nhiều dịch vụ cần kiểm tra trước khả năng tương thích về cổng, lưu trữ và cgroups.

Chọn Rootless cho homelab thử nghiệm, giữ cấu hình có chủ đích cho server

Với máy cá nhân chạy công cụ năng suất, lưu trữ hoặc các image đang thử nghiệm, Rootless là lựa chọn hợp lý nếu các dịch vụ không cần cổng thấp và giới hạn của hệ thống phù hợp. Người quản trị nên kiểm tra quyền của socket Docker, tránh mount rộng thư mục host, và chỉ cấp các quyền bổ sung mà ứng dụng thực sự cần.

Docker không phải lựa chọn duy nhất. Podman được thiết kế theo kiến trúc không cần daemon trung tâm và hỗ trợ chạy rootless, nên có thể hợp với người muốn tránh một daemon rootful thường trực. Tuy nhiên, đổi runtime cũng kéo theo việc kiểm tra tương thích image, Compose và quy trình vận hành hiện có; tên gọi rootless tự nó không xóa bỏ nhu cầu kiểm soát quyền và cấu hình.

Rootless đáng cân nhắc nhất khi mức giảm rủi ro quan trọng hơn sự tiện lợi của cổng thấp hoặc tính năng chưa tương thích. Trên server nhiều dịch vụ, quyết định nên dựa vào nhu cầu thực tế của từng workload, không phải mặc định rằng mọi container đều an toàn chỉ vì đã tách khỏi tiến trình host.

Nguồn tham khảo: Docker Docs: Rootless mode; Docker Docs: Troubleshooting Rootless mode; XDA Developers

Bài viết mới nhất