Docker Engine, containerd, runc và OCI
Docker CLI gọi Engine API; dockerd quản lý Docker objects và policy; lifecycle ở lớp thấp hơn được phối hợp với containerd, shim và OCI runtime. Hiểu đúng các boundary này giúp chẩn đoán lỗi pull, create/start, disk, cgroup, seccomp và security thay vì coi “Docker” là một process duy nhất.
docker là client; dockerd là control-plane của Docker Engine; containerd quản lý lifecycle/content/snapshot/task ở runtime layer; shim tách lifetime của container process khỏi daemon; runc là OCI runtime phổ biến dùng để tạo/start process theo OCI Runtime Specification.1. Architecture
| Thành phần | Vai trò chính | Boundary cần nhớ |
|---|---|---|
docker CLI | Nhận lệnh người dùng và gọi Docker Engine API. | CLI không trực tiếp tạo namespace/cgroup cho container. |
dockerd | Serve Engine API; quản lý containers, images, networks, volumes và policy/configuration của Docker. | Quyền điều khiển daemon thường tương đương quyền quản trị rất mạnh trên host. |
| containerd | Cung cấp runtime APIs cho image/content, snapshots và tasks; Docker Engine dùng containerd để tạo/start/stop container. | Implementation có thể thay đổi theo Engine version; đừng phụ thuộc vào process topology nội bộ. |
| containerd shim | Làm parent/intermediary cho container process, giữ I/O/PTY, thu exit status và cho container tiếp tục sống khi containerd restart/crash. | Container lifecycle không nhất thiết chết theo daemon quản lý. |
runc | OCI runtime tạo container process từ OCI bundle/config, thiết lập namespaces, cgroups, mounts, capabilities và security-related settings rồi thoát khỏi đường điều khiển chính. | runc không phải long-running application supervisor của container. |
OCI tạo interoperability ở đâu?
Open Container Initiative hiện duy trì ba specification chính: Image Specification mô tả image manifest/config/layers; Runtime Specification mô tả bundle, config.json, execution environment và lifecycle; Distribution Specification chuẩn hóa API protocol để phân phối content như container images. Nhờ boundary chuẩn này, image và runtime không bị khóa hoàn toàn vào một vendor implementation.
2. Create call flow
Luồng khái niệm của một lần create/run có thể đọc theo thứ tự sau. Chi tiết implementation khác nhau theo Engine version và storage backend, nhưng boundary chẩn đoán vẫn hữu ích:
- CLI → Engine API: lệnh như
docker runđược client chuyển thành nhiều API operation tớidockerd. - Resolve image: daemon/runtime kiểm tra image local; nếu thiếu thì resolve registry reference, authenticate khi cần, lấy manifest/index và chọn platform phù hợp.
- Pull và verify content: download config/layers theo digest; lỗi auth, network hoặc digest validation nằm ở phase này.
- Prepare filesystem: image layers được materialize qua storage driver/snapshotter để tạo root filesystem có writable layer cho container.
- Generate runtime configuration: Docker options được chuyển thành runtime config gồm argv/env, mounts, namespaces, cgroups/resource limits, capabilities, seccomp và các thông số platform.
- Create task/shim: containerd runtime layer tạo shim/task và invoke OCI runtime.
runccreate/start: runtime dựng isolation, mount rootfs, áp security/resource configuration rồi exec process container.- Process exit: shim thu exit status. Process đã exit không có nghĩa Docker container object/metadata tự động bị remove; removal phụ thuộc lifecycle command/policy như
--rm.
Quan sát boundary bằng command
docker version
docker info
docker inspect <container>
docker events --since 10m
docker system df
journalctl -u docker --since "10 min ago"
Nhóm lệnh này cho evidence từ client/API compatibility, daemon/storage state, container configuration, lifecycle events, disk consumption và daemon logs. Trên host dùng init/logging khác systemd, thay journalctl bằng log source tương ứng.
3. Daemon boundary và security
Docker daemon mặc định nhận request qua Unix socket /var/run/docker.sock. Người có quyền truy cập socket có thể yêu cầu daemon tạo container với host mounts hoặc cấu hình quyền rất mạnh; vì vậy Docker documentation chỉ khuyến nghị cho trusted users điều khiển daemon. Không mount Docker socket vào untrusted container và không expose TCP API không được bảo vệ.
Rootless mode
Rootless mode chạy daemon và containers mà không cần root privileges, giảm impact nếu daemon/runtime bị compromise. Trade-off là một số capability phụ thuộc kernel/user namespace/cgroup v2 và có khác biệt về storage, networking, privileged ports, AppArmor/checkpoint/overlay-network support tùy release. Vì vậy cần test workload thật thay vì giả định rootless tương đương rootful về mọi feature/performance.
4. Failure modes và cách khoanh vùng
| Failure mode | Failure window / dấu hiệu | Điểm kiểm tra đầu tiên | Recovery / rollback |
|---|---|---|---|
| Registry pull/auth/digest mismatch | Fail trước khi rootfs sẵn sàng; pull retries, 401/403, manifest/platform hoặc digest errors. | Registry reachability, credentials, image reference/digest, selected platform. | Khôi phục credential/network; pin digest đã biết tốt; tránh overwrite tag trong incident. |
| Disk đầy do layers/logs/build cache | Pull/build/create fail, writes chậm, filesystem gần 100%, inode exhaustion. | docker system df, filesystem bytes/inodes, container logs, build cache. | Giải phóng có kiểm soát, rotate logs, tăng capacity; không chạy prune mù trên production host. |
| Runtime create fail: mount/cgroup/seccomp | Image pull thành công nhưng create/start fail; daemon/runtime log có permission, mount, cgroup, OCI runtime error. | docker inspect, daemon logs, kernel/cgroup state, mount paths, seccomp/capabilities. | Revert config/resource/security-profile change; sửa host prerequisite trước khi retry hàng loạt. |
| Architecture mismatch amd64/arm64 | Manifest selection fail hoặc process trả exec format error. | docker image inspect, image index/platform, host architecture. | Dùng đúng platform image hoặc multi-arch build; chỉ dùng emulation khi performance/compatibility được chấp nhận. |
| Docker socket/API exposure | Unexpected privileged containers, mounts, image pulls, API requests hoặc host changes. | Socket permissions, remote listeners, audit/process/network logs, recent Docker events. | Revoke access/credentials, isolate host, preserve evidence; rebuild host nếu trust boundary bị phá. |
| Daemon/containerd restart/crash | Management API gián đoạn trong khi một số container process vẫn chạy nhờ shim. | Service status, shim/container processes, daemon logs, health checks. | Restart management plane có kiểm soát; xác nhận workload state trước khi recreate để tránh duplicate instances. |
5. Production signals và capacity
Không chỉ monitor “container up/down”. Với host chạy Docker Engine, nên có alert hoặc dashboard cho các signal liên quan trực tiếp đến failure modes ở trên:
- Capacity: disk bytes/inodes cho Docker/containerd data roots, image/cache growth, container log growth.
- Runtime health: create/start failure rate, restart count, OOM/cgroup pressure, daemon/containerd/shim churn.
- Registry path: pull latency/error rate, auth failures, rate limits và digest/platform mismatch.
- Host pressure: memory, CPU, filesystem latency và PID pressure; capacity plan phải chừa headroom cho pull/unpack/restart burst.
- Security: Docker socket permissions/listeners, unexpected privileged containers/host mounts, daemon config changes.
6. Version scope và điều cần không hard-code
Bài này dùng boundary ở mức concept thay vì phụ thuộc process tree cụ thể. Docker Engine documentation hiện ghi containerd image store là mặc định trên fresh install của Engine 29.0+, trong khi upgraded installation có thể vẫn dùng classic storage driver. Từ Engine 29.7 có experimental embedded-containerd mode, nhưng task shims vẫn là process riêng. Vì vậy production runbook nên kiểm tra docker info và daemon configuration trên host thật trước khi giả định storage/runtime topology.