Tự động hóa phân vùng đĩa: Đánh giá 6 tháng vận hành thực tế systemd-repart

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Nút thắt của các Image đĩa tĩnh

Sáu tháng trước, đội ngũ của tôi đã gặp một trở ngại lớn. Chúng tôi đang triển khai một đội ngũ gồm 120 thiết bị edge và nhiều instance đám mây khác nhau chỉ bằng một image Linux duy nhất dung lượng 2.1GB. Mặc dù image này khá gọn nhẹ, nhưng phần cứng của chúng tôi lại rất đa dạng. Một số đơn vị chạy trên thẻ nhớ SD 32GB, trong khi số khác sử dụng ổ cứng NVMe 1TB. Mỗi khi triển khai, chúng tôi phải thay đổi kích thước phân vùng root một cách thủ công hoặc duy trì các script shell dễ lỗi để kích hoạt growpart và resize2fs trong lần khởi động đầu tiên.

Nếu bạn từng quản lý nhiều hơn năm máy chủ, bạn sẽ hiểu sự ức chế này. Bạn tải xuống một image cloud Ubuntu phổ biến, khởi chạy nó và nhận ra hệ điều hành chỉ nhận 8GB trong tổng số 100GB dung lượng mà bạn đã trả tiền. Cloud-init có thể xử lý việc này, nhưng nó thường tạo cảm giác quá rườm rà đối với các môi trường tối giản. Nếu bạn đang xây dựng một hệ thống nhúng tùy chỉnh, có lẽ bạn muốn một giải pháp có dung lượng chiếm dụng nhỏ hơn những gì bộ công cụ cloud-init đầy đủ cung cấp.

Tại sao việc thay đổi kích thước chuẩn lại thất bại ở quy mô lớn

Sự xung đột bắt nguồn từ thực tế là các bảng phân vùng GPT hoặc MBR truyền thống mang tính tĩnh. Khi bạn tạo một image đĩa, bảng phân vùng sẽ được ghi vào những sector đầu tiên của tệp. Nó không hề biết đĩa vật lý cuối cùng sẽ lớn như thế nào. Khi bạn nạp image 2GB đó lên một ổ đĩa 64GB, bảng phân vùng vẫn bị khóa ở mức 2GB. 62GB còn lại sẽ ở trạng thái “không gian chưa phân bổ” (unallocated space) cho đến khi có tác động bên ngoài.

Các cách khắc phục thủ công thường bao gồm:

  • Sử dụng fdisk để xóa và tạo lại phân vùng (một công việc gây đau tim khi thực hiện trên hệ thống đang vận hành).
  • Chạy resize2fs hoặc xfs_growfs để mở rộng hệ thống tệp thực tế.
  • Đối mặt với rủi ro hỏng dữ liệu nếu xảy ra mất điện giữa chừng khi đang thay đổi kích thước.

Sau khi quản lý hàng chục node Linux trong vài năm qua, tôi nhận ra rằng các bước thủ công chính là cơ hội cho sai sót của con người. Tôi đã dành nhiều tuần tìm kiếm một phương pháp khai báo (declarative) mạnh mẽ để xử lý bố cục đĩa. Cuộc tìm kiếm đó đã dẫn tôi đến systemd-repart.

So sánh các đối thủ: growpart và systemd-repart

Trước khi chuyển đổi, tôi đã đánh giá các công cụ tiêu chuẩn. Hầu hết quản trị viên sử dụng growpart, thực chất là một script shell bao bọc quanh sfdisk. Đây là một công cụ mang tính mệnh lệnh (imperative). Bạn phải nói chính xác cho nó biết cần làm gì tại một thời điểm cụ thể. Nếu script gặp một trường hợp biên (edge case) và thất bại giữa chừng, bạn thường sẽ bị để lại một bảng phân vùng bị lỗi.

systemd-repart đi theo một con đường khác. Nó mang tính khai báo. Bạn định nghĩa đĩa sẽ trông như thế nào bằng các tệp cấu hình đơn giản. Trong giai đoạn đầu của quá trình khởi động, systemd-repart sẽ kiểm tra đĩa vật lý và so sánh nó với cấu hình của bạn. Sau đó, nó thực hiện các thay đổi cần thiết để đạt được trạng thái đó. Vì nó có tính lũy đẳng (idempotent), bạn có thể chạy nó lặp đi lặp lại mà không sợ làm hỏng bất cứ thứ gì.

Tính năng growpart / Thủ công systemd-repart
Cấu hình Dựa trên script (Mệnh lệnh) Tệp cấu hình (Khai báo)
Độ an toàn Trung bình (Logic script thay đổi) Cao (Cập nhật GPT nguyên tử)
Mã hóa Cần thay đổi kích thước LUKS thủ công Hỗ trợ LUKS gốc
Độ phức tạp Yêu cầu nhiều tệp thực thi Tích hợp sẵn trong systemd

Triển khai systemd-repart: Phương pháp khai báo

Thay vì chạy một lệnh phức tạp, bạn đặt các tệp .conf vào /usr/lib/repart.d/ hoặc /etc/repart.d/. Lưu ý rằng công cụ này nhắm mục tiêu cụ thể vào các bảng phân vùng GPT. Nó không hỗ trợ định dạng MBR (DOS) cũ.

1. Mở rộng phân vùng Root

Nhiệm vụ phổ biến nhất là mở rộng phân vùng root để lấp đầy đĩa. Nếu phân vùng root của bạn là mục thứ hai trên đĩa, bạn sẽ tạo một tệp có tên 50-root.conf:

# /etc/repart.d/50-root.conf
[Partition]
Type=root
# Kích thước tối thiểu yêu cầu
SizeMinBytes=512M
# Để trống để sử dụng toàn bộ không gian còn trống
GrowFileSystem=yes

Khi dịch vụ chạy, nó xác định phân vùng thông qua GPT Type GUID. Sau đó, nó sẽ mở rộng phân vùng và hệ thống tệp bên dưới đồng thời, miễn là kernel có hỗ trợ.

2. Thêm phân vùng dữ liệu riêng biệt

Một tính năng mà tôi rất tin dùng là hệ thống dựa trên trọng số (weight). Giả sử bạn muốn một phân vùng /var/log riêng biệt có thể mở rộng dựa trên kích thước ổ đĩa. Bạn không cần phải tự mình tính toán.

# /etc/repart.d/60-data.conf
[Partition]
Type=linux-generic
Label=Data
# Chiếm 50% không gian trống còn lại
Weight=500
Format=ext4
MountPoint=/data

Nếu bạn có hai phân vùng với Weight=500, systemd-repart sẽ chia không gian còn lại theo tỷ lệ 50/50. Đây là một cứu cánh khi triển khai cùng một image lên cả thẻ SD 32GB và ổ NVMe 1TB.

3. Kiểm tra cấu hình

Đừng bao giờ áp dụng các thay đổi lên đĩa đang vận hành thực tế mà không kiểm tra. Tôi luôn sử dụng cờ --dry-run trước. Nó hiển thị một bản đồ chi tiết các thay đổi dự kiến mà không ghi bất kỳ byte nào.

systemd-repart --dry-run --pretty

Kết quả đầu ra cung cấp cho bạn hình ảnh trực quan về bố cục hiện tại so với bố cục dự kiến. Sau khi đã xác minh, bạn có thể áp dụng thủ công bằng lệnh --apply=yes. Trong hầu hết các thiết lập thực tế, systemd-repart.service sẽ tự động xử lý việc này trong giai đoạn initramfs.

Bài học sau 6 tháng vận hành thực tế

Sau nửa năm, tôi đã nhận thấy một vài sắc thái mà các trang hướng dẫn (man pages) không nhấn mạnh.

GPT Backup Header: Khi bạn thay đổi kích thước đĩa ảo trong AWS hoặc Proxmox, header sao lưu của GPT không còn nằm ở cuối đĩa vật lý nữa. systemd-repart sẽ tự động sửa lỗi này. Tuy nhiên, nó yêu cầu quyền ghi vào thiết bị block, điều này có thể bị hạn chế trong một số môi trường container được bảo mật nghiêm ngặt.

Hỗ trợ hệ thống tệp: Tùy chọn GrowFileSystem=yes hoạt động hoàn hảo với Ext4, XFS và Btrfs. Nếu bạn sử dụng các hệ thống tệp ít phổ biến hơn, systemd-repart sẽ mở rộng phân vùng, nhưng bạn có thể cần systemd-growfs để xử lý việc mở rộng nội bộ hệ thống tệp.

Thứ tự chữ cái và số: Các tệp trong repart.d/ được xử lý theo thứ tự bảng chữ cái. Nếu cả 10-root.conf và 20-data.conf đều muốn mở rộng, thứ tự này sẽ quyết định vị trí vật lý của chúng. Hãy tuân thủ quy ước đánh số nghiêm ngặt để tránh những bất ngờ về bố cục.

Giải pháp này có phù hợp với bạn không?

Nếu bạn chỉ quản lý một chiếc laptop cá nhân, giải pháp này có lẽ là quá mức cần thiết. Nhưng đối với bất kỳ ai đang xây dựng image đĩa, quản lý đội ngũ máy chủ đám mây hoặc triển khai các thiết bị IoT, đây là một sự nâng cấp đáng kể. Nó đã thay thế các script shell dài 200 dòng của chúng tôi bằng ba tệp cấu hình đơn giản.

Sự tích hợp sâu với hệ sinh thái systemd—đặc biệt là LUKS và systemd-growfs—làm cho cơ sở hạ tầng của bạn trở nên ổn định và dễ dự đoán hơn. Theo kinh nghiệm của tôi, tính ổn định là người bạn tốt nhất khi máy chủ gặp sự cố vào lúc 3 giờ sáng. Nếu bạn vẫn đang sử dụng các thủ thuật fdisk trong script khởi động của mình, hãy thử dùng systemd-repart. Chỉ cần nhớ chạy --dry-run trước.

Share: