This programming guide is only available in Vietnamese. Switch to Vietnamese to read the full article.

Quản trị máy chủ Linux phụ thuộc hoàn toàn vào mức độ tự động hóa. Việc chạy các tác vụ định kỳ, liên tục kiểm tra sức khỏe phần cứng, gửi cảnh báo tức thời khi có sự cố và quản lý lưu trữ log là những kỹ năng sống còn của một kỹ sư DevOps và quản trị hệ thống (SysAdmin). Bài viết này sẽ hướng dẫn bạn xây dựng hệ thống tự động hóa máy chủ chuẩn chỉnh từ A-Z.

1. Viết script giám sát tài nguyên hệ thống (CPU, RAM, Disk)

Để theo dõi trạng thái hệ thống, ta có hai hướng tiếp cận: Đọc file ảo trực tiếp từ thư mục nhân hệ điều hành /proc/ hoặc gọi các câu lệnh tiện ích wrapper.

So sánh phương pháp thu thập Metrics hệ thống

Phương pháp Cơ chế hoạt động Ưu điểm Nhược điểm & Cạm bẫy
Đọc trực tiếp từ /proc/ Mở các file ảo do kernel phơi bày như /proc/meminfo, /proc/loadavg, /proc/stat. Tốc độ cực nhanh. Không tạo thêm tiến trình con (zero fork overhead). Rất tin cậy trên các hệ thống tối giản. Dữ liệu thô, đòi hỏi kỹ năng xử lý chuỗi phức tạp bằng awk để quy đổi về đơn vị phần trăm.
Sử dụng tiện ích (free, df, top) Gọi các chương trình wrapper đã được biên dịch sẵn. Dữ liệu đã được định dạng thân thiện, dễ đọc trực quan. Khởi tạo tiến trình mới (fork), tiêu tốn một phần tài nguyên CPU nếu gọi liên tục ở tần suất cao.

Phân biệt CPU Usage (Hiệu suất CPU) & CPU Load Average (Tải trung bình)

  • CPU Usage (Phần trăm sử dụng CPU): Thể hiện tỷ lệ phần trăm thời gian hoạt động của CPU xử lý luồng không trống (non-idle processes) tại một tích tắc thời gian cụ thể.
  • CPU Load Average (Tải trung bình của hệ thống): Thể hiện số lượng tiến trình trung bình đang ở trạng thái chạy (Running) hoặc đang xếp hàng đợi CPU/I/O (Runnable/Uninterruptible Sleep) trong các khoảng thời gian 1 phút, 5 phút và 15 phút.
    Cơ chế toán học: Hệ điều hành sử dụng thuật toán trung bình trượt làm mượt theo cấp số nhân (exponentially damped moving average).
    Công thức tải lý tưởng: Load Average / Số nhân CPU (Cores). Nếu tỷ số này < 0.70, máy chủ đang hoạt động cực kỳ mượt mà. Nếu tỷ số > 1.00, hệ thống bắt đầu bị thắt nút cổ chai (tiến trình phải xếp hàng chờ xử lý).
monitor_engine.sh
# Đọc dữ liệu RAM trực tiếp từ /proc/meminfo để tránh fork lệnh free
mem_total=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
mem_free=$(awk '/MemFree/ {print $2}' /proc/meminfo)
mem_buffers=$(awk '/Buffers/ {print $2}' /proc/meminfo)
mem_cached=$(awk '/^Cached/ {print $2}' /proc/meminfo)

# Công thức tính RAM khả dụng thực tế của Linux Kernel
mem_used=$((mem_total - mem_free - mem_buffers - mem_cached))
ram_percent=$((mem_used * 100 / mem_total))

# Đo dung lượng ổ cứng phân vùng root
disk_percent=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')

# Lấy CPU Load Average 1 phút qua
cpu_load_1m=$(awk '{print $1}' /proc/loadavg)

echo "RAM: ${ram_percent}%, Disk: ${disk_percent}%, CPU Load 1m: ${cpu_load_1m}"

2. Gửi cảnh báo tức thời qua Slack / Telegram Webhooks

Việc lưu log lỗi cục bộ là chưa đủ trong môi trường sản xuất. Ta cần bắn tin nhắn JSON tới Webhook API của Telegram/Slack. Hãy sử dụng cờ --max-time hoặc --connect-timeout để tránh việc lệnh curl bị treo vô hạn nếu máy chủ gặp sự cố nghẽn mạng.

send_alert.sh
TELEGRAM_TOKEN="123456789:ABCDefGh"
CHAT_ID="-98765432"

send_telegram_alert() {
    local text_message="$1"
    # Thiết lập timeout kết nối là 5s và tổng thời gian request tối đa là 10s
    curl -s -f --connect-timeout 5 --max-time 10 \
         -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
         -d "chat_id=${CHAT_ID}" \
         -d "text=${text_message}" \
         -d "parse_mode=Markdown" > /dev/null
}

# Kiểm tra điều kiện đĩa cứng đầy
if [ "$disk_percent" -gt 85 ]; then
    send_telegram_alert "🚨 *CẢNH BÁO HỆ THỐNG* 🚨%0AMáy chủ $(hostname) sắp đầy ổ đĩa: *${disk_percent}%*!"
fi

3. So sánh chuyên sâu: Cron Jobs so với Systemd Timers

Để script chạy tự động theo chu kỳ thời gian xác định, Linux cung cấp hai bộ lập lịch (Schedulers) chính.

Lập lịch bằng Cron Jobs

Mở file cấu hình bằng crontab -e:

# Cú pháp chạy script mỗi 5 phút
*/5 * * * * /usr/local/bin/monitor_engine.sh >> /var/log/monitor.log 2>&1
[!WARNING] Cạm bẫy môi trường tối giản của Cron: Cron chạy các script dưới một shell tối giản. Biến $PATH của nó thường chỉ giới hạn ở /usr/bin:/bin. Bất kỳ câu lệnh nào được gọi trong script mà không nằm trong PATH này (hoặc không khai báo đường dẫn tuyệt đối như /usr/local/bin/my_cmd) đều sẽ báo lỗi "command not found".

Lập lịch bằng Systemd Timers

Systemd Timers là tiêu chuẩn công nghệ hiện đại thay thế cho Cron, bao gồm một file dịch vụ system-monitor.service và một file timer system-monitor.timer đặt tại /etc/systemd/system/.

Bảng so sánh chi tiết tính năng quyết định chọn lựa công nghệ

Tính năng Cron Jobs Systemd Timers
Độ phân giải thời gian Tối thiểu 1 phút. Không thể hẹn lịch theo giây. Hỗ trợ độ phân giải cấp micro giây (Microseconds).
Tích hợp ghi nhận nhật ký (Logging) Phải tự cấu hình redirect xuất file log thủ công. Khó theo dõi tập trung. Tự động tích hợp vào hệ thống log journald của OS. Xem cực dễ qua journalctl -u system-monitor.
Phục hồi lịch bị bỏ lỡ (Persistent) Không hỗ trợ. Nếu máy chủ tắt nguồn vào lúc 3:00 AM, task đó sẽ bị bỏ lỡ hoàn toàn. Hỗ trợ xuất sắc qua cờ Persistent=true. Dịch vụ tự động chạy bù ngay sau khi hệ thống khởi động lại.
Quản lý tài nguyên hệ thống Không hỗ trợ. Một cron job lỗi có thể chiếm 100% tài nguyên CPU và làm treo toàn bộ máy chủ. Hỗ trợ giới hạn tài nguyên (RAM, CPU tối đa) cho task thông qua tích hợp Cgroups trực tiếp trong file Service.

4. Quản lý xoay vòng logs tránh đầy ổ đĩa bằng logrotate

Khi script chạy liên tục, file log sẽ phình to rất nhanh. Daemon logrotate tự động xoay vòng logs để giải phóng bộ nhớ.

Bản chất cơ chế hoạt động của Logrotate

Khi xoay vòng log, logrotate có hai cơ chế chính:

  • Cơ chế Create (Mặc định): Logrotate sẽ đổi tên file log hiện tại (ví dụ: app.log thành app.log.1) rồi tạo mới một file app.log trống với quyền hạn định sẵn.
    Cạm bẫy: Các tiến trình đang ghi đè vào log cũ vẫn giữ số hiệu file descriptor (FD) trỏ vào file cũ (bây giờ đã mang tên app.log.1). Chúng ta bắt buộc phải gửi một tín hiệu (ví dụ: `kill -HUP` hoặc reload service) để báo hiệu cho ứng dụng đóng và mở lại file descriptor mới.
  • Cơ chế Copytruncate: Logrotate sao chép toàn bộ nội dung của file log đang ghi sang file backup, sau đó cắt cụt kích thước file log hiện tại về 0 byte (truncate).
    Ưu điểm: Ứng dụng không cần đóng file descriptor, không cần reload service.
    Nhược điểm: Có nguy cơ mất dữ liệu nhỏ diễn ra trong tích tắc giữa thời điểm copy xong và thời điểm bắt đầu truncate (các dòng log ghi vào đúng khoảng thời gian này sẽ bị xóa mất).

Cấu hình Logrotate chuẩn Production

Tạo cấu hình tại /etc/logrotate.d/system_monitor:

logrotate.conf
/var/log/system_check.log {
    daily              # Thực hiện hàng ngày
    rotate 7           # Giữ tối đa 7 file log đã nén
    compress           # Nén log cũ thành .gz
    delaycompress      # Hoãn nén log của ngày gần nhất để dễ đọc trực tiếp
    missingok          # Không báo lỗi nếu không tìm thấy file log
    notifempty         # Không chạy xoay vòng nếu file log rỗng
    copytruncate       # Dùng copytruncate để tránh gián đoạn tiến trình ghi log
}

5. Trắc nghiệm ôn tập

Trắc nghiệm 1: Cạm bẫy môi trường Cron

Tại sao lệnh curl gọi trong script chạy trực tiếp thì thành công nhưng chạy qua cron job lại thất bại?

Trắc nghiệm 2: Systemd Timers

Đâu là ưu điểm lớn nhất của Systemd Timers so với Cron Job truyền thống trong giám sát hệ thống?

Tải file code thực hành minh họa bài học

Tập tin script tổng hợp các lệnh kiểm tra tài nguyên hệ thống, gửi webhook và trình tự xoay vòng log:

Tải về system_automation.sh