Linux / lab

Lịch chạy

Kế hoạch 40 phiên

Bản chia nhỏ của lộ trình thành 40 phiên 2 tiếng + 1 phiên linh hoạt. Đơn vị theo dõi là số phiên, không phải ngày.

Nhịp~4h/tuần
Mỗi phiên2 tiếng
Chia thời gian~40′ đọc / ~80′ lab
Tổng~20 tuần

Với nhịp 4h/tuần, 40 phiên trải ra khoảng 20 tuần. Nhịp thấp hơn thì giãn ra tương ứng — không nhồi.

Cách dùng

  • Nhịp chuẩn mỗi phiên: ~40′ đọc / ~80′ lab (giữ tỉ lệ 1 đọc : 2 lab của lộ trình gốc). Phiên nào lab là chính thì đọc rút xuống 20–30′.
  • Đơn vị theo dõi là số phiên, không phải ngày. Lab tràn thì lấy tiếp phiên sau và đẩy toàn bộ phần còn lại xuống. Một phiên trôi không phải là chậm tiến độ — nhồi hai phiên vào một buổi mới là.
  • Điều kiện đạt các mốc M-L* giữ nguyên như lộ trình gốc; cuối mỗi phase dành 15–20′ của phiên chốt để tự kiểm tra mốc.

Phase 0 — Dựng lab (P1–P2)

  • P1 — Dựng VM Ubuntu Server bằng libvirt/virt-install; bật serial console (console=ttyS0), boot và xem được kernel log. Phiên gần như toàn lab, đọc chỉ tra docs công cụ. → giáo trình
  • P2 — Học virsh snapshot-create-as / snapshot-revert; viết lab-reset.sh: xoá VM cũ, tạo lại, cài sẵn strace ltrace perf bpftrace linux-tools-common build-essential; đo thời gian tái tạo dưới 2 phút. → M-L0.

Phase 1 — Process, file descriptor, signal (P3–P8)

  • P3fork/exec/wait, exit status, zombie/orphan, reparent về PID 1. Đọc: TLPI ch. 24–25. Lab 1: C nhỏ fork → con exit → cha ngủ 30s, quan sát zombie trong ps, sửa bằng waitpid; thêm case orphan → reparent.
  • P4execwait chi tiết; tour /proc/<pid>/: status, cmdline, limits, cgroup, maps. Đọc: TLPI ch. 26–28 + man 5 proc (chỉ phần liên quan). Lab: mổ xẻ một process thật hoàn toàn qua /proc.
  • P5 — File descriptor thật sự là gì: bảng fd → open file description → inode; vì sao dup2 và redirect hoạt động. Đọc: TLPI ch. 5 (tra cứu). Lab 2: chạy một service self-host, ls -l /proc/<pid>/fd liệt kê file/socket nó giữ, đối chiếu ss -tlnp.
  • P6 — Process group, session, controlling terminal; vì sao Ctrl+C giết cả nhóm; nohup vs setsid. Lab: thí nghiệm đóng shell giết process con, rồi lặp lại với setsid.
  • P7 — Signal: disposition, handler, vì sao SIGKILL/SIGSTOP không chặn được. Đọc: TLPI ch. 20–22. Lab 3: strace -f -e trace=openat,connect một tiến trình khởi động để xem nó đọc config từ đâu.
  • P8 — Signal trong shutdown container: SIGTERM → grace period → SIGKILL. Lab 4: gửi SIGTERM cho container, đo thời gian tới khi bị SIGKILL, đối chiếu docker stop --time. Ôn cả phase. → M-L1.

Phase 2 — Memory, page cache, OOM (P9–P13)

  • P9 — Virtual memory, page table; RSS vs VSZ vs PSS. Đọc: TLPI ch. 6 + man 5 proc phần meminfo, smaps. Lab: cộng RSS toàn hệ, so với RAM thật, giải thích chênh lệch bằng PSS/smaps.
  • P10 — Page cache, dirty page, writeback, fsync semantics; vì sao ghi xong mất điện là mất dữ liệu. Đọc: TLPI ch. 13 (+ ch. 49 mmap, lướt). Lab 1: đọc file lớn, quan sát buff/cache trong free -m, drop cache, đo lại thời gian đọc.
  • P11 — OOM killer và cgroup v2 memory controller: memory.max, memory.events. Đọc: Documentation/admin-guide/cgroup-v2.rst phần Memory. Lab 2: cgroup memory.max=100M, chạy chương trình cấp phát dần, đọc memory.events + dòng OOM trong dmesg.
  • P12 — Swap và vm.swappiness; memory.high/memory.stat; oom_score/oom_score_adj. Lab: chỉnh oom_score_adj và swappiness, quan sát OOM killer chọn nạn nhân khác đi.
  • P13 — Lab 3: mô phỏng “xoá file mà disk không giảm” — xoá file khi một process còn giữ fd, quan sát bằng lsof +L1. Ôn cả phase. → M-L2.

Phase 3 — Filesystem, mount, overlayfs (P14–P18)

  • P14 — VFS, inode, dentry; hardlink vs symlink; vì sao mv cùng filesystem là O(1). Đọc: TLPI ch. 14, 18. Lab: thí nghiệm inode/link count với stat, hardlink, symlink gãy.
  • P15 — Mount, bind mount, mount propagation (shared/private/slave) — gốc rễ nhiều lỗi volume Docker. Đọc: man 8 mount phần propagation, man 5 tmpfs. Lab: tự dựng từng kiểu propagation, quan sát khác biệt.
  • P16 — overlayfs: lowerdir/upperdir/workdir — chính là cơ chế image layer của Docker. Đọc: Documentation/filesystems/overlayfs.rst. Lab 1: dựng overlayfs tay bằng mount -t overlay, sửa file ở upper, quan sát whiteout khi xoá file của lower.
  • P17 — Docker volume vs bind mount vs anonymous volume — cái nào biến mất khi service update. Lab 2: tái dựng một sự cố mất dữ liệu: state trong anonymous volume, docker service update --force, xem dữ liệu đi đâu; làm lại với named volume và bind mount.
  • P18 — LVM: PV/VG/LV, snapshot, mở rộng LV online. Lab 3: tạo LV, snapshot, phá dữ liệu, restore. Ôn cả phase. → M-L3.

Phase 4 — Namespace, cgroup, viết container từ đầu (P19–P25)

  • P19 — 8 namespace (mount, PID, net, UTS, IPC, user, cgroup, time), cái nào Docker dùng mặc định. Đọc: man 7 namespaces. Lab 1: unshare --pid --fork --mount-proc bashps aux thấy PID 1 là bash của mình.
  • P20clone(2) flags, unshare(1), nsenter(1). Đọc: TLPI ch. 28 + loạt bài namespaces của Kerrisk trên LWN. Lab 3: nsenter vào namespace của container đang chạy để debug không cần docker exec.
  • P21pivot_root vs chroot, vì sao container dùng cái đầu. Lab (mini-container bước 1): giải nén rootfs từ image, tạo mount namespace, pivot_root vào.
  • P22 — Mini-container bước 2: thêm PID namespace + mount /proc, UTS hostname riêng, exec /bin/sh. Shell script, hoặc một chương trình nhỏ bằng ngôn ngữ có binding syscall.
  • P23 — cgroup v2 unified hierarchy, delegation, systemd quản cgroup ra sao. Lab: thêm giới hạn memory cho mini-container qua cgroup v2.
  • P24 — user namespace, capabilities, seccomp, no-new-privs — vì sao container không phải sandbox bảo mật thật. Đọc: man 7 user_namespaces, man 7 capabilities, TLPI ch. 39. Lab: drop capabilities và quan sát.
  • P25 — Hoàn thiện artifact. → M-L4.

Phase 5 — Network stack (P26–P32)

  • P26 — netns, veth pair, bridge; ip command (bỏ hẳn ifconfig/route). Đọc: man 8 ip. Lab 1: 2 netns nối qua veth + bridge, ping được nhau, không Docker.
  • P27 — Routing table sâu hơn. Lab: mở rộng lab 1 — route giữa các subnet, default route, man 7 netdevice.
  • P28 — netfilter: hook, chain, table; iptables vs nftables (Ubuntu dùng iptables-nft — rule thật xem bằng nft list ruleset). In sơ đồ packet flow dán bàn. Lab: đọc ruleset trên máy có Docker, map từng rule vào sơ đồ hook.
  • P29 — conntrack, NAT, vì sao docker-proxy tồn tại. Lab 2: thêm NAT bằng nftables để netns ra được internet; xem bảng conntrack.
  • P30 — VXLAN — nền tảng overlay network của Swarm. Lab 3a: dựng VXLAN tunnel giữa 2 VM.
  • P31 — Lab 3b: cho 2 netns ở 2 máy khác nhau ping nhau qua VXLAN; so sánh với docker network inspect của overlay network thật; chú ý MTU và phân mảnh.
  • P32ss, tcpdump, đọc TCP handshake và retransmission. Lab 4: tcpdump một request đi qua Swarm ingress, xác định đúng các chặng NAT. Ôn cả phase. → M-L5.

Phase 6 — Observability & performance (P33–P40)

  • P33 — USE method (Utilization, Saturation, Errors). Đọc: Systems Performance ch. 2 — chương đọc kỹ nhất của phase. Lab: lập checklist USE cho CPU/memory/disk/network kèm công cụ đo cụ thể cho từng ô.
  • P34 — Lab 1: áp USE method đầy đủ lên một service self-host thật, viết report một trang.
  • P35perf: sampling, perf record/report, flame graph. Đọc: SP ch. 6 (CPU). Lab 4: vẽ flame graph CPU cho một pipeline xử lý document.
  • P36 — Lab 2: gây tải bằng stress-ng/fio, tự xác định bottleneck (CPU-bound vs I/O-bound vs lock contention) trước khi xem đáp án, rồi kiểm chứng.
  • P37 — eBPF: bpftrace one-liner, bcc tools (execsnoop, opensnoop, tcplife). Đọc: BPF Performance Tools — dùng như catalogue, không đọc tuyến tính.
  • P38 — Lab 3: biolatency trên một service I/O nặng, đối chiếu với latency thấy ở tầng ứng dụng. Đọc: SP ch. 9 (disk).
  • P39 — Latency analysis: vì sao average vô dụng, percentile, coordinated omission. Bắt đầu bài M-L6: chọn triệu chứng thật, đặt giả thuyết, lên kế hoạch đo.
  • P40 — Hoàn thiện bài phân tích. → M-L6.

Phiên linh hoạt

  • B1 — Boot process (1 phiên, chèn lúc nào tiện; gợi ý là sau M-L3): firmware → GRUB → initramfs → PID 1. Lab: làm hỏng initramfs trên VM lab rồi cứu bằng rescue mode. Một lần là nhớ mãi.

Xen kẽ không chiếm phiên riêng (học khi đụng việc): systemd (unit type, After vs Requires, systemd-analyze blame, timer thay cron, journalctl -u --since, MemoryMax=/CPUQuota=) và security cơ bản (AppArmor, SSH hardening, auditd).

Mốc tổng kết (theo phiên)

MốcPhiênĐiều kiện đạt
M-L0P2Lab VM dựng lại bằng một lệnh
M-L1P8Đọc được /proc/<pid>/, giải thích fd và signal
M-L2P13Phân tích được một vụ OOM từ dmesg
M-L3P18Dựng overlayfs tay, giải thích đường đi file trong container
M-L4P25Container tự viết, chạy được, có cgroup limit
M-L5P32Dựng tay overlay network qua VXLAN
M-L6P40Bài phân tích hiệu năng hoàn chỉnh trên hệ thống thật