Docker 推动了容器镜像分发与开发工作流的普及,并推动 OCI 标准建立。理解 Client-Server 架构,是理解 Docker 一切操作的前提。
容器是什么?(零基础版)#
如果你已经读过 Podman 系列的容器入门 容器的基础概念在 Podman 01 篇 有详细解释。Docker 和 Podman 共用同一套容器标准(OCI),概念基础概念相通,具体引擎功能仍有差异。
镜像和容器
- 镜像 (Image):一个只读模板,包含运行程序所需的一切——代码、库、配置文件。它是"安装包"。
- 容器 (Container):镜像的运行实例。它是"正在运行的程序"。
docker pull nginx:alpine # 下载镜像(安装包)
docker run nginx:alpine # 从镜像启动容器(运行程序)Client-Server 架构:Docker 的核心模型#
graph TD
subgraph "你的终端"
CLI["docker CLI / $ docker run ..."]
end
subgraph "Docker 守护进程"
SOCK["/var/run/docker.sock / Unix Socket"]
DOCKERD["dockerd / 以 root 运行 / 常驻后台"]
CONTAINERD["containerd / 容器生命周期管理"]
end
subgraph "容器运行时"
RUNC["runc / OCI 标准运行时"]
end
subgraph "你的容器"
C["nginx 容器 / 独立进程"]
end
CLI -->|"REST API over Unix Socket"| SOCK
SOCK --> DOCKERD
DOCKERD --> CONTAINERD
CONTAINERD --> RUNC
RUNC --> C每一步发生了什么:
- 你敲
docker run nginx:alpine dockerCLI 把请求发到/var/run/docker.sockdockerd(守护进程)收到请求,检查本地有没有nginx:alpine镜像,没有就从 Docker Hub 拉dockerd调用containerd创建容器containerd调用runc启动容器进程- 你的 nginx 容器开始运行;具体进程父关系涉及 containerd shim 和运行时,不能简单称为 dockerd 的直接子进程
三个关键组件#
dockerd(守护进程)
- 常驻后台:系统启动时自动运行,一直占用内存
- rootful 或 rootless:传统系统 daemon 以 root 运行,也可配置 rootless;控制 rootful socket 的权限应视为高权限
- 单点控制:本篇描述传统 daemon 管理路径;构建与不同 context 可能涉及额外工具和服务
- 管理不可用,现有容器行为取决于 live-restore 等配置:daemon 不可用会影响管理操作;live-restore 可使独立容器在部分 daemon 停止/升级场景继续运行,并有版本和日志缓冲限制
docker.sock(通信桥梁)
/var/run/docker.sock 是 dockerd 的 Unix Socket 文件:
# docker CLI 通过这个 Socket 和 dockerd 通信
ls -l /var/run/docker.sock
# srw-rw---- 1 root docker ... /var/run/docker.sock
# └ root └ 属于 docker 组的用户可读写
# 能读写这个 Socket 的人 = 能操控 Docker
# 操控 Docker = 能以 root 身份做任何事
# 这就是为什么 docker 组 ≈ root 权限Docker Hub(镜像仓库)
Docker Hub(docker.io)是 Docker 的公共镜像仓库,类似 GitHub 但对于镜像:
docker pull nginx:alpine默认从 Docker Hub 拉- 也可以推自己的镜像上去:
docker push exampleuser/myimage:latest - 国内可能需要镜像加速(配置
registry-mirrors)
Docker 的运行流程#
# 典型的一次操作
docker run -d --name web -p 8080:80 -v /data:/usr/share/nginx/html nginx:alpine
# 命令拆解:
# docker — 调用 Docker CLI
# run — 创建并启动一个新容器
# -d — 在后台运行(不占用当前终端)
# --name web — 给容器起名 web(不指定则随机生成)
# -p 8080:80 — 把宿主机的 8080 端口,转发到容器的 80 端口
# -v /data:/usr/share/nginx/html — 把宿主机的 /data 目录,挂载到容器的指定路径
# nginx:alpine — 用哪个镜像容器生命周期
pull(拉取镜像)
│
▼
create(创建容器,分配文件系统和网络)
│
▼
start(启动容器进程)
│
▼
running(运行中)
│
├── stop(发送配置的停止信号,等待超时后强杀;默认通常为 SIGTERM)
│ │
│ └── 容器进程退出
│
├── kill(发送 SIGKILL,立即强杀)
│ │
│ └── 容器进程立即终止
│
├── pause(冻结容器进程(并非关闭全部外部 I/O),不释放内存)
│ │
│ └── unpause(恢复运行)
│
└── rm(删除容器及其可写层,不自动删除命名卷或镜像)Docker 的优势和劣势#
为什么 Docker 最流行
| 优势 | 说明 |
|---|---|
| 生态最成熟 | 最多的镜像、教程、文档、Stack Overflow 问答 |
| 团队协作 | 工具和配置可形成团队共同工作流,实际标准按团队选择 |
| Docker Compose 原生 | 第一方工具,提供 profiles/watch/secrets 等功能 |
| CI/CD 集成 | 常见 CI 提供容器任务或 Docker 集成,权限与 runner 条件各异 |
| Docker Desktop | GUI 管理、集成 K8s、开发体验好(但有收费) |
| Docker Swarm | 轻量集群编排,使用 legacy Compose v3 格式子集,需检查迁移兼容性 |
劣势
| 劣势 | 说明 |
|---|---|
| dockerd 是单点故障 | 挂着影响所有容器 |
| root 安全风险 | dockerd 以 root 运行,socket 泄露 = 系统沦陷 |
| 内存占用 | 资源占用依配置与负载测量 |
| Docker Desktop 收费 | 较大企业商业使用需订阅;当前文档以超过 250 名员工或超过 1000 万美元年营收描述,按许可条款核对 |
| 限制拉取速率 | 配额依匿名/认证与订阅方案变化,按官方 Hub usage 页面核对 |
Docker 和 OCI 标准#
Docker 在 2015 年把容器运行时 runc 捐献给 OCI(Open Container Initiative),OCI 定义镜像、运行时及分发等规范;这里关注其中两类:
- OCI Image Spec — 镜像格式标准(Docker 支持 OCI 与相关镜像格式,具体 manifest/media type 应检查)
- OCI Runtime Spec — 容器运行时标准(runc 是参考实现)
这意味着:常用兼容镜像可被 Podman 或 Kubernetes 所用的容器引擎消费,仍须匹配平台架构、运行时要求及配置;containerd 本身也需对应工具和配置。镜像格式不是 Docker 专有的。
参考与延伸
根据技术笔记重新整理,示例使用通用名称。