Có thể tạo ISO NixOS nhỏ hơn không?
(natkr.com)- NixOS giúp tạo VM hoặc ISO dễ dàng chỉ bằng cấu hình, nhưng ngay cả image live gần mức tối thiểu cũng được tạo ra ở mức 458MiB ngay từ đầu, chênh lệch lớn so với ISO Alpine VM khoảng 66MiB
- Phần lớn dung lượng nằm ở nix-store.squashfs, bên trong có Python 3.13.13, Linux modules, systemd, Perl, GRUB, tài liệu và các phụ thuộc liên quan đến Nix
- Qua các bước
nix.enable = false,documentation.enable = false, và loại bỏregister-nix-paths, ISO đã giảm từ 458MiB → 384MiB → 360MiB, đồng thời phụ thuộc Boost cũng biến mất - Sau khi loại bỏ OpenSSH client, các gói mặc định, công cụ cài đặt GRUB, kernel module runtime và cả đường kích hoạt dựa trên Perl, kích thước cuối cùng giảm xuống còn 183MiB
- Đây là tài liệu tham khảo hữu ích cho image khởi động nhỏ phục vụ thử nghiệm, nhưng vì đã loại bỏ quá nhiều chức năng nên khó dùng nguyên trạng cho desktop hoặc môi trường quan trọng
Tạo ISO từ cấu hình NixOS
- NixOS cho phép tạo VM dễ dàng dựa trên cấu hình
nixos-rebuild build-vmtạo VM từ cấu hình hệ thống hiện tại- Dùng
pkgs.nixoscó thể tạo VM từ cấu hình tùy ý ngay cả khi đó không phải cấu hình hệ thống
- Ví dụ cơ bản tạo một VM tối thiểu chỉ với
system.stateVersion = "26.05"vàservices.getty.autologinUser = "root" - VM này hoạt động theo kiểu thin VM
- Ảnh đĩa chỉ chứa các tệp được tạo trực tiếp bên trong VM
- Phần còn lại như
/nix/stoređược mount từ hệ điều hành host
- Nếu host không có Nix, là host từ xa, hoặc chạy trên hypervisor thông thường, thì cần một ISO tự chứa
- Có thể build ISO bằng cách import module
iso-image.nixcủa NixOSimage.baseName = lib.mkForce "nixos"dùng để đặt tên file ISO đầu ra- Ví dụ chạy là
qemu-system-x86_64 --cdrom .../nixos.iso -m 1G --accel kvm - Nếu không phải môi trường Linux hiện đại trên amd64 thì có thể cần đổi kiến trúc hoặc cách tăng tốc
Điểm khởi đầu: ISO 458MiB
- Kết quả build ISO mặc định là 458MiB
- Image này thậm chí còn chưa có
vim- Sau khi boot, chạy
vimsẽ nhậncommand not found
- Sau khi boot, chạy
- ISO VM của Alpine được dùng để so sánh có dung lượng khoảng 66MiB
- Damn Small Linux được nhắc đến như một ví dụ từng cung cấp môi trường desktop hoàn chỉnh với kích thước nhỏ hơn rất nhiều
- Mục tiêu không phải đạt đến mức của Damn Small Linux mà là kiểm tra xem có thể giảm ISO NixOS thêm được bao nhiêu
Phân tích dung lượng bên trong ISO
- Sau khi mount ISO và kiểm tra bằng
du, dung lượng được chia như saunix-store.squashfs: 416MiB- initrd: 26MiB
- kernel: 13MiB
- toàn bộ ISO: 458MiB
- Yếu tố chiếm dung lượng chính là nix-store.squashfs, tức không gian user space chính
- Khi mount squashfs sẽ thấy các đường dẫn trông như Nix store
python3-3.13.13: 128MiBlinux-6.18.35-modules: 144MiBsystemd-260.1: 60MiBperl-5.42.0: 56MiBgrub-2.12: tổng nhiều mục khoảng 62MiB- Cũng có cả tài liệu như
nix-manual-2.34.7,nixos-manual-html
- Vì ISO được build trên host, nên các đường dẫn store trong ISO cũng có thể lần theo trong
/nix/storecủa host nix why-dependsđược dùng để tìm nguồn gốc phụ thuộc- Boost được kéo vào qua đường dẫn Nix daemon
- Từ
nix-daemon.conf,nix,libnixutil.sođi đếnboost-1.89.0
Loại bỏ Nix và tài liệu
- Thử dùng
nix.enable = falseđể loại bỏ chính Nix khỏi image - Dùng
documentation.enable = falseđể tắt tài liệu - Kết quả đầu tiên là 458MiB → 384MiB
- Tuy vậy Boost vẫn còn tồn tại
register-nix-paths.servicecố đăng ký nội dung store của ISO khi boot- Đường này lại kéo Nix và Boost quay trở lại
- Dùng
systemd.services.register-nix-paths = lib.mkForce {}để xóa rỗng service đó - Kết quả là ISO còn 360MiB, và
nix why-dependsxác nhận không còn phụ thuộc Boost
Loại bỏ OpenSSH và các gói mặc định
- Theo cách tương tự,
environment.defaultPackagescũng có thể bị xóa rỗng - Việc loại bỏ
sshphức tạp hơnmodules/programs/ssh.nixthêm OpenSSH vàoenvironment.corePackages- Không tìm thấy tùy chọn kiểu
programs.ssh.enableđể kiểm soát việc này services.openssh.enablelà cấu hình cho server chứ không phải tùy chọn xóa client
- Có thể loại
programs/ssh.nixbằngdisabledModules, nhưng các module khác lại giả định rằng tùy chọnprograms.sshtồn tại, gây lỗi dây chuyền - Cách giải quyết là cung cấp một stub option riêng không sử dụng các tùy chọn
programs.sshoptions.programs.ssh = lib.mkOption {};- Sau đó loại module SSH thật bằng
disabledModules = [ "programs/ssh.nix" ];
- Trong quá trình này cũng áp dụng thêm các cấu hình sau
documentation.man.enable = falsenetworking.firewall.enable = falseenvironment.defaultPackages = lib.mkForce []
Ghi chú về cấu trúc module của NixOS
- Module NixOS về cơ bản có ba phần lớn
- Mục ở cấp module:
imports,disabledModules - Định nghĩa tùy chọn:
options.* - Phần triển khai:
config.*
- Mục ở cấp module:
- Những module không định nghĩa tùy chọn có thể dùng dạng rút gọn với các thuộc tính triển khai mà không cần tiền tố
config. - Để giữ dạng rút gọn trong phần cấu hình còn lại, stub option cho
programs.sshđược tách ra thành một module import riêng
Loại bỏ công cụ cài đặt GRUB
- Một trong những mục lớn còn lại là các tệp liên quan đến GRUB, khoảng 62MiB
- Bản thân bootloader là cần thiết, nhưng không cần phải mang theo toàn bộ công cụ cài đặt
- Preset ISO của NixOS đóng gói cả GRUB bản UEFI lẫn BIOS
- Không có tùy chọn rõ ràng để tắt chúng, nên dùng cách mạnh tay hơn để đặt lại các giá trị sau
system.extraDependencies = lib.mkForce []environment.systemPackages = lib.mkForce config.environment.corePackages
- Không xóa hoàn toàn
environment.systemPackages- Nếu không có
bash, getty có thể rơi vào crashloop liên tục, nên vẫn giữcorePackagesđể shell còn hoạt động ở mức tối thiểu
- Nếu không có
Loại bỏ kernel module
linux-6.18.35-modulescó dung lượng 144MiB, tương đương khoảng một phần tư toàn bộ- NixOS dường như không có hook phù hợp để giới hạn kernel module dùng ở runtime
- Thay vào đó, thư mục
kernel-modulesbị xóa khỏi đầu ra hệ thốngsystem.systemBuilderCommands = lib.mkAfter "rm $out/kernel-modules";
- Cách này về thực chất vô hiệu hóa việc nạp module runtime
- Các module cần thiết phải được đưa vào
boot.initrd.kernelModuleshoặcavailableKernelModules
- Các module cần thiết phải được đưa vào
- Sau thay đổi này, hệ thống mất khả năng chuyển sang độ phân giải hiển thị thuận tiện hơn, nhưng vẫn boot được
- Kích thước ISO giảm xuống 197MiB
Loại bỏ Perl và các tính năng thay thế mang tính thử nghiệm
- Vẫn còn Perl chiếm 56MiB
- Kiểm tra bằng
nix why-dependscho thấy Perl được dùng trong quá trình kích hoạt hệ thống để cấu hình user và/etc - Không thể bỏ hoàn toàn phần cấu hình user và
/etc - Thay vào đó, dùng các tính năng thử nghiệm để thay thế đường đi hiện có
- Quản lý
/etcbằng cơ chế overlay - Quản lý user bằng userborn native
- Quản lý
- Cấu hình được áp dụng như sau
system.etc.overlay.enable = truesystem.etc.overlay.mutable = falseservices.userborn.enable = true
- Kích thước ISO cuối cùng là 183MiB
Trạng thái cuối cùng và giới hạn
- Từ điểm xuất phát 458MiB xuống 183MiB, tức gần bằng một phần ba bản gốc
- Dù vậy, kết quả này vẫn khó có thể gọi là “tốt”
- Nó không phù hợp để dùng nguyên trạng cho desktop hoặc môi trường quan trọng thực sự
- Mọi chức năng bị loại bỏ đều tồn tại vì có lý do
- Nếu cần một image boot nhỏ cho mục đích thử nghiệm và chỉ thực hiện các tác vụ rất đơn giản, đây có thể là tài liệu tham khảo hữu ích
- Nếu sao chép nguyên cấu hình cuối cùng để dùng, rất có thể sẽ thiếu những chức năng cần cho mục đích thực tế
Vẫn còn chỗ để giảm thêm
- Lần này tác giả tập trung vào những mục có thể “xóa luôn” hoặc có phương án thay thế tương đối rõ ràng
- Vẫn còn những khu vực đòi hỏi đào sâu hơn
- Hiện tại cả
systemdMinimallẫnsystemdđều được đóng gói cùng nhau - Nếu cố loại một trong hai thì các đường build khác sẽ bị hỏng
- Hiện tại cả
- Những mục nhỏ hơn nữa cũng vẫn có thể loại bỏ, và cộng dồn lại có thể tạo ra khác biệt đáng kể
- Tối ưu thêm sẽ cần nhiều điều tra và thử nghiệm hơn
1 bình luận
Ý kiến trên Lobste.rs
Có một mô-đun được tạo ra đúng cho mục đích này. Cần biên dịch khá nhiều, nhưng có thể tạo một initrd hoàn toàn độc lập bao gồm toàn bộ không gian người dùng của NixOS với kích thước khoảng 80MiB khi nén bằng zstd
Việc này không chỉ giới hạn ở initrd độc lập, mà còn có thể dùng để giảm dung lượng của bất kỳ hệ NixOS nào. Có lẽ cũng áp dụng được cho ISO cài đặt
https://github.com/wucke13/minimal-nixos/
Hệ thống cơ bản của TinyCore Linux là Core với dung lượng 17MB
Nếu muốn cả X và FLTK/FLWM thì có TinyCore 23MB, còn nếu muốn thêm nhiều trình quản lý cửa sổ và ứng dụng hơn thì có CorePlus 248MB
http://www.tinycorelinux.net/downloads.html
Tôi khuyên nên xem bài trình bày ở NixCon về việc thu nhỏ NixOS để làm phương án thay thế cho Yocto: https://youtu.be/AsXY61laNb8
Nó không chi tiết như tôi kỳ vọng, nhưng những gì tôi nghe trực tiếp từ Óli và Matthew tại hội nghị thì rất ấn tượng. Không biết có bài viết tổng hợp nào không
Trên NixOS, việc tạo một môi trường cài đặt nhỏ luôn hơi gây bực bội
Có vẻ có thể giảm kích thước phần SSH bằng cấu hình dưới đây
Cũng có thể import
"${nixpkgs}/nixos/modules/profiles/minimal.nix". Trong đó có một phần các tối ưu được nhắc trong bài viếtDù vậy, trong đa số trường hợp thì cách này có lẽ hợp lý hơn
Tôi từng xem
"${nixpkgs}/nixos/modules/profiles/minimal.nix"nhưng thấy không ấn tượng như kỳ vọng, nên lúc bắt đầu tìm hiểu tôi đã không nghĩ đến việc đưa nó vào. Khi nhớ ra thì tôi đã làm được khoảng một nửa rồi, nên cảm thấy hơi không trung thực nếu chèn nó vào giai đoạn đầu, vốn là chỗ đáng ra nó phải xuất hiệnDạo này có quá nhiều trường hợp Perl bị kéo vào các hệ thống, thật kỳ lạ. Ngay cả với ISO nhỏ, Perl cũng xuất hiện; và nếu thử biên dịch một thứ gì đó cho ra hồn từ đầu thì lại thành openssl -> Perl
Ngay từ trước khi đọc, tôi đã đoán nguyên nhân sẽ là một script Perl ngớ ngẩn nào đó chưa được viết lại bằng C
Sửa: đúng là vậy thật
Từ NixOS 26.05, initrd mặc định của NixOS dùng systemd. Lý do là có nhiều trường hợp sử dụng initrd mà hệ điều hành hiện đại cần hỗ trợ
systemdMinimallà một nhị phân systemd được biên dịch với ít cờ và phụ thuộc hơn, giúp giữ initrd nhỏ hơnTuy vậy, nếu mục tiêu là ISO tối thiểu thì có vẻ vẫn có thể khiến cả hai cùng phụ thuộc vào một nhị phân duy nhất