一文看懂容器核心技术:Docker、containerd 与运行时生态全景解析
🔍 容器技术已经成为现代云原生架构的基石,但很多人对 Docker、containerd、runc 之间的关系、底层原理及实际操作细节仍存在模糊认知。本文将以图表 + 命令 + 场景的方式,带你彻底理解容器运行时体系、镜像构建优化、安全实践及网络/存储机制。
一、Docker 架构与运行时演进

1.1 Docker 架构核心组件:
- Docker Client:命令行工具,调用 REST API 与 Daemon 通信。
- Docker Daemon:守护进程,负责容器生命周期、镜像管理、网络等。
- containerd:容器生命周期管理器,轻量、可嵌入,被 Docker 和 K8s 调用。
- runc:最底层容器执行工具,负责具体容器的创建与运行(OCI 标准实现)。
1.2 containerd 的定位与角色
- 特点:不直接面向用户,专注容器生命周期管理。
- 与 Docker 的关系:Docker Daemon 将具体容器操作委托给 containerd,再由 containerd 调用 runc。
二、主流容器运行时技术对比

三、容器镜像制作与优化技巧

3.1 镜像层机制(Layer)
每条 Dockerfile 指令(如 RUN, COPY)都会创建一个只读层。层的共享机制能极大节省磁盘空间,但也可能造成臃肿镜像。
3.2 优化策略示例:多阶段构建
FROM alpine:3.18 AS builder
RUN apk add gcc && compile-app
FROM alpine:3.18
COPY --from=builder /app/bin/ /app/
USER appuser
CMD ["/app/start"]
推荐优化方法:
- 使用
alpine等轻量基础镜像(体积 < 5MB)。 - 多阶段构建,分离编译与运行环境。
- 合并指令,减少层数(避免重复
RUN命令)。
四、Docker vs containerd:命令与工具对比

4.1 工具关系图解

4.2 工具角色说明
• Docker CLI:用户通过命令行工具(如 docker run)与 Docker Daemon 交互。
• Docker Daemon(dockerd):接收 CLI 指令后,通过 containerd 管理容器生命周期。
• nerdctl 和 ctr:均为直接操作 containerd 的客户端工具(nerdctl 兼容 Docker 命令,ctr 是 containerd 原生 CLI)。
• containerd:作为容器运行时核心,最终调用 runc 创建容器进程
• Docker Daemon 的网络(如 bridge)和存储(如 overlay2)由 dockerd 直接管理,不经过 containerd
五、网络模型全景图解:从 Bridge 到 VXLAN

5.1 容器网络类型概览:
- Bridge 模式(默认):NAT 转发,通过 iptables 实现外网访问。
- Host 模式:复用宿主机网络栈,适合高性能场景,但容易端口冲突。
- Overlay 网络:支持跨主机容器通信,典型如 Docker Swarm、Kubernetes 使用的 Flannel、Calico。
5.2 VXLAN 工作原理图解

数据流示例(容器 A(10.244.1.2) → 容器 B(10.244.2.3)):
1.容器 A 发送原始以太网帧(目的 MAC 为容器 B 的 MAC)。
2.源 VTEP(10.12.34.56)将帧封装为 VXLAN UDP 包,目标 VTEP IP 为 10.12.34.78(由 ARP/Flannel 学习)。
3.物理网络传输封装后的 UDP 包至目的 VTEP。
4.目的 VTEP(10.12.34.78)解封装帧,并递交给容器 B。
VXLAN 通过封装二层以太网帧为 UDP 数据包,实现跨三层的虚拟网络隔离与互联,广泛用于 Kubernetes 网络插件中(如 Flannel)。
六、存储机制:Volume vs Bind Mount

6.1 Volume(推荐方式)
docker volume create my-data
docker run -v my-data:/app/data nginx
- 数据默认存储于
/var/lib/docker/volumes/ - 即使容器被删,Volume 数据依然保留
6.2 Bind Mount(宿主机路径映射)
docker run -v /host/path:/container/path nginx
- 可用于实时映射宿主机目录,适合调试或共享配置
- 注意权限问题与目录覆盖风险
6.3 k8s 中常用的挂载存储类型

- emptyDir:临时数据共享
场景: 同一个 Pod 内的多个容器需要共享临时数据(如中间处理结果、缓存)。 - hostPath:访问宿主机文件系统
场景: 访问宿主机系统路径(如日志采集、节点监控)。
七、安全实践:非 root 用户运行容器
FROM alpine
RUN adduser -D -u 1001 appuser
USER appuser # 在 Dockerfile 中指定运行用户
CMD ["sh", "-c", "echo 'Log entry' > /logs/app.log && sleep 3600"]
7.1 宿主机权限同步策略
sudo mkdir /host/logs
sudo chown 1001:1001 /host/logs
docker run -v /host/logs:/logs --user 1001 my-app
7.2 推荐做法:组权限共享
sudo groupadd -g 2000 appgroup # 宿主机创建相同 GID 的组
sudo chown :2000 /host/logs # 设置目录属组
sudo chmod g+w /host/logs # 赋予组写权限
Dockerfile:
镜像构建阶段: 创建用户并加入公共组(如 appgroup)。
RUN adduser -D -u 1001 -G appgroup appuser
通过统一 GID 保证不同容器或宿主进程都能写入共享目录,无需绑定特定 UID。
结语:理解容器技术,迈向云原生
从 Docker 到 containerd、从镜像构建到网络/存储安全,容器技术已经发展出完整的生态体系。掌握其原理与实操,是迈向云原生架构的第一步。
无论你是开发、运维,还是架构师,希望本文能为你提供一个全景、系统的容器知识地图。
结语
💬 重点提醒 :喜欢请加关注哦 !
📣 更多原创内容、技术干货,欢迎关注「键上江湖」公众号,与你一键相逢!
1140

被折叠的 条评论
为什么被折叠?



