Sự cố khẩn cấp lúc 2:14 sáng
Vào lúc 2:14 sáng, điện thoại của tôi rung lên với một cảnh báo từ PagerDuty. Đó là dòng tin nhắn mà bất kỳ quản trị viên hệ thống nào cũng khiếp sợ: CRITICAL: No space left on device (ENOSPC) (LỖI NGHIÊM TRỌNG: Không còn dung lượng trống trên thiết bị). Máy chủ phát triển chung của chúng tôi đã ngừng hoạt động. Tôi đăng nhập qua SSH và hy vọng sẽ tìm thấy một file /var/log bị phình to hoặc một file tạm khổng lồ nào đó. Tuy nhiên, lệnh df -h cho thấy phân vùng /home đã đầy 100% dung lượng.
Kiểm tra các thư mục người dùng bằng lệnh du -sh /home/* đã tìm ra thủ phạm. Một lập trình viên mới (junior) đã chạy một script sao lưu đệ quy, đẩy 450GB dữ liệu cảm biến thô vào thư mục cá nhân của họ chỉ trong chưa đầy 20 phút. Vì chúng tôi thiếu cơ chế quản trị tài nguyên, chỉ một người dùng duy nhất đó đã làm tê liệt toàn bộ quy trình làm việc của cả đội. Máy chủ email ngừng hoạt động, các tác vụ cron thất bại, và hệ thống thậm chí không thể tạo nổi một file lock để lưu một tài liệu văn bản.
Tại sao hệ thống tập tin thất bại nếu không có giới hạn
Theo mặc định, Linux cực kỳ “hào phóng”. Nó giả định rằng người dùng sẽ chia sẻ tài nguyên một cách có trách nhiệm. Tuy nhiên, trong môi trường production, việc tin tưởng vào ý thức tự giác là công thức dẫn đến thảm họa. Khi ổ đĩa đầy, kernel không thể ghi metadata và các ứng dụng sẽ bị treo ngay lập tức. Nó tạo ra một sự tê liệt toàn diện cho hệ thống.
Nguyên nhân gốc rễ của sự cố đêm đó không chỉ là một script bị lỗi; đó là do thiếu Disk Quotas (Hạn mức ổ đĩa). Nếu không có quota, hệ thống tập tin coi mỗi người dùng như một người đồng sở hữu toàn bộ không gian trống. Để ngăn chặn điều này, bạn phải thiết lập các ranh giới. Bạn cần một hệ thống có thể thông báo cho kernel rằng: “Người dùng A được dùng 10GB, Người dùng B được 20GB, và nhóm ‘Dev’ được tổng cộng 100GB”.
Lựa chọn công cụ phù hợp
Có vài cách để xử lý giới hạn lưu trữ. Bạn có thể dùng LVM để tạo các phân vùng riêng biệt cho mỗi người dùng, nhưng quản lý 500 phân vùng cá nhân là một cơn ác mộng. XFS có các công cụ quota tích hợp sẵn rất tuyệt vời cho các hệ thống hiệu năng cao. Tuy nhiên, đối với các hệ thống dựa trên ext4 tiêu chuẩn như Ubuntu 22.04 hoặc Debian, gói quota cổ điển vẫn là giải pháp đáng tin cậy và đã được kiểm chứng thực tế tốt nhất.
Trên một máy chủ production với 8GB RAM và 2.000 người dùng hoạt động, tôi thấy phương pháp ở cấp độ kernel này tiêu tốn rất ít CPU. Nó hiệu quả hơn nhiều so với việc chạy các script bash tùy chỉnh để theo dõi dung lượng mỗi 5 phút. Vì nó hoạt động ở cấp độ hệ thống tập tin, người dùng không thể lách luật bằng cách đổi tên file hoặc ẩn chúng trong các thư mục con sâu thẳm.
Triển khai Disk Quota từng bước một
Để đảm bảo tôi không bao giờ nhận được cuộc gọi lúc 2:14 sáng đó nữa, tôi đã triển khai hệ thống quota tiêu chuẩn. Bạn có thể thiết lập hệ thống này trên máy chủ của mình trong khoảng mười phút.
Bước 1: Cài đặt các công cụ tiện ích
Bạn cần các công cụ ở không gian người dùng (userspace) để giao tiếp with kernel. Trên Ubuntu hoặc Debian, hãy cài đặt chúng bằng lệnh sau:
sudo apt update
sudo apt install quota quotatool -y
Bước 2: Cập nhật bảng hệ thống tập tin
Kernel cần biết phân vùng nào nên được theo dõi mức độ sử dụng. Mở file /etc/fstab và tìm phân vùng bạn muốn giới hạn, ví dụ như /home.
# Dòng gốc trong /etc/fstab:
UUID=xxxx-xxxx /home ext4 defaults 0 2
# Dòng đã sửa đổi cho quota Người dùng và Nhóm:
UUID=xxxx-xxxx /home ext4 defaults,usrquota,grpquota 0 2
Việc thêm usrquota và grpquota sẽ báo cho hệ thống bắt đầu theo dõi việc sử dụng đĩa theo từng người dùng và từng nhóm trong lần mount tiếp theo.
Bước 3: Khởi tạo cơ sở dữ liệu Quota
Bạn không cần phải khởi động lại máy chủ. Hãy mount lại hệ thống tập tin để áp dụng các thay đổi ngay lập tức:
sudo mount -o remount /home
Tiếp theo, tạo các file chỉ mục quota (aquota.user và aquota.group). Lệnh quotacheck sẽ quét đĩa và tính toán mức sử dụng hiện tại cho mọi file trên hệ thống.
sudo quotacheck -cum /home
-c: Tạo các file quota mới.-u: Kiểm tra quota cấp người dùng.-m: Thực hiện kiểm tra mà không cần mount lại ở chế độ chỉ đọc (read-only).
Cuối cùng, kích hoạt hệ thống:
sudo quotaon -v /home
Bước 4: Thiết lập giới hạn với edquota
Lệnh edquota sẽ mở một file tạm thời trong trình soạn thảo văn bản mặc định của bạn (như Vim hoặc Nano), nơi bạn định nghĩa các giới hạn cụ thể.
sudo edquota -u developer_name
Cấu hình sẽ trông như thế này:
Hạn mức ổ đĩa cho người dùng developer_name (uid 1001):
Filesystem blocks soft hard inodes soft hard
/dev/sda2 409600 1048576 1258291 5 0 0
Hiểu các cột này là rất quan trọng:
- blocks: Dung lượng hiện tại đang sử dụng, tính bằng các khối 1KB.
- soft (limit): Giới hạn mềm (ngưỡng cảnh báo). Người dùng có thể vượt quá mức này tạm thời trong một “thời gian ân hạn”, thường là 7 ngày.
- hard (limit): Giới hạn cứng (ngưỡng tuyệt đối). Hệ thống sẽ chặn tất cả các thao tác ghi ngay khi người dùng chạm tới con số này.
- inodes: Tổng số lượng file. Điều này ngăn người dùng tạo ra hàng triệu file trống làm cạn kiệt khả năng lưu trữ metadata của hệ thống tập tin.
Trong ví dụ này, tôi đặt giới hạn mềm là 1GB (1.048.576 KB) và giới hạn cứng là 1.2GB (1.258.291 KB).
Bước 5: Điều chỉnh thời gian ân hạn
Để thay đổi thời gian người dùng có để xóa file sau khi chạm giới hạn mềm, hãy sử dụng lệnh hẹn giờ:
sudo edquota -t
Tôi thường đặt mức này là 48 giờ cho các môi trường production. Nó cung cấp đủ thời gian để lập trình viên phản ứng trong tuần làm việc mà không để ổ đĩa rơi vào tình trạng đầy nguy hiểm quá lâu.
Theo dõi lưu trữ của bạn
Thiết lập giới hạn mới chỉ là bước đầu tiên. Bạn cũng cần xem ai đang sắp hết dung lượng. Lệnh repquota cung cấp một bản tóm tắt sạch sẽ về mọi người dùng trên hệ thống tập tin.
sudo repquota -s /home
Tham số -s chuyển đổi các khối thô thành định dạng MB và GB dễ đọc. Tôi thường chuyển đầu ra này vào một tác vụ cron hàng tuần để xác định mười người dùng tiêu tốn nhiều dung lượng nhất trong tổ chức.
Tự động hóa quy trình
Việc chạy edquota thủ công cho mỗi nhân viên mới là rất tẻ nhạt. Nếu bạn có giới hạn tiêu chuẩn là 5GB cho tất cả lập trình viên mới, hãy sử dụng một người dùng mẫu (prototype) để sao chép cài đặt ngay lập tức.
sudo edquota -p template_user new_user
Lệnh này sao chép các giới hạn từ template_user sang new_user chỉ trong một giây. Nó đảm bảo tính nhất quán và ngăn ngừa lỗi cấu hình trong quá trình tiếp nhận nhân viên mới.
Kể từ khi triển khai các hạn mức này, tôi chưa gặp một lỗi “No space left on device” nào do người dùng gây ra. Khi ai đó chạm giới hạn, hệ thống chỉ dừng các thao tác ghi của riêng họ. Phần còn lại của hệ điều hành và đội ngũ vẫn tiếp tục làm việc mà không bị gián đoạn. Đây là một công cụ đơn giản, mang tính cổ điển nhưng vẫn là một phần bắt buộc trong bộ công cụ của bất kỳ quản trị viên Linux chuyên nghiệp nào.

