Tài liệu gốc
Lộ trình học Linux
Từ user thành thạo đến systems engineer. Sáu phase, mỗi phase một câu hỏi cần trả lời và một thứ chạy được phải làm ra.
Giả định & ràng buộc
- Nhịp: khoảng 4h/tuần, chia thành các phiên 2 tiếng — xem kế hoạch theo phiên.
- Tổng: 40 phiên. Với nhịp 4h/tuần là khoảng 20 tuần; chậm hơn thì giãn ra, đừng nhồi.
- Nền giả định: dùng Linux hằng ngày, đã vận hành server thật và chạy container ở môi trường có người dùng. Bỏ qua toàn bộ phần nhập môn (cd/ls/permission cơ bản).
- Nguyên tắc: không đọc sách tuyến tính. Mỗi phase có một câu hỏi cần trả lời và một artifact phải làm ra. Sách là tra cứu.
Nguyên tắc học
- Mỗi phase kết thúc bằng một thứ chạy được, không phải một tập note.
- Không test trên server production. Mọi thứ chạy trên VM throwaway (Phase 0).
- Gặp lệnh lạ → đọc
mansection 2/5/7 trước khi đọc blog.man 7 namespaces,man 5 proc,man 2 clonelà tài liệu chất lượng cao nhất và luôn đúng version. - Note theo dạng câu hỏi → thí nghiệm → kết quả, không phải tóm tắt sách.
- Nếu một khái niệm không giải thích được bằng lời trong 2 phút → chưa nắm, quay lại làm lab.
Phase 0 — Dựng lab (tuần 1)
Mục tiêu: có môi trường được phép phá, tái tạo trong dưới 2 phút.
- Dựng VM Ubuntu Server bằng
libvirt/virt-installtrên host lab. - Bật serial console (
console=ttyS0) để xem kernel log khi VM không boot được. - Học
virsh snapshot-create-as/snapshot-revert. Đây là thứ khiến việc phá hệ thống trở nên rẻ. - Viết script
lab-reset.sh: xoá VM cũ, tạo lại, cài sẵnstrace ltrace perf bpftrace linux-tools-common build-essential.
Artifact: script dựng lại lab từ đầu bằng một lệnh.
Giáo trình đã soạn: Phiên 1
Phase 1 — Process, file descriptor, signal (tuần 2–5)
Đây là tầng nền. Mọi thứ về sau (container, systemd, debug) đều quy về đây.
Nội dung
fork/exec/wait, exit status, zombie, orphan, reparent về PID 1.- File descriptor thật sự là gì: bảng fd → open file description → inode. Vì sao
dup2và redirect hoạt động. - Process group, session, controlling terminal, vì sao Ctrl+C giết cả nhóm, vì sao
nohupvàsetsidkhác nhau. - Signal: signal disposition,
SIGKILL/SIGSTOPkhông chặn được, signal trong quá trình shutdown container (SIGTERM→ grace period →SIGKILL). /proc/<pid>/:status,fd/,maps,cmdline,limits,cgroup.
Đọc
- TLPI ch. 24–28 (process creation, termination, monitoring, exec), ch. 20–22 (signal).
man 5 proc— đọc dần, không đọc hết.
Lab
- Viết C nhỏ: fork → con exit → cha ngủ 30s. Quan sát zombie trong
ps. Sửa bằngwaitpid. - Chạy một service self-host, dùng
ls -l /proc/<pid>/fdliệt kê nó đang giữ file/socket nào. Đối chiếu vớiss -tlnp. strace -f -e trace=openat,connectmột tiến trình khởi động để xem nó đọc config từ đâu — kỹ năng debug dùng được ngay trong công việc.- Gửi
SIGTERMcho container, đo thời gian tới khi bịSIGKILL. Đối chiếudocker stop --time.
M-L1 — kiểm tra: giải thích được vì sao process trong container thấy PID 1 là chính nó; vì sao đóng shell làm chết process con nhưng setsid thì không.
Phase 2 — Memory, page cache, OOM (tuần 6–8)
Phase trả lời cho các sự cố production dạng “máy còn RAM mà vẫn chết” và “disk đầy nhưng xoá file không giải phóng”.
Nội dung
- Virtual memory, page table, RSS vs VSZ vs PSS — vì sao cộng RSS của tất cả process ra số lớn hơn RAM thật.
- Page cache, dirty page, writeback,
fsyncsemantics. Vì sao ghi file xong mất điện là mất dữ liệu. - OOM killer:
oom_score,oom_score_adj, cách đọc dòng OOM trongdmesg. - Swap và
vm.swappiness; vì sao tắt swap không phải lúc nào cũng đúng. - cgroup v2 memory controller:
memory.max,memory.high,memory.stat,memory.events.
Đọc
- TLPI ch. 6 (memory layout), ch. 49 (mmap), ch. 13 (buffering, fsync).
man 5 procphầnmeminfo,smaps.- Kernel doc:
Documentation/admin-guide/cgroup-v2.rst— phần Memory.
Lab
- Đọc một file lớn, quan sát
free -mphầnbuff/cachetăng. Drop cache, đo lại thời gian đọc. - Tạo cgroup v2, set
memory.max=100M, chạy chương trình cấp phát dần → đọcmemory.eventsvà dòng OOM trongdmesg. - Mô phỏng “xoá file mà disk không giảm”: xoá file trong khi một process còn giữ fd, quan sát bằng
lsof +L1. Đây là bug hay gặp với log file.
M-L2 — kiểm tra: đọc một dòng OOM kill trong dmesg và nói được process nào bị giết, vì sao nó chứ không phải process khác.
Phase 3 — Filesystem, mount, overlayfs (tuần 9–11)
Phase khớp trực tiếp với dạng sự cố kinh điển: container update xong thì dữ liệu biến mất.
Nội dung
- VFS, inode, dentry, hardlink vs symlink, vì sao
mvtrong cùng filesystem là O(1). - Mount, bind mount, mount propagation (
shared/private/slave) — nguyên nhân sâu xa của nhiều lỗi volume trong Docker. - overlayfs: lowerdir/upperdir/workdir. Đây chính là cơ chế image layer của Docker.
- Docker volume vs bind mount vs anonymous volume — cái nào biến mất khi service update.
- LVM cơ bản: PV/VG/LV, snapshot, mở rộng LV online.
Đọc
- TLPI ch. 14 (filesystem), ch. 18 (directories, links).
man 8 mountphần propagation,man 5 tmpfs.- Kernel doc:
Documentation/filesystems/overlayfs.rst.
Lab
- Dựng overlayfs bằng tay: 3 thư mục +
mount -t overlay. Sửa file ở upper, quan sát whiteout khi xoá file của lower. - Tái dựng một sự cố mất dữ liệu trên lab: chạy container có state trong anonymous volume,
docker service update --force, quan sát dữ liệu đi đâu. Rồi làm lại với named volume và bind mount. - Tạo LV, snapshot, phá dữ liệu, restore từ snapshot.
M-L3 — kiểm tra: vẽ được đường đi từ một file trong container tới vị trí thật của nó trên host.
Phase 4 — Namespace, cgroup, viết container từ đầu (tuần 12–15)
Phase có ROI cao nhất: sau phase này Docker Swarm không còn là hộp đen.
Nội dung
- 8 namespace: mount, PID, net, UTS, IPC, user, cgroup, time. Cái nào Docker dùng mặc định.
clone(2)flags,unshare(1),nsenter(1).pivot_rootvschroot, vì sao container dùng cái đầu.- cgroup v2 unified hierarchy, delegation,
systemdquản cgroup ra sao. - capabilities, seccomp, no-new-privs — vì sao container không phải sandbox bảo mật thật.
Đọc
man 7 namespaces,man 7 user_namespaces,man 7 capabilities— đọc kỹ, đây là nguồn chính.- TLPI ch. 28 (clone), ch. 39 (capabilities).
- Loạt bài namespaces của Michael Kerrisk trên LWN.
Lab
unshare --pid --fork --mount-proc bash→ chạyps aux, thấy PID 1 là bash của mình.- Viết mini-container: shell script, hoặc một chương trình nhỏ bằng ngôn ngữ có binding syscall (Rust với
nix, Go, C) — tạo namespace,pivot_rootvào rootfs giải nén từ image, set cgroup limit, exec/bin/sh. nsentervào namespace của một container đang chạy để debug mà không cầndocker exec.
M-L4 — artifact: chương trình dưới 200 dòng chạy được process cô lập PID + mount + net, có giới hạn memory, không dùng Docker.
Phase 5 — Network stack (tuần 16–19)
Phase giải thích overlay network của Swarm.
Nội dung
- netns, veth pair, bridge, routing table,
ipcommand toàn bộ (bỏifconfig/route). - iptables vs nftables (Ubuntu hiện dùng nft backend), chain, table, hook điểm nào trong netfilter.
- conntrack, NAT, vì sao
docker-proxytồn tại. - VXLAN — nền tảng overlay network của Docker Swarm; MTU và vấn đề phân mảnh.
ss,tcpdump, đọc TCP handshake và retransmission.
Đọc
man 8 ip,man 7 netdevice.- Sơ đồ packet flow của netfilter (bản đồ hook) — in ra dán bàn.
- TLPI ch. 56–61 (socket) — tra cứu khi cần.
Lab
- Dựng bằng tay: 2 netns nối qua veth + bridge, ping được nhau. Không dùng Docker.
- Thêm NAT bằng nftables để netns ra được internet.
- Dựng VXLAN tunnel giữa 2 VM, cho 2 netns ở 2 máy khác nhau ping nhau. So sánh với
docker network inspectcủa overlay network thật. tcpdumpmột request đi qua Swarm ingress, xác định đúng các chặng NAT.
M-L5 — kiểm tra: giải thích được đường đi của gói tin từ client tới container trong Swarm, kể tên đúng các thành phần.
Phase 6 — Observability & performance (tuần 20–26)
Phase tạo khác biệt lớn nhất về mặt nghề nghiệp.
Nội dung
- USE method (Utilization, Saturation, Errors) và cách áp cho CPU/memory/disk/network.
perf: sampling,perf record/report, flame graph.- eBPF:
bpftraceone-liner,bcctools (execsnoop,opensnoop,biolatency,tcplife). - Latency analysis: đo ở đâu, vì sao average vô dụng, percentile và coordinated omission.
- Phân biệt bottleneck: CPU-bound vs I/O-bound vs lock contention.
Đọc
- Systems Performance (Brendan Gregg, 2nd ed) — ch. 2 (methodology), 6 (CPU), 7 (memory), 9 (disk), 10 (network). Đây là sách chính của phase.
- BPF Performance Tools (Gregg) — dùng như catalogue công cụ.
Lab
- Chọn một service self-host thật, áp USE method đầy đủ, viết report một trang.
- Gây tải bằng
stress-ng/fio, xác định bottleneck trước khi xem đáp án, rồi kiểm chứng. biolatencytrên một service I/O nặng, đối chiếu với latency thấy ở tầng ứng dụng.- Vẽ một flame graph CPU cho một workload CPU-bound thật.
M-L6 — artifact: một bài phân tích hiệu năng thật (nêu triệu chứng → giả thuyết → phép đo → kết luận), đủ chất lượng để người khác đọc và tái lập được.
Xen kẽ (rải rác, không chiếm slot riêng)
systemd — học khi cần, không học một lượt: unit type, dependency (After vs Requires), systemd-analyze blame, timer thay cron, journalctl -u --since, resource control qua cgroup (MemoryMax=, CPUQuota=).
Boot process — một buổi: firmware → GRUB → initramfs → PID 1. Làm hỏng initramfs trên lab rồi cứu bằng rescue mode. Một lần là nhớ mãi.
Security cơ bản — AppArmor trên Ubuntu (không phải SELinux), SSH hardening, auditd khi cần điều tra.
Sau lộ trình này — nhánh kernel
Chỉ vào sau khi đã có nền OS thực hành — tự viết được một kernel nhỏ chạy trên máy ảo. Vào sớm hơn thì loãng.
- OSTEP — miễn phí, đọc để có khung khái niệm OS.
- Slide training của Bootlin — kernel/driver/embedded, chất lượng cao, miễn phí.
- LFD103 (Linux Foundation) — miễn phí, hướng dẫn quy trình đóng góp kernel thật.
- Mục tiêu thực tế: đọc hiểu được một subsystem nhỏ và gửi được một patch cleanup, không phải “hiểu cả kernel”.
Reading list — mua/lấy theo thứ tự cần
| Sách | Dùng vào | Cách dùng | Ưu tiên |
|---|---|---|---|
| The Linux Programming Interface (Kerrisk) | Phase 1–5 | Tra cứu theo chương, không đọc tuyến tính | Cao, mua sớm |
| Systems Performance 2nd ed (Gregg) | Phase 6 | Đọc xuyên ch. 2, còn lại tra | Cao |
| BPF Performance Tools (Gregg) | Phase 6 | Catalogue công cụ | Trung bình |
| Linux System Programming (Love) | Phase 1–3 | Bản rút gọn của TLPI nếu TLPI nặng | Tuỳ chọn |
| Understanding the Linux Kernel | Nhánh kernel | Cũ nhưng khung vẫn đúng | Thấp, để sau |
| man-pages (miễn phí) | Toàn bộ | Nguồn chính, không phải phụ | Bắt buộc |
Nguồn miễn phí bám sát: man 7 *, kernel Documentation/, blog Julia Evans, LWN.
Bẫy thường gặp
- Học lệnh thay vì học khái niệm. Thuộc 50 flag của
ipmà không hiểu netns thì vẫn không debug được. Cứ hỏi “cái này ở tầng nào của kernel”. - cgroup v1 vs v2. Rất nhiều blog cũ viết cho v1. Ubuntu mới mặc định v2 unified. Kiểm tra bằng
stat -fc %T /sys/fs/cgrouptrước khi làm theo bất kỳ hướng dẫn nào. - iptables vs nftables. Ubuntu dùng
iptables-nft— lệnh iptables vẫn chạy nhưng rule thật nằm ở nft. Xem bằngnft list rulesetđể tránh nhầm lẫn. - Đọc nhiều, làm ít. Tỉ lệ mục tiêu: 1 phần đọc, 2 phần lab.
- Nhồi cả TLPI. 1500 trang, đọc tuyến tính là bỏ cuộc ở tuần 3.
- Học tách rời việc thật. Mỗi phase nên soi lại một sự cố có thật hoặc một hệ thống đang chạy — đó là thứ giữ động lực.
Mốc tổng kết
| Mốc | Tuần | Điều kiện đạt |
|---|---|---|
| M-L0 | 1 | Lab VM dựng lại bằng một lệnh |
| M-L1 | 5 | Đọc được /proc/<pid>/, giải thích fd và signal |
| M-L2 | 8 | Phân tích được một vụ OOM từ dmesg |
| M-L3 | 11 | Dựng overlayfs tay, giải thích được đường đi file trong container |
| M-L4 | 15 | Container tự viết, chạy được, có cgroup limit |
| M-L5 | 19 | Dựng tay được overlay network qua VXLAN |
| M-L6 | 26 | Một bài phân tích hiệu năng hoàn chỉnh trên hệ thống thật |