Sau bài này bạn làm được: đọc ps/top để biết process đang chờ gì; gửi đúng tín hiệu (TERM vs KILL); hiểu vì sao app “bị kill không báo”; đọc sơ cgroup v2 và thấy đường nối tới limit trong container orchestrator.
Process là inode sống: PID, PPID, state
ps auxww | head
ps -eo pid,ppid,stat,cmd --sort=pid | tail
Cột STAT (ví dụ):
Ssleeping interruptibleRrunningDuninterruptible sleep (thường I/O kernel — khó kill)Zzombie (đã exit nhưng parent chưawait)
Zombie: không “ăn” RAM như process sống, nhưng chiếm slot PID; parent bug có thể làm cạn PID space hiếm gặp nhưng đau.
Tín hiệu: SIGTERM là yêu cầu, SIGKILL là án tử hình
| Signal | Hành vi điển hình |
|---|---|
SIGTERM (15) | Daemon bắt được, graceful shutdown |
SIGINT (2) | Ctrl+C — tương tự graceful cho CLI |
SIGKILL (9) | Kernel kill ngay — không bắt được để dọn resource userspace |
Ops: kill -9 là biện pháp cuối; nếu process ở D state, kill có thể không giải quyết — cần kernel/fs fix hoặc reboot node.
kill -TERM "$PID"
sleep 2
kill -0 "$PID" 2>/dev/null && echo still_alive
OOM killer: khi kernel phải chọn nạn nhân
Khi RAM+cấu hình overcommit đẩy hệ thống tới wall, OOM killer có thể chọn process để kill để cứu hệ thống.
# Xem log OOM (journald)
journalctl -k --grep -i oom --no-pager | tail
dmesg -T | grep -i oom | tail
Giảm thiểu: MemoryMax= / MemoryHigh= trong systemd; cgroup limit trong K8s; tuning JVM/Go heap; swap (trade-off latency).
ulimit và /etc/security/limits.conf
ulimit điều chỉnh giới hạn per-session / PAM — dễ gây nhầm với cgroup.
ulimit -n
# số file descriptor mở tối đa cho shell hiện tại
Ứng dụng: reverse proxy mở nhiều connection — thiếu nofile gây too many open files. Chỉnh:
- systemd:
LimitNOFILE=trong unit /etc/security/limits.d/*.confcho login session (PAM)
Kiểm tra limit thực của process:
PID=$(pgrep -f nginx | head -1)
tr '\0' '\n' < /proc/$PID/limits
cgroup: nhóm process + giới hạn tài nguyên
cgroup v1 nhiều hierarchy; cgroup v2 (unified) là mặc định trên kernel mới — Docker/K8s hiện đại dựa trên v2.
# Mount và controllers (tóm tắt)
findmnt -no TARGET /sys/fs/cgroup
ls /sys/fs/cgroup | head
Ý tưởng: mỗi group có file knob như memory.max, cpu.max. systemd tạo slice (user.slice, system.slice) và scope cho service.
systemctl show nginx.service -p MemoryCurrent -p MemoryMax --no-pager
Namespace nhanh (để không nhầm với cgroup)
- cgroup giới hạn tài nguyên.
- namespace cô lập quan điểm (mount, PID, net, user…).
Container = cgroup + namespaces (+ capabilities, seccomp…).
nice / ionice — ưu tiên mềm
Chúng điều chỉnh scheduling chứ không hard-cap như cgroup CPU quota. Hữu ích cho batch job trên node chia sẻ nhưng không thay thế limit cho multi-tenant.
Liên hệ bài trước / sau
Câu hỏi hay gặp
1. “top hiện load average cao nhưng CPU idle?”
Uninterruptible I/O (D), hoặc runnable threads chờ CPU khác — đọc vmstat 1, iostat -xz.
2. “Container limit 512Mi nhưng free -h trong container vẫn thấy RAM host?”free trong container thường phản ánh cgroup view tuỳ libc/tooling — đừng tin một lệnh; dùng cat /sys/fs/cgroup/memory.current (đường dẫn cgroup đổi theo runtime).
3. “Tôi nên set LimitNOFILE bao nhiêu?”
Đo từ workload + hệ số an toàn; “một tỉ” có thể làm overhead kernel; benchmark thực tế.
Bài tiếp theo trong loạt
→ Phần 7: Lưu trữ — disk, inode, filesystem — khi df báo còn dung lượng nhưng không ghi được file.