Khởi động lại Linux trong vài giây: Sử dụng kexec để bỏ qua BIOS và POST

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

Cửa sổ bảo trì 9 phút

Tôi đã từng phải vá một lỗ hổng kernel nghiêm trọng trên một máy chủ cơ sở dữ liệu có lưu lượng truy cập cao. Tôi thực hiện lệnh reboot và chờ đợi. Rồi tôi đợi thêm chút nữa. Bảy phút trôi qua trong khi máy chủ thực hiện các bước kiểm tra bộ nhớ nội bộ. Hai phút nữa biến mất trong quá trình khởi tạo RAID controller. Đến khi hệ điều hành thực sự bắt đầu tải, hệ thống giám sát của chúng tôi đã kích hoạt một sự cố P1. Trên một hệ thống production, khoảng cách 9 phút đó không chỉ là sự bất tiện—đó là mối đe dọa đối với SLA của bạn.

Sau khi quản lý hàng chục máy chủ cấp doanh nghiệp, tôi nhận ra rằng khởi tạo phần cứng là kẻ thù của uptime. Điều này dẫn tôi đến một công cụ đã thay đổi hoàn toàn quy trình bảo trì của mình: kexec.

Nút thắt cổ chai: Tại sao reset phần cứng lại lãng phí thời gian

Một lệnh reboot tiêu chuẩn sẽ kích hoạt một “cold boot” (khởi động nguội). CPU reset, BIOS/UEFI thực hiện Power-On Self-Test (POST), và mọi thiết bị ngoại vi—từ card mạng 10GbE đến các bộ điều khiển NVMe—phải khởi tạo lại. Trên một chiếc Dell PowerEdge hoặc HP ProLiant với 512GB RAM, riêng giai đoạn phần cứng có thể mất từ 5 đến 8 phút.

Linux cung cấp một lối shortcut. Thay vì trả quyền điều khiển cho phần cứng, chúng ta có thể chỉ thị cho kernel đang chạy nạp trực tiếp một kernel mới vào bộ nhớ. Điều này bỏ qua hoàn toàn firmware của bo mạch chủ. Quá trình này được xử lý bởi system call kexec.

Bắt đầu nhanh: Lần đầu khởi động lại với kexec

Để sử dụng tính năng này, bạn cần gói kexec-tools. Công cụ này là cầu nối giữa shell và các hàm kexec nội bộ của kernel.

1. Cài đặt các công cụ

Dành cho các hệ thống dựa trên Ubuntu hoặc Debian:

sudo apt update && sudo apt install kexec-tools

2. Xác định vị trí Kernel mục tiêu

Bạn phải trỏ kexec đến đúng kernel và initrd (initial RAM disk) mà bạn muốn khởi động. Các tệp này nằm trong thư mục /boot. Thông thường, bạn sẽ muốn chọn phiên bản cao nhất hiện có.

ls /boot/vmlinuz* /boot/initrd.img*

3. Nạp sẵn (Stage) Kernel mới

Bước này nạp kernel vào một vùng bộ nhớ được dự phòng mà chưa chạy nó ngay. Hãy thay thế các trình giữ chỗ bằng đường dẫn tệp thực tế của bạn:

sudo kexec -l /boot/vmlinuz-$(uname -r) \
--initrd=/boot/initrd.img-$(uname -r) \
--reuse-cmdline
  • -l: Nạp kernel vào bộ nhớ.
  • --initrd: Trỏ đến image của RAM disk.
  • --reuse-cmdline: Sao chép các tham số khởi động hiện tại (như UUID của root và cài đặt console) sang kernel mới.

4. Kích hoạt bước nhảy

Khi bạn đã sẵn sàng chuyển đổi, hãy chạy:

sudo kexec -e

Phiên SSH của bạn sẽ bị treo ngay lập tức. Trong vòng 20 đến 30 giây, máy chủ sẽ trực tuyến trở lại sau khi đã bỏ qua toàn bộ trình tự BIOS.

kexec hoạt động như thế nào bên dưới lớp vỏ

System call kexec_load chính là động cơ ở đây. Khi bạn nạp sẵn một kernel, hệ điều hành sẽ cấp phát các trang bộ nhớ không liên tục để lưu trữ image mới. Để tránh ghi đè lên bộ nhớ hiện đang được kernel đang hoạt động sử dụng, kexec sử dụng một “control page” chứa mã máy đặc thù cho kiến trúc.

Một khi bạn thực hiện bước nhảy (-e), hệ thống sẽ tuân theo một trình tự nghiêm ngặt:

  1. Kernel hiện tại tắt các hệ thống con như mạng và lưu trữ một cách sạch sẽ nhất có thể.
  2. CPU vô hiệu hóa tất cả các ngắt (interrupts).
  3. Mã điều khiển di chuyển image kernel mới vào đích bộ nhớ liên tục cuối cùng của nó.
  4. CPU nhảy trực tiếp đến điểm bắt đầu (entry point) của kernel mới.

Vì phần cứng không bao giờ mất điện, CPU không bao giờ quay lại vector reset. Thực tế là bạn đang tráo đổi “bộ não” của máy chủ trong khi cơ thể vẫn thức.

Cách dùng nâng cao: Tích hợp với systemd

Nạp kernel thủ công chỉ phù hợp cho việc thử nghiệm một lần, nhưng môi trường production yêu cầu sự tự động hóa. Hầu hết các bản phân phối hiện đại đều sử dụng systemd để quản lý quá trình này một cách an toàn.

Kiểm tra trạng thái nạp

Bạn có thể xác nhận xem một kernel đã được nạp sẵn và sẵn sàng chưa bằng cách kiểm tra một tệp ảo trong hệ thống tệp sysfs:

cat /sys/kernel/kexec_loaded

Giá trị 1 nghĩa là bạn đã sẵn sàng để nhảy; 0 nghĩa là chưa có kernel nào được nạp.

Cách tiếp cận an toàn hơn với systemd

Sử dụng kexec -e khá là “thô bạo”. Nó không phải lúc nào cũng cho các dịch vụ đủ thời gian để dừng lại. Thay vào đó, hãy sử dụng wrapper của systemd, điều này đảm bảo các cơ sở dữ liệu flush buffer và các hệ thống tệp được unmount đúng cách trước khi tráo đổi kernel:

sudo systemctl kexec

Tôi khuyên dùng cách này cho các node cơ sở dữ liệu. Nó mang lại tốc độ của kexec cùng với sự toàn vẹn dữ liệu của một lần tắt máy tiêu chuẩn.

Những lưu ý thực tế và an toàn

kexec rất mạnh mẽ, nhưng nó không phải là sự thay thế vạn năng cho việc khởi động lại. Đây là những gì tôi đã học được khi triển khai nó thực tế.

Xử lý phần cứng “bẩn”

Vì bo mạch chủ không reset, một số thiết bị phần cứng có thể vẫn ở trạng thái hoạt động. Nếu driver cho kernel mới không khởi tạo lại đúng cách một card mạng hoặc card Fiber Channel cụ thể, thiết bị đó có thể bị treo. Luôn kiểm tra kexec trên máy chủ staging mô phỏng đúng phần cứng production của bạn. Nếu một thiết bị không thể khởi động lại, bạn có thể cần thực hiện cold boot truyền thống.

Hạn chế của Secure Boot

Nếu UEFI Secure Boot đang hoạt động, lệnh kexec -l tiêu chuẩn thường thất bại với lỗi “Permission Denied”. Đây là một tính năng bảo mật để ngăn chặn các kernel không có chữ ký được nạp lén lút. Để vượt qua điều này, hãy sử dụng cờ -s (kexec -s -l ...). Điều này buộc kernel phải sử dụng cơ chế xác minh chữ ký của chính nó thay vì tiện ích ở user-space.

Khi nào nên dùng Cold Boot

Kexec chỉ cập nhật lớp phần mềm. Nếu bạn đang cập nhật firmware BIOS/UEFI, thay đổi cấu hình RAID hoặc thay RAM vật lý, bạn phải thực hiện reboot tiêu chuẩn. Kexec không thể áp dụng các thay đổi cấu hình ở cấp độ phần cứng.

Lời kết

Bằng cách đưa systemctl kexec vào các script vá lỗi của mình, bạn có thể giảm thời gian ngừng hoạt động từ 10 phút xuống còn chưa đầy 60 giây. Nó biến một sự kiện bảo trì căng thẳng thành một sự gián đoạn nhỏ. Hãy sử dụng nó cho các bản cập nhật kernel định kỳ để giữ cho dịch vụ của bạn luôn phản hồi nhanh và người dùng luôn hài lòng.

Share: