Khi nào bạn thực sự cần PXE Boot?
Lần đầu mình cần cài Ubuntu cho 12 máy chủ mới nhập về cùng lúc, cách duy nhất lúc đó là cắm USB boot vào từng cái, ngồi bấm Next → Next → Install suốt buổi chiều. Mất gần 4 tiếng, chưa kể sau đó còn phải cấu hình thủ công từng máy. Từ hôm đó mình quyết định dựng PXE Boot Server.
PXE (Preboot eXecution Environment) cho phép máy tính khởi động qua card mạng thay vì USB hay DVD, rồi tải OS installer trực tiếp từ server nội bộ. Với office 50 người và datacenter nhỏ như mình, đây là thứ tiết kiệm thời gian nhất từ trước đến nay. Cài 10 máy cùng lúc. Không cần USB. Không cần ngồi canh — chỉ cần boot máy lên và ra về.
Kiến trúc PXE Boot hoạt động ra sao
Nắm được flow này trước sẽ giúp bạn debug nhanh hơn nhiều lần khi gặp sự cố:
- Máy client khởi động, BIOS/UEFI gửi DHCP Discover với option PXE
- DHCP Server trả IP + địa chỉ TFTP server + tên file bootloader
- Client tải bootloader (pxelinux.0 hoặc grubx64.efi) qua TFTP
- Bootloader hiển thị menu, user chọn OS cần cài
- Kernel + initrd được tải qua TFTP, OS installer chạy, mount NFS hoặc HTTP để lấy file cài đặt
Ba thành phần bắt buộc: DHCP server (dnsmasq hoặc isc-dhcp-server), TFTP server (tftpd-hpa), và NFS/HTTP server để serve OS images.
Cài đặt các thành phần cần thiết
Mình dùng Ubuntu 22.04 làm PXE server. Cài hết một lượt:
sudo apt update
sudo apt install -y dnsmasq tftpd-hpa nfs-kernel-server syslinux-common pxelinux
Nếu đang chạy systemd-resolved thì phải tắt đi — nó chiếm port 53, xung đột thẳng với dnsmasq:
sudo systemctl disable --now systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
Gán IP tĩnh cho interface mạng của PXE server — mình dùng 192.168.10.1 trên interface eth1 (interface riêng cho management network):
# /etc/netplan/99-pxe.yaml
network:
version: 2
ethernets:
eth1:
addresses: [192.168.10.1/24]
dhcp4: false
sudo netplan apply
Cấu hình chi tiết từng thành phần
1. DHCP + TFTP với dnsmasq
Mình chọn dnsmasq thay vì isc-dhcp-server vì config gọn hơn, dễ đọc hơn, và tích hợp sẵn TFTP proxy không cần cài thêm gì. Tạo file cấu hình:
sudo nano /etc/dnsmasq.d/pxe.conf
# Interface phục vụ
interface=eth1
bind-interfaces
# DHCP range cho management network
dhcp-range=192.168.10.100,192.168.10.200,12h
# TFTP server
enable-tftp
tftp-root=/srv/tftp
# PXE boot file — BIOS
dhcp-boot=pxelinux/pxelinux.0
# PXE boot file — UEFI (nếu cần hỗ trợ UEFI)
# dhcp-match=set:efi-x86_64,option:client-arch,7
# dhcp-boot=tag:efi-x86_64,grubx64.efi
# Log để debug
log-dhcp
log-facility=/var/log/dnsmasq.log
sudo systemctl restart dnsmasq
sudo systemctl enable dnsmasq
2. Cấu trúc thư mục TFTP
Copy bootloader vào TFTP root:
sudo mkdir -p /srv/tftp/pxelinux
# Copy pxelinux bootloader
sudo cp /usr/lib/PXELINUX/pxelinux.0 /srv/tftp/pxelinux/
# Copy các module cần thiết
sudo cp /usr/lib/syslinux/modules/bios/{ldlinux,menu,vesamenu,libutil,chain}.c32 /srv/tftp/pxelinux/
# Tạo thư mục chứa menu config
sudo mkdir -p /srv/tftp/pxelinux/pxelinux.cfg
3. Tạo PXE Boot Menu
File menu mặc định áp dụng cho tất cả client chưa có config riêng. Timeout 100 nghĩa là 10 giây trước khi tự boot entry đầu tiên:
sudo nano /srv/tftp/pxelinux/pxelinux.cfg/default
UI vesamenu.c32
TIMEOUT 100
PROMPT 0
MENU TITLE PXE Boot Menu — IT From Zero
LABEL ubuntu2204
MENU LABEL Ubuntu 22.04 LTS (x64)
KERNEL ubuntu22.04/vmlinuz
APPEND initrd=ubuntu22.04/initrd root=/dev/nfs nfsroot=192.168.10.1:/srv/nfs/ubuntu22.04 ip=dhcp quiet splash
LABEL ubuntu2404
MENU LABEL Ubuntu 24.04 LTS (x64)
KERNEL ubuntu24.04/vmlinuz
APPEND initrd=ubuntu24.04/initrd root=/dev/nfs nfsroot=192.168.10.1:/srv/nfs/ubuntu24.04 ip=dhcp quiet splash
LABEL local
MENU LABEL Boot from local disk
LOCALBOOT 0
4. Mount ISO và chuẩn bị NFS
Download Ubuntu ISO, mount và export qua NFS:
# Tạo thư mục
sudo mkdir -p /srv/nfs/ubuntu22.04
sudo mkdir -p /mnt/ubuntu22.04
# Download ISO (hoặc copy từ USB)
wget https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso -O /tmp/ubuntu22.04.iso
# Mount ISO
sudo mount -o loop /tmp/ubuntu22.04.iso /mnt/ubuntu22.04
# Copy toàn bộ nội dung ISO vào NFS share
sudo rsync -av /mnt/ubuntu22.04/ /srv/nfs/ubuntu22.04/
# Copy kernel và initrd vào TFTP
sudo mkdir -p /srv/tftp/ubuntu22.04
sudo cp /srv/nfs/ubuntu22.04/casper/vmlinuz /srv/tftp/ubuntu22.04/
sudo cp /srv/nfs/ubuntu22.04/casper/initrd /srv/tftp/ubuntu22.04/
Cấu hình NFS export:
sudo nano /etc/exports
/srv/nfs/ubuntu22.04 192.168.10.0/24(ro,sync,no_subtree_check,no_root_squash)
/srv/nfs/ubuntu24.04 192.168.10.0/24(ro,sync,no_subtree_check,no_root_squash)
sudo exportfs -ra
sudo systemctl restart nfs-kernel-server
sudo systemctl enable nfs-kernel-server
5. Mẹo hay: Cấu hình PXE riêng theo MAC address
Đây là tính năng mình dùng nhiều nhất khi cần cài OS khác nhau cho từng máy. Tên file phải khớp đúng MAC, prefix 01- là cố định cho Ethernet:
# Format: 01-aa-bb-cc-dd-ee-ff
sudo nano /srv/tftp/pxelinux/pxelinux.cfg/01-aa-bb-cc-dd-ee-ff
# Máy này sẽ tự động boot Ubuntu 24.04
DEFAULT ubuntu2404
LABEL ubuntu2404
KERNEL ubuntu24.04/vmlinuz
APPEND initrd=ubuntu24.04/initrd root=/dev/nfs nfsroot=192.168.10.1:/srv/nfs/ubuntu24.04 ip=dhcp quiet splash
Cực kỳ tiện khi nhập lô máy mới — tạo sẵn config cho từng MAC, bật máy lên là tự chạy đúng OS installer. Không cần ngồi canh từng cái.
Kiểm tra và Monitoring
Kiểm tra TFTP hoạt động
# Cài tftp client để test
sudo apt install tftp-hpa
# Test download file từ TFTP server
tftp 192.168.10.1
tftp> get pxelinux/pxelinux.0
tftp> quit
# Kiểm tra file đã download chưa
ls -lh pxelinux.0
Xem log DHCP real-time
# Theo dõi client nào đang request PXE
sudo tail -f /var/log/dnsmasq.log | grep -E "DHCP|PXE|TFTP"
# Hoặc dùng journalctl
sudo journalctl -u dnsmasq -f
Client boot PXE thành công sẽ cho ra log kiểu này — nhìn thấy dòng sent pxelinux.0 là ổn:
dnsmasq-dhcp: DHCPDISCOVER(eth1) aa:bb:cc:dd:ee:ff
dnsmasq-dhcp: DHCPOFFER(eth1) 192.168.10.105 aa:bb:cc:dd:ee:ff
dnsmasq-tftp: sent /srv/tftp/pxelinux/pxelinux.0 to 192.168.10.105
Kiểm tra NFS export
# Xem danh sách export hiện tại
showmount -e 192.168.10.1
# Test mount từ client
sudo mount -t nfs 192.168.10.1:/srv/nfs/ubuntu22.04 /mnt/test
ls /mnt/test
Script kiểm tra nhanh toàn bộ stack
#!/bin/bash
# check-pxe.sh — kiểm tra nhanh PXE server
echo "=== PXE Server Health Check ==="
echo -n "[dnsmasq] "
systemctl is-active dnsmasq
echo -n "[tftpd] "
systemctl is-active tftpd-hpa
echo -n "[nfs] "
systemctl is-active nfs-kernel-server
echo -n "[TFTP dir] "
ls /srv/tftp/pxelinux/pxelinux.0 &>/dev/null && echo "OK" || echo "MISSING"
echo -n "[NFS exp] "
showmount -e localhost 2>/dev/null | grep -q srv && echo "OK" || echo "NO EXPORTS"
echo "===="
chmod +x check-pxe.sh
./check-pxe.sh
Vài điều rút ra từ thực tế
- Firewall trước tiên: Mở UDP 67/68 (DHCP), UDP 69 (TFTP), TCP 2049 (NFS). Quên cái này là ngồi debug mãi không ra — mình đã bị lần đó rồi.
- UEFI vs BIOS: Máy mới từ 2020 trở đi hầu hết là UEFI. Cần thêm dhcp-boot riêng cho EFI và dùng grubx64.efi thay vì pxelinux.0. Comment sẵn trong file config ở trên rồi, uncomment ra là xong.
- Network switch và BIOS client: Phải bật PXE Boot trong BIOS từng máy client và kiểm tra VLAN đúng. Mình từng mất đúng 1 tiếng chỉ vì quên bật option này trên managed switch — ngồi nhìn client broadcast hoài mà DHCP server im thin thít.
- NFS thay vì TFTP cho file lớn: ISO Ubuntu server là 1.4GB+. TFTP chậm và không ổn định với file lớn. Chỉ dùng TFTP cho bootloader và kernel, còn lại để NFS lo.
- Lên một tầng nữa với preseed/kickstart: Kết hợp preseed (Ubuntu) hoặc kickstart (RHEL/Rocky) để cài hoàn toàn không cần tương tác — boot lên, pha cà phê, quay lại thấy máy đã cài xong và đang chờ login.
Sau khi dựng xong PXE server, mình cài 15 máy Rocky Linux cho datacenter trong khoảng 45 phút — bao gồm cả thời gian uống cà phê. So với cách cũ cắm USB từng cái thì không có gì so sánh được.
