Tháng trước mình update kernel trên một cái Raspberry Pi chạy Fedora IoT — và máy không boot lên được nữa. Không có màn hình, không có bàn phím, chỉ là một hộp đen nhỏ nằm góc phòng. Phải SSH từ máy khác vào rescue mode mới fix được. Đó là lần đầu mình thực sự hiểu tại sao Greenboot tồn tại.
Bối cảnh & Tại sao cần Greenboot
Fedora IoT và CoreOS đều dùng hệ thống file immutable dựa trên rpm-ostree — mỗi lần update tạo ra một “deployment” mới, hệ thống cũ vẫn còn nguyên. Về lý thuyết, nếu update lỗi, bạn chỉ cần boot vào deployment cũ. Nhưng trên thiết bị headless không màn hình không bàn phím, ai sẽ phát hiện ra lỗi đó và tự động kéo về bản cũ?
Đó là việc của Greenboot.
Về cơ bản, Greenboot là một framework nhỏ tích hợp với systemd. Nó chạy các script kiểm tra sức khỏe ngay sau mỗi lần boot — nếu bất kỳ script nào trong thư mục required.d fail, Greenboot đánh dấu boot hiện tại là thất bại. Sau 3 lần thất bại liên tiếp, rpm-ostree tự động rollback về deployment trước đó, không cần người can thiệp.
Mình dùng Fedora làm máy development chính được 2 năm. Update thất bại trên laptop thì khó chịu, nhưng vẫn sửa được. Với thiết bị headless cắm ở góc phòng hoặc server đặt tại data center cách xa hàng trăm kilomet thì câu chuyện hoàn toàn khác. Greenboot đặc biệt cần thiết khi:
- Thiết bị ở xa, không có access vật lý (VPS, edge device, Raspberry Pi)
- Hệ thống cần uptime cao — downtime 30 phút chờ fix thủ công là quá đắt
- Bạn bật
rpm-ostreed-automatichoặczincatiđể update tự động không giám sát
Cài đặt Greenboot
Trên Fedora IoT và CoreOS, Greenboot thường đã được cài sẵn. Kiểm tra nhanh:
rpm -q greenboot
# greenboot-0.15.0-4.fc40.noarch
Nếu chưa có, vì filesystem là immutable nên phải dùng rpm-ostree thay vì dnf:
# Fedora IoT / CoreOS
sudo rpm-ostree install greenboot greenboot-default-health-checks
# Reboot để apply
sudo systemctl reboot
Trên Fedora Workstation/Server thông thường:
sudo dnf install greenboot greenboot-default-health-checks
Sau khi cài, enable và khởi động 2 service chính:
sudo systemctl enable --now greenboot-healthcheck.service
sudo systemctl enable --now greenboot-status.service
# Kiểm tra trạng thái
sudo systemctl status greenboot-healthcheck.service
Cấu hình chi tiết
Greenboot đọc health check scripts từ hai thư mục chính:
/etc/greenboot/check/required.d/— Script bắt buộc phải pass. Fail → hệ thống bị đánh dấu unhealthy/etc/greenboot/check/wanted.d/— Script không bắt buộc. Fail → chỉ log warning, không kích hoạt rollback
Tùy vào kết quả health check, Greenboot còn chạy hai thư mục hook:
/etc/greenboot/green.d/— Chạy khi tất cả check đều pass/etc/greenboot/red.d/— Chạy khi có check fail, trước khi reboot để rollback
Script kiểm tra kết nối mạng
Exit code 0 = healthy, khác 0 = fail. Quy tắc này đơn giản nhưng cần nhớ — Greenboot không đọc output text, chỉ nhìn vào exit code của script. Mình hay bắt đầu với network check vì đây là thứ dễ bị ảnh hưởng nhất sau kernel update:
sudo nano /etc/greenboot/check/required.d/01-check-network.sh
#!/bin/bash
# Kiểm tra kết nối mạng sau boot
TIMEOUT=30
TARGET="8.8.8.8"
echo "Checking network connectivity..."
for i in $(seq 1 $TIMEOUT); do
if ping -c 1 -W 1 "$TARGET" &>/dev/null; then
echo "Network OK after ${i}s"
exit 0
fi
sleep 1
done
echo "ERROR: Network unreachable after ${TIMEOUT}s"
exit 1
sudo chmod +x /etc/greenboot/check/required.d/01-check-network.sh
Prefix số trong tên file (01-, 10-, 99-) kiểm soát thứ tự chạy. Đặt network check ở 01- vì nhiều check khác phụ thuộc vào mạng — không có nghĩa gì khi test API endpoint nếu network chưa lên.
Script kiểm tra service quan trọng
sudo nano /etc/greenboot/check/required.d/10-check-services.sh
#!/bin/bash
# Kiểm tra các service bắt buộc phải chạy
REQUIRED_SERVICES=("sshd" "NetworkManager")
for svc in "${REQUIRED_SERVICES[@]}"; do
if ! systemctl is-active --quiet "$svc"; then
echo "ERROR: Service $svc is not running"
systemctl status "$svc" --no-pager
exit 1
fi
echo "OK: $svc is active"
done
exit 0
sudo chmod +x /etc/greenboot/check/required.d/10-check-services.sh
Gửi thông báo Telegram khi boot thành công
Với thiết bị remote, biết chính xác lúc nào máy boot xong rất tiện — thay vì phải mở terminal ping thủ công. Hook trong green.d chạy sau khi tất cả health check pass, nên đây là thời điểm lý tưởng để gửi tín hiệu “tôi sống rồi”:
sudo nano /etc/greenboot/green.d/99-notify-success.sh
#!/bin/bash
HOSTNAME=$(hostname)
TOKEN="your-bot-token"
CHAT_ID="your-chat-id"
MESSAGE="✅ ${HOSTNAME} boot thành công lúc $(date '+%Y-%m-%d %H:%M')"
curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
-d "chat_id=${CHAT_ID}&text=${MESSAGE}" &>/dev/null
exit 0
Gửi cảnh báo trước khi rollback
sudo nano /etc/greenboot/red.d/99-notify-failure.sh
#!/bin/bash
HOSTNAME=$(hostname)
TOKEN="your-bot-token"
CHAT_ID="your-chat-id"
BOOT_COUNTER=$(cat /run/greenboot/boot_counter 2>/dev/null || echo "unknown")
MESSAGE="⚠️ ${HOSTNAME}: Boot health check FAILED (attempt ${BOOT_COUNTER}/3). Preparing rollback..."
curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
-d "chat_id=${CHAT_ID}&text=${MESSAGE}" &>/dev/null
exit 0
Kiểm tra & Monitoring
Chạy health check thủ công không cần reboot
# Chạy toàn bộ health check ngay lập tức
sudo systemctl start greenboot-healthcheck.service
# Xem kết quả
sudo systemctl status greenboot-healthcheck.service
# Log chi tiết từng script
sudo journalctl -u greenboot-healthcheck.service -n 50 --no-pager
Xem trạng thái deployment và boot counter
# Boot counter hiện tại (tăng mỗi lần fail, reset về 0 khi pass)
sudo grub2-editenv - list | grep boot_counter
# Xem tất cả deployments
rpm-ostree status
# Output mẫu:
# ● fedora:fedora/40/x86_64/iot
# Version: 40.20240601.0 (current)
# fedora:fedora/40/x86_64/iot
# Version: 40.20240501.0 (rollback target)
Test rollback bằng script giả lỗi
Trước khi tin tưởng Greenboot với thiết bị thật, mình luôn test thủ công. Cách nhanh nhất là tạo một script fail có chủ đích, reboot 3 lần, và xem hệ thống có tự rollback đúng không:
# Tạo script fail có chủ đích
sudo bash -c 'cat > /etc/greenboot/check/required.d/99-test-failure.sh << EOF
#!/bin/bash
echo "Simulated failure for testing"
exit 1
EOF'
sudo chmod +x /etc/greenboot/check/required.d/99-test-failure.sh
# Reboot và quan sát
sudo systemctl reboot
Sau 3 lần boot fail liên tiếp, hệ thống tự rollback về deployment cũ. Nhớ xóa script test sau khi kiểm tra xong bằng sudo rm /etc/greenboot/check/required.d/99-test-failure.sh.
Tích hợp với Zincati trên CoreOS
Trên CoreOS, Zincati lo việc tải và áp dụng update tự động. Ghép với Greenboot, bạn có một vòng lặp hoàn chỉnh không cần người giám sát: update lúc 2 giờ sáng, sáng dậy hoặc máy đang chạy bản mới ổn định, hoặc đã tự rollback về bản cũ rồi.
sudo mkdir -p /etc/zincati/config.d
sudo nano /etc/zincati/config.d/55-updates-strategy.toml
[updates]
strategy = "periodic"
[[updates.periodic.window]]
days = [ "Mon", "Wed", "Fri" ]
start_time = "02:00"
length_minutes = 60
Thứ 2, 4, 6 lúc 2 giờ sáng — tránh cuối tuần để còn người trực nếu có gì bất thường. Nếu update gây lỗi, Greenboot phát hiện ngay lần boot tiếp theo và rollback xong trước khi trời sáng.
Theo dõi log realtime
# Theo dõi tất cả Greenboot services
sudo journalctl -fu "greenboot*"
# Chỉ xem 1 giờ gần nhất
sudo journalctl -u "greenboot*" --since "1 hour ago" --no-pager
Sau khi setup xong, mình để Fedora IoT trên Raspberry Pi tự update mấy tháng không cần đụng vào. Có 1 lần kernel update bị lỗi driver WiFi, Greenboot phát hiện ngay (script check network fail), rollback tự động, và mình nhận thông báo Telegram lúc sáng sớm. Không mất downtime, không phải mò vào rescue mode như hồi trước nữa.

