Part 11 · Docker · 11.1.02

OCI image, layers và container lifecycle

Image là tập nội dung và metadata bất biến theo content-addressing; container dùng image làm nền rồi thêm runtime configuration, process và writable layer riêng. Hiểu lifecycle giúp phân biệt rõ “image nào được chạy”, “container đang ở state nào”, dữ liệu nào sẽ mất và cần nhìn đâu khi sự cố xảy ra.

1. Image model

Một OCI image có thể gồm image index (tuỳ chọn), image manifest, image configuration và các filesystem layer. Image index có thể tham chiếu nhiều manifest khác nhau; registry/runtime chọn manifest phù hợp platform như OS và architecture. Manifest tham chiếu config cùng danh sách layer theo descriptor/digest; config chứa metadata phục vụ runtime như command/arguments, environment và lịch sử tạo layer.

Các layer là filesystem changeset được đóng gói và định danh bằng digest. Digest là content address: nội dung thay đổi thì digest thay đổi. Ngược lại, tag là tên mutable có thể được cập nhật để trỏ sang manifest khác, vì vậy production cần phân biệt rõ “deploy theo tag” với “pin theo digest”.

Mental model: tag là nhãn dễ đọc; digest là danh tính content. Multi-platform image không phải một root filesystem duy nhất cho mọi máy — index có thể dẫn đến manifest khác nhau cho linux/amd64, linux/arm64, v.v.

2. Container states

docker create tạo container object từ image/config và chuẩn bị root filesystem nhưng chưa chạy application process. docker start khởi động main process. docker run về mặt mental model là create + start. Khi container đang chạy, PID 1 của container là process quyết định lifetime chính của container.

Createconfig + rootfs, chưa chạy app
Startkhởi động main process
Pauseđóng băng process
Stop / Restartdừng hoặc tạo process mới
Removexóa container object + writable layer
ActionĐiều gì xảy raĐiểm cần nhớ
pauseTrên Linux, Docker dùng freezer cgroup để suspend các process trong container.Pause không phải graceful shutdown; application không có cơ hội “kết thúc công việc”.
stopMain process nhận stop signal (mặc định thường là SIGTERM), rồi SIGKILL sau grace period nếu vẫn chưa thoát.Stop signal và timeout có thể cấu hình; shutdown handler cần hoàn tất trong failure window này.
restartDừng rồi khởi động process mới trên cùng container object và writable layer hiện có.Restart không biến container thành “container mới sạch”; file đã ghi trong writable layer vẫn còn.
removeXóa container object và writable layer của container.Dữ liệu chỉ nằm ở writable layer sẽ mất; volume/bind mount có lifecycle riêng.
Failure window quan trọng: nếu app không xử lý stop signal, flush buffer hoặc checkpoint kịp trước timeout, Docker có thể phải kill process. Với workload ghi dữ liệu, cần thiết kế graceful shutdown, idempotency/recovery và mount persistent storage phù hợp thay vì kỳ vọng restart sẽ “cứu” state.

3. Copy-on-write và writable layer

Các image layer là read-only và có thể được chia sẻ giữa nhiều container dùng cùng image. Mỗi container có writable layer riêng ở trên cùng. Với copy-on-write, file ở lower layer được dùng trực tiếp khi chỉ đọc; lần đầu cần sửa, storage implementation copy file lên writable layer rồi mới thay đổi.

Writable layer phù hợp với ephemeral writes, nhưng không phải nơi tốt cho large mutable data, database files hoặc log cần retention lâu dài: dữ liệu mất khi container bị remove, khó backup/di chuyển hơn, và một số workload ghi nhiều chịu overhead của storage driver/snapshotter. Process, memory và network namespace của từng container vẫn tách riêng dù image layers được chia sẻ.

Loại dữ liệuNên đặt ở đâuLý do
Scratch/cache tạm, file có thể tái tạoWritable layer hoặc tmpfs khi phù hợpKhông cần sống lâu hơn container.
Database / dữ liệu business cần persistVolume hoặc storage bên ngoài containerTách lifecycle dữ liệu khỏi lifecycle container, giảm rủi ro mất state.
Log cần lưu giữ/phân tíchLogging pipeline hoặc mount/storage được quản lýKhông phụ thuộc việc container còn tồn tại để điều tra sự cố.

Về capacity/operations, cần theo dõi disk usage của image store, container writable layers, volume và logging. Disk pressure có thể khiến pull/build/start/write thất bại dù CPU/memory còn dư; dọn dẹp image/container phải theo policy để tránh xóa nhầm artifact còn cần cho rollback.

4. Inspect and debug

Khi container lỗi, bắt đầu từ state chứ không chỉ nhìn dòng log cuối. Dùng docker inspect để xem low-level state/config, exit code và metadata; docker logs để xem output của container; docker events để correlate create/start/die/oom/stop; dùng image history/digest để xác nhận chính xác artifact nào đang chạy.

# State, exit code và OOM flag
docker inspect --format '{{json .State}}' <container>

# Log của container
docker logs --tail 200 <container>

# Event gần thời điểm lỗi
docker events --since 30m --filter container=<container>

# Xác nhận image/digest
docker inspect --format '{{.Image}}' <container>
docker image inspect <image>

“Container exited” thường chỉ có nghĩa main process/PID 1 đã kết thúc; điều đó không tự động chứng minh Docker daemon bị lỗi. Exit code 137 thường liên quan process bị SIGKILL (128 + signal 9) và có thể do OOM killer, nhưng không nên kết luận chỉ từ con số: cần kiểm tra .State.OOMKilled, Docker events và bằng chứng phía host/kernel.

Debug order: identity → state → event timeline → logs → host evidence. Trước tiên xác nhận container/image digest đúng; sau đó xem state/exit/OOM; rồi đối chiếu events và logs. Cách này tránh chẩn đoán nhầm một app crash thành daemon failure hoặc nhầm mọi exit 137 thành OOM.

5. Production guardrails: security, recovery và rollback

Operational trade-off: container được thiết kế để có thể thay thế. Càng để nhiều state quan trọng, log điều tra hoặc manual fix trong writable layer, chi phí recovery càng tăng và rollback càng kém reproducible.

6. Checklist ôn nhanh

Tài liệu: OCI Image Specification · OCI Distribution Specification · Docker Container CLI · docker container stop · docker container pause · Docker storage drivers · Docker storage