containerd – Runtime container cốt lõi của hệ sinh thái container
containerd là một container runtime được thiết kế để quản lý vòng đời của container trên Linux và Windows. Ban đầu là một phần của Docker, containerd hiện là một dự án độc lập thuộc Cloud Native Computing Foundation (CNCF) và được sử dụng rộng rãi trong các hệ thống như Kubernetes.
containerd là gì?
containerd hoạt động như một service chạy ngầm (daemon), đảm nhiệm các nhiệm vụ cốt lõi: pull và lưu trữ container image, quản lý storage, tạo và chạy container, giám sát trạng thái container. Khác với Docker, containerd tập trung vào chức năng runtime thuần túy, không bao gồm các công cụ như Docker CLI hay Docker Compose.
Điểm đặc biệt của containerd là thiết kế modular và lightweight. Nó cung cấp API ổn định thông qua gRPC, cho phép các orchestrator như Kubernetes hoặc Docker Engine tích hợp dễ dàng. containerd tuân thủ các chuẩn OCI (Open Container Initiative), đảm bảo tính tương thích và khả năng thay thế giữa các runtime khác nhau.
Lịch sử phát triển
Năm 2016, Docker Inc. quyết định tách containerd ra khỏi Docker Engine và đóng góp cho CNCF. Quyết định này xuất phát từ nhu cầu tạo ra một runtime trung lập, không phụ thuộc vendor, có thể được sử dụng bởi nhiều platform khác nhau. Năm 2019, containerd đạt trạng thái graduated trong CNCF, đánh dấu sự trưởng thành và sẵn sàng cho production.
Một cột mốc quan trọng là khi Kubernetes 1.20 (2020) deprecated Docker shim và từ Kubernetes 1.24 (2022), Docker runtime bị loại bỏ hoàn toàn. containerd trở thành một trong những runtime được khuyến nghị chính thức, cùng với CRI-O.
Vị trí trong container stack
containerd nằm ở layer giữa trong container stack, kết nối high-level orchestration với low-level kernel features:
Kernel Layer cung cấp các primitives như namespaces (để cô lập processes, network, filesystem), cgroups (để giới hạn resources), capabilities (quản lý privileges), và seccomp (filter system calls).
Low-level Runtime Layer là nơi runc hoặc các OCI-compliant runtime khác tương tác trực tiếp với kernel để tạo và khởi chạy container, thiết lập namespaces và cgroups.
containerd Layer quản lý các chức năng cấp cao như image management, storage, networking, và container lifecycle. Nó cung cấp API ổn định cho các layer trên.
Orchestration Layer là nơi Kubernetes, Docker Engine, hoặc các platform khác sử dụng containerd thông qua gRPC API hoặc CRI plugin.
Kiến trúc và thành phần chính
containerd được thiết kế theo kiến trúc plugin-based, cho phép mở rộng linh hoạt. Core daemon nhẹ và các chức năng được triển khai thông qua plugin system.
Content Store
Content Store lưu trữ các image layers dưới dạng content-addressable, nghĩa là mỗi piece of data được định danh bằng SHA256 hash của nội dung. Điều này mang lại ba lợi ích lớn: deduplication (layers giống nhau chỉ lưu một lần), integrity verification (phát hiện corruption ngay lập tức), và immutability (content không thể bị modify sau khi lưu).
Content store được tổ chức trong thư mục /var/lib/containerd/io.containerd.content.v1.content/ với cấu trúc phân cấp theo SHA256 digest. Khi nhiều images share cùng base layers, những layers đó chỉ được lưu trữ một lần, tiết kiệm đáng kể disk space.
Snapshot Service
Snapshot Service quản lý filesystem layers cho containers. Nó sử dụng các công nghệ như overlayfs, btrfs, hoặc zfs để tạo layered filesystem. Với overlayfs (snapshotter phổ biến nhất), các read-only image layers được stack làm lowerdir, và một writable layer (upperdir) được tạo cho container. Khi container ghi file, overlayfs sử dụng copy-on-write: file từ lowerdir được copy sang upperdir trước khi modification.
Snapshotter cho phép tạo container nhanh chóng vì không cần copy toàn bộ filesystem, chỉ cần tạo một writable layer mới trên các existing layers.
Task Service
Task Service quản lý các running container processes. Một "task" đại diện cho một container đang chạy với PID cụ thể. Service này theo dõi trạng thái container, thu thập metrics (CPU, memory, I/O usage), và xử lý lifecycle events như start, stop, kill.
Metadata Store
Metadata Store lưu trữ thông tin về images, containers, snapshots và các resources khác. Metadata được persist vào database (thường là BoltDB) để đảm bảo dữ liệu không bị mất khi containerd restart. Metadata bao gồm image labels, creation time, snapshot references, và configuration.
Shim Architecture
containerd-shim là một innovation quan trọng. Mỗi container có một shim process riêng đóng vai trò trung gian giữa containerd daemon và container process. Điều này mang lại nhiều lợi ích: containerd daemon có thể restart hoặc upgrade mà không kill containers, shim tiếp tục monitor container process và forward stdio (stdin/stdout/stderr), xử lý signals (SIGTERM, SIGKILL) từ containerd đến container.
Shim là lightweight process, chỉ consume minimal resources nhưng cung cấp essential functionality. Nhờ shim, container lifecycle hoàn toàn độc lập với containerd daemon lifecycle.
Image management chi tiết
OCI Image Specification
containerd tuân thủ OCI Image Specification, định nghĩa cách packaging và distribution của container images. Một OCI image bao gồm:
Image Manifest mô tả cấu trúc image với danh sách layers và config object. Manifest được định danh bằng digest.
Image Configuration là JSON object chứa metadata như architecture, OS, environment variables, entrypoint, và command.
Filesystem Layers là các tar archives chứa filesystem changes, được stack lên nhau để tạo complete filesystem.
Image Pull Process
Khi bạn pull một image, containerd thực hiện các bước:
Đầu tiên, resolve image reference (ví dụ nginx:latest) thành registry URL và manifest digest. Sau đó fetch manifest từ registry, parse để lấy danh sách layers. containerd download các layers song song nếu chưng chưa tồn tại trong content store, kiểm tra digest trước để tránh duplicate work. Sau khi download, verify SHA256 của mỗi layer để đảm bảo integrity. Cuối cùng, snapshotter unpack các layers và tạo snapshot hierarchy, cập nhật metadata store với thông tin về image.
Container lifecycle management
Tạo container
Process tạo container gồm nhiều giai đoạn:
Container Object Creation: Client gọi API với container spec (bao gồm image reference, runtime name, configuration options). containerd tạo container entry trong metadata store nhưng chưa start process.
Snapshot Preparation: Snapshotter tạo active snapshot từ image's committed snapshot. Với overlayfs, điều này có nghĩa tạo upperdir (writable layer) và merged mountpoint.
OCI Runtime Spec Generation: containerd generate OCI runtime specification (config.json) từ container config. Spec này define namespaces, cgroups, mounts, và security settings.
Runtime Plugin Selection: Dựa trên runtime name, containerd chọn runtime plugin phù hợp (runc, kata, gvisor).
Chạy container
Task Creation: Client gọi API để tạo task từ container. Task đại diện cho running instance.
Shim Process: containerd spawn containerd-shim process. Shim đóng vai trò trung gian, cho phép daemon restart mà không ảnh hưởng containers.
Runtime Invocation: Shim gọi low-level runtime (runc) để create và start container. runc thực thi OCI spec, setup namespaces, cgroups, và exec entrypoint.
Process Monitoring: Shim monitor container process, forward stdio, collect exit status, và publish events về containerd daemon.
Container states
containerd định nghĩa các trạng thái rõ ràng:
Created: Container object tồn tại với configuration nhưng chưa có running process.
Running: Task đang active với PID hợp lệ, process đang execute.
Paused: Container process bị pause sử dụng cgroups freezer, memory state được preserve.
Stopped: Task đã exit với exit code, process không còn tồn tại nhưng container object vẫn available.
Deleted: Container object đã bị xóa khỏi metadata store.
Runtime integration
runc - Reference Implementation
runc là reference implementation của OCI runtime spec, được sử dụng làm default runtime bởi containerd. Khi containerd gọi runc, nó thực hiện:
Namespace Creation: runc tạo các Linux namespaces để isolate container. PID namespace cho phép container có init process là PID 1. Network namespace cung cấp network stack riêng. Mount namespace isolate filesystem. UTS namespace cho hostname riêng. IPC và User namespace cung cấp thêm layers of isolation.
Cgroup Configuration: runc configure cgroups để limit resources như CPU time, memory, I/O bandwidth, và số lượng processes.
Filesystem Setup: runc mount rootfs từ snapshot location vào container namespace, setup essential mounts như /proc, /sys, /dev.
Security: runc drop unnecessary capabilities, setup seccomp profiles, apply AppArmor/SELinux labels để harden container security.
Alternative Runtimes
containerd hỗ trợ nhiều runtime thông qua runtime v2 API:
Kata Containers chạy mỗi container trong lightweight VM riêng, cung cấp stronger isolation với kernel riêng. Phù hợp cho multi-tenant environments hoặc untrusted workloads.
gVisor là user-space kernel implementation, intercept syscalls và emulate kernel behavior. Giảm kernel attack surface nhưng trade một chút performance.
Container Runtime Interface (CRI)
CRI là plugin interface cho phép Kubernetes sử dụng các container runtimes khác nhau. containerd có built-in CRI plugin, làm nó trở thành CRI-compliant runtime trực tiếp.
Pod Sandbox
Trong Kubernetes, một Pod được map đến một PodSandbox. containerd implement sandbox bằng pause container - một container minimal chạy pause binary để hold network namespace. Các containers trong pod share network và IPC namespaces thông qua pause container này.
Khi kubelet gọi RunPodSandbox, containerd pull pause image, tạo pause container với network namespace, setup CNI networking cho sandbox, rồi return sandbox ID.
Container trong Pod
Khi kubelet cần tạo container trong pod, nó gọi CreateContainer với container config và sandbox ID. containerd chuyển đổi CRI config sang internal spec, set container để join network namespace của sandbox, mount volumes và secrets, rồi tạo container object. Sau đó kubelet gọi StartContainer để containerd tạo task và start process.
Networking với CNI
containerd không implement networking mà rely on CNI (Container Network Interface) plugins. Khi container được tạo với network namespace riêng, containerd invoke CNI plugin với configuration. Plugin thực hiện các tác vụ như tạo veth pair (một end trong container, một end trên host), attach host end vào bridge, configure IP address và routes, enable IP forwarding và NAT rules nếu cần.
Popular CNI plugins bao gồm:
bridge tạo Linux bridge và connect containers qua veth pairs, simple và efficient cho single-host.
flannel là overlay network cho multi-host connectivity, popular trong Kubernetes.
calico cung cấp advanced networking với BGP routing, network policies, và security features.
Security features
containerd cung cấp nhiều lớp bảo mật:
Namespaces Isolation: Linux namespaces isolate processes, network, filesystem. Containers không thể see hoặc affect processes bên ngoài.
Cgroups Resource Limits: Prevent containers từ consuming excessive resources, limit CPU, memory, I/O.
Capabilities: containerd drop dangerous capabilities như CAP_SYS_ADMIN, CAP_NET_ADMIN mặc định, chỉ giữ lại những capabilities cần thiết.
Seccomp Profiles: Filter system calls, block dangerous syscalls như reboot, mount, kernel module operations.
AppArmor/SELinux: Mandatory Access Control systems cung cấp additional security layer với profile-based hoặc label-based restrictions.
Rootless Mode: Cho phép run containerd và containers hoàn toàn unprivileged, attacker escape container chỉ gain unprivileged user permissions.
Command line tools
ctr là official CLI tool của containerd, cung cấp low-level access đến containerd API. Ví dụ: ctr images pull, ctr run, ctr containers ls.
nerdctl là tool thân thiện hơn, tương thích với Docker CLI syntax nhưng hoạt động với containerd. Nó cung cấp trải nghiệm quen thuộc cho những ai đã sử dụng Docker: nerdctl run, nerdctl build, nerdctl compose.
crictl là tool debug cho CRI, hữu ích khi troubleshoot Kubernetes nodes: crictl pods, crictl ps, crictl logs.
So sánh với Docker
Docker là platform hoàn chỉnh với nhiều tools và features cho developers: Docker CLI thân thiện, Docker Compose cho multi-container apps, Docker Desktop với GUI. Docker Engine sử dụng containerd bên dưới nhưng thêm layer abstraction và utilities.
containerd, ngược lại, là runtime thuần túy tập trung vào việc chạy containers hiệu quả. Trong production và Kubernetes, sử dụng trực tiếp containerd loại bỏ các layer không cần thiết, giảm overhead, cải thiện performance và giảm attack surface.
Tại sao containerd quan trọng?
containerd đã trở thành tiêu chuẩn de facto cho container runtime trong môi trường cloud-native. Với thiết kế modular, hiệu suất cao, tính ổn định production-ready, và sự hỗ trợ mạnh mẽ từ cộng đồng CNCF, containerd là lựa chọn lý tưởng cho cả development và production.
Hiểu về containerd không chỉ giúp bạn làm việc hiệu quả hơn với containers mà còn cung cấp nền tảng vững chắc để tối ưu hóa infrastructure, troubleshoot issues, và xây dựng các giải pháp container customized. Trong thời đại cloud-native, containerd là một trong những building blocks không thể thiếu của modern infrastructure.