【Docker 从入门到实战】:容器生态系统全景 + Docker 架构详解,镜像、容器、仓库一文搞定
摘要 :本文是 Docker 学习笔记的第 1-2 章合集。第 1 章先带你"鸟瞰"整个容器生态系统------核心技术、平台技术、支持技术三大板块一次讲清,并带你完成 Docker 安装、运行人生第一个容器;第 2 章从 What / Why / How 三个角度回答"容器到底是什么、为什么需要它、它内部怎么工作",再深入 Docker 的 Client/Server 架构与组件协作全流程。适合零基础入门,建议收藏后跟着实验一起动手。
一、容器生态系统
容器生态分 3 层:核心技术(单机跑容器)、平台技术(集群编排)、支持技术(保障稳定运行)
| 层次 | 包含内容 | 核心作用 |
|---|---|---|
| 核心技术 | 容器规范、容器 Runtime、容器管理工具、容器定义工具、Registry、容器 OS | 让容器在单个 Host 上运行起来 |
| 平台技术 | 容器编排引擎、容器管理平台、基于容器的 PaaS | 让容器以集群方式在分布式环境中运行 |
| 支持技术 | 容器网络、服务发现、监控、数据管理、日志管理、安全性 | 支撑基于容器的基础设施 |
1.1 容器核心技术
核心技术是让 container 能在 host OS 上跑起来的技术,一共 6 类:
| 技术 | 代表 | 说明 |
|---|---|---|
| 容器规范 | OCI(Open Container Initiative) | 由 Docker、CoreOS、Google 等公司共同成立,发布 runtime spec 和 image format spec 两个开放标准,保证不同容器的可移植性和互操作性 |
| 容器 Runtime | lxc、runc、rkt | 容器真正运行的地方,与内核紧密协作提供运行环境 |
| 容器管理工具 | docker engine、lxd、rkt cli | 对内与 runtime 交互,对外为用户提供 CLI 接口 |
| 容器定义工具 | docker image、Dockerfile、ACI | 定义容器的内容和属性,使容器可以被保存、共享和重建 |
| Registry | Docker Hub、Quay.io、私有 Registry | 统一存放镜像的"仓库" |
| 容器 OS | CoreOS、atomic、Ubuntu Core | 专为运行容器定制的操作系统,体积更小、启动更快 |
几个容易混淆的点,划重点:
① 容器 Runtime 类比 JVM
Java 程序就好比是容器,JVM 就好比是 Runtime。容器只有在 Runtime 中才能运行。
lxc:Linux 老牌容器 Runtime,Docker 最初就是用它;runc:Docker 自研、符合 OCI 规范,是现在 Docker 的默认 Runtime(由 Libcontainer 演变而来);rkt:CoreOS 开发,符合 OCI 规范,也能运行 Docker 的容器。
② 管理工具 ≠ Runtime
光有 Runtime 不够,用户还要工具去管理容器。我们通常说的 "Docker",一般就是指 docker engine ,它包含后台 daemon 和 CLI 两部分。
③ 定义工具:image 与 Dockerfile
docker image是容器的模板,Runtime 依据它创建容器;Dockerfile是包含若干命令的文本文件,通过它构建出 docker image。
④ Registry 与镜像加速
- Docker Hub(hub.docker.com)是 Docker 提供的公共托管 Registry,上面有海量现成镜像;
- 企业可以用 Docker Registry / Harbor 构建私有仓库;
- 国内访问 Docker Hub 慢,通常要配置镜像加速器。
1.2 容器平台技术
核心技术解决"单机跑起来",平台技术解决"集群跑起来"。基于容器的应用一般采用微服务架构 :应用被拆成不同组件,各自以服务形式跑在容器里;为了保证高可用,每个组件可能运行多个相同的容器,这些容器组成集群,被动态创建、迁移和销毁------这就需要容器编排引擎来管理。
| 技术 | 代表 | 说明 |
|---|---|---|
| 容器编排引擎 | docker swarm、kubernetes、mesos + marathon | 负责容器管理、调度、集群定义和服务发现,把容器有机组合成微服务应用 |
| 容器管理平台 | Rancher、ContainerShip | 架构在编排引擎之上,抽象底层实现细节,支持多种编排引擎,提供应用目录、一键部署等功能 |
| 基于容器的 PaaS | Deis、Flynn、Dokku | 为微服务应用的开发、部署、管理提供平台,用户不用关心底层基础设施 |
补充:Kubernetes 是 Google 领导开发的开源编排引擎,同时支持 Docker 和 CoreOS 容器;CNCF(云原生计算基金会,隶属于 Linux Foundation)旗下的明星项目就有 Kubernetes、Prometheus、Fluentd 等。
1.3 容器支持技术
容器让网络拓扑变得更动态复杂,也带来监控、日志、安全等新挑战:
| 技术方向 | 代表方案 | 作用 |
|---|---|---|
| 容器网络 | docker network、flannel、weave、calico | 管理容器与容器、容器与其他实体之间的连通性和隔离性 |
| 服务发现 | etcd、consul、zookeeper | 在容器动态变化的环境中,保存所有微服务最新的 IP/端口并对外提供查询 API |
| 监控 | docker ps/top/stats、sysdig、cAdvisor/Heapster、Weave Scope | 掌握容器运行状态和资源使用情况 |
| 数据管理 | Flocker | 保证容器跨 Host 迁移时,持久化数据也能动态迁移 |
| 日志管理 | docker logs、logspout | 为问题排查和事件管理提供依据 |
| 安全性 | OpenSCAP | 对容器镜像进行扫描,发现潜在漏洞 |
本章小结:核心技术让容器"跑起来",平台技术让容器"组团跑",支持技术让容器"跑得稳"。Docker 是生态的基石,但完善的生态系统才是容器技术健康发展的保障。
二、容器技术:What / Why / How
学习任何技术都可以用 3W 框架,容器也不例外。
2.1 容器发展史(时间线)
| 时间 | 事件 | 意义 |
|---|---|---|
| 1979 | Unix V7 引入 Chroot Jail | 最早的容器化技术雏形,隔离进程的根目录 |
| 1982 | Chroot 加入 BSD | 技术普及 |
| 2000 | FreeBSD 引入 FreeBSD Jail | 更安全的文件隔离,可为每个 jail 分配 IP |
| 2001 | Linux VServer | 操作系统级虚拟化,单系统上运行多个 Linux 发行版 |
| 2004 | Solaris Containers | 用系统资源控制和 zone 实现边界分离 |
| 2006 | Google 推出 Process Containers | 限制、计算、隔离一组进程的资源使用 |
| 2007 | 改名为 cgroups | 最终合并进 Linux 内核 2.6.24 |
| 2008 | LXC 诞生 | 第一个 Linux 容器管理器,用 cgroups + namespace 在单内核上跑多个容器 |
| 2013 | Docker 发布第一个版本 | 在 LXC 基础上优化体验,后自研 libcontainer 替代 |
| 2014 | Google 开源 LMCTFY、CoreOS 发布 rkt | 容器生态百花齐放(Google 每周有超 20 亿个容器在跑) |
2.2 What:容器是什么?
容器是一种轻量级、可移植、自包含的软件打包技术 ,使应用程序可以在几乎任何地方以相同的方式运行。开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能在生产环境的虚拟机、物理服务器或公有云主机上运行。
容器由两部分组成:
- 应用程序本身;
- 依赖:应用需要的库或其他软件。
容器在 Host 操作系统的用户空间中运行,与操作系统的其他进程隔离。
2.3 容器 VS 虚拟机
两者都是为应用提供封装和隔离,但思路完全不同------虚拟化目标是创建完整的虚拟机(装应用还要装整个操作系统,几十 GB);容器则共享 Host OS,只打包应用及其依赖(几十 MB)。
| 对比维度 | 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒甚至毫秒 | 数秒至数十秒 |
| 系统内核 | 共享内核 | 不共享内核 |
| 实现技术 | Linux 内核 Namespace / Cgroup | Hypervisor 层虚拟化 |
| 隔离效果 | 进程级隔离 | 系统资源级隔离 |
| 资源消耗 | 应用只是宿主机上的普通进程,开销极小 | 额外的资源消耗和占用 |
| 资源调用 | 应用进程直接由宿主机 OS 管理 | 需经 Hypervisor 拦截和处理 |
| 运行数量 | 一台服务器 1000+ 容器 | 一台一般不超过 100 台 |
| 镜像 | 分层镜像 | 非分层镜像 |
| 体积 | MB 级 | GB 级 |
| 典型应用 | DevOps、微服务 | 硬件资源划分 |
容器本质是进程级隔离,共享宿主机内核,依靠 Linux 两大内核能力:
Namespace:做隔离 ------"看不见"
| Namespace | 隔离内容 | 对应现象 |
|---|---|---|
| PID | 进程编号 | 容器里 PID 1 是自己的主进程,看不到宿主机其他进程 |
| Network | 网络栈 | 每个容器有自己的 IP、端口、路由表(所以能跑同一个 80 端口) |
| Mount | 挂载点 / 文件系统 | 容器看到的是自己的 rootfs,看不到宿主机的目录 |
| UTS | 主机名 | 容器有自己的 hostname |
| IPC | 进程间通信 | 容器间不能共享消息队列等 |
| User | 用户 / 用户组 | 容器内有自己的 root(实际可能映射为宿主机普通用户) |
| Cgroup | 控制组视图 | 容器只能看到自己被分配的资源 |
类比:虚拟机是给每个人一套独立的房子(完整操作系统),Namespace 是给所有人住同一栋楼,但每人一个独立房间、窗户贴了膜
Cgroup:做资源限制 ------"用不多"
| 资源 | 限制内容 |
|---|---|
| CPU | 限制 CPU 使用份额 / 上限(比如最多用 2 核的 50%) |
| 内存 | 限制内存上限,超限触发 OOM |
| 磁盘 I/O | 限制读写带宽和 IOPS |
| 网络带宽 | 限制容器网络流量 |
| 进程数 | 限制容器内能创建的进程数量 |
类比:每个房间都装了独立的水表电表,规定了额度 ------ 你最多用这么多,用完就限流,不会影响整栋楼的其他人。
2.4 Why:为什么需要容器?
简要答案:容器使软件具备了超强的可移植能力。
今天的应用架构比十年前复杂得多:开发人员用多种服务(MQ、Cache、DB)组装应用,应用还要部署到虚拟服务器、私有云、公有云等不同环境。于是产生了"各种服务 × 各种环境"的 N×M 矩阵------开发要适配环境,运维要配置环境,双方都很痛苦。
容器从运输行业找到了答案:集装箱。
| 特性 | 集装箱 | Docker |
|---|---|---|
| 打包对象 | 几乎任何货物 | 任何软件及其依赖 |
| 硬件依赖 | 标准接口,运输全程无需开箱 | 无需修改,可运行在虚拟机、物理机、公有云、私有云 |
| 隔离性 | 货物互不压坏(香蕉不会被铁桶压烂) | 资源、网络、库都隔离,不出现依赖问题 |
| 自动化 | 标准接口易自动装卸 | 提供 run / start / stop 等标准化操作 |
| 高效性 | 无需开箱,快速搬运 | 轻量级,快速启动和迁移 |
| 职责分工 | 货主管装什么,承运方管怎么运 | 开发管写代码,运维管配置环境 |
有趣的知识点:"集装箱"和"容器"的英文都是 Container。Docker 的 Logo 正是一堆集装箱。
容器对两类人的价值:
- 对开发人员 ------ Build Once, Run Anywhere:只需为应用创建一次运行环境,打包成容器就能在其他机器上运行,环境与 Host 隔离,更快更简单;
- 对运维人员 ------ Configure Once, Run Anything:只需配置好标准 Runtime 环境,服务器就能运行任何容器,消除了开发、测试、生产环境的不一致性。
2.5 How:容器如何工作?
Docker 是什么
- Docker 是基于 Go 语言 实现的开源容器项目,2013 年初由 dotCloud 公司发起,因影响力太大,dotCloud 后来直接改名 Docker Inc;
- Docker 是 GitHub 上 Moby 开源项目的一部分,遵循 Apache License 2.0;
- 可以简单把 Docker 容器理解为轻量级的沙盒:每个容器里跑一个应用,容器之间相互隔离,也可通过网络互相通信;创建和停止几乎和原生应用一样快,资源消耗远低于虚拟机。
Docker 版本
- 17.03 之前叫 Docker Engine(版本号 0.1.0 ~ 1.13.1);
- 2017 年 3 月 2 日发布 Docker EE(企业版) ,免费版更名为 Docker CE(社区版) ,采用基于时间的版本号 YY.MM;
- CE 每季度发布一个季度版本(17.03、17.06、17.09、17.12),每月还有 EDGE 版;CE 维护期 4 个月,EE 维护期 12 个月。
三、Docker 核心概念:镜像、容器、仓库
Docker 大部分操作都围绕三大核心概念展开:
| 对比维度 | 镜像(Image) | 容器(Container) | 仓库(Registry) |
|---|---|---|---|
| 本质 | 只读模板 | 镜像的运行实例 | 存放镜像的场所 |
| 类比 | 图纸 / 类(Class) | 按图纸造出的房子 / 对象(Object) | 应用商店 / 车库 |
| 包含内容 | 基本操作系统环境 + 应用(如 Apache 镜像) | "简易版 Linux 环境(root 权限、进程空间、用户空间、网络空间)+ 应用" 的盒子 | 各类镜像,通过 tag 区分版本(ubuntu 18.04/16.04/14.04) |
| 可写性 | 只读(不可修改) | 可写(修改只发生在容器层) | 可读写 |
| 隔离性 | 可被多个容器共享 | 容器之间彼此隔离、互不可见 | 分公开 / 私有(最大公开仓库:Docker Hub) |
| 生命周期 | 软件生命周期的构建和打包阶段 | 软件的启动和运行阶段 | 存储和分发阶段 |
| 生成 / 操作方式 | 从无到有创建、下载现成、Dockerfile + docker build 修改 |
由镜像 docker run 创建;可启动、停止、删除 |
docker push 上传,docker pull 下载 |
| 常用命令 | build / commit / images / history / tag |
run / ps / start / stop / rm / exec |
push / pull / login / search |
| 数量关系 | 1 个镜像 → 可创建无数个容器 | 1 个容器只能由 1 个镜像创建 | 1 个仓库 → 存放无数个镜像 |
四、Docker 架构详解
4.1 Client/Server 架构
Docker 采用 Client/Server 架构 :客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器可以运行在同一个 Host 上,客户端也可以通过 socket 或 REST API 与远程服务器通信(第 1 章的 C/S 分离部署就是例证)。

完整的 Docker 由以下部分组成:
| 组件 | 作用 |
|---|---|
| 守护进程 Daemon(dockerd) | 侦听 Docker API 请求,管理镜像、容器、网络、卷等 Docker 对象 |
| REST API | 与 Docker Daemon 交互的接口,Docker CLI 或直接调用都走它 |
| 客户端 Client(docker 命令) | 用户与 Docker 交互的主要方式,把命令通过 REST API 发给 daemon |
| Registry 镜像仓库 | 存储 Docker 镜像(Docker Hub 公共仓库 / Harbor 私有仓库) |
| Image 镜像 | 只读模板,可通过 Docker Hub 拉取 |
| Container 容器 | 镜像的可运行实例,可创建、启动、停止、移动、删除 |
| Services 服务 | 跨多个 Docker 守护进程扩展管理容器,定义所需状态并做负载均衡 |
4.2 Docker 内部工作流程
- 用户通过 Docker Client 与 Docker Daemon 建立通信并发送请求;
- Docker Daemon 是架构主体,提供 Docker Server 功能以接受请求;
- Docker Engine 执行内部的一系列工作,每项工作以 Job 的形式存在;
- 需要镜像时,从 Registry 下载镜像,通过 Graph driver 以 Graph 形式存储;
- 需要网络环境时,由 Network driver 创建并配置容器网络;
- 需要限制资源或执行用户指令时,通过 Exec driver 完成;
- Libcontainer 是独立的容器管理包,Network driver 和 Exec driver 都通过它实现对容器的具体操作。

| 组件名称 | 核心作用 | 关键备注 |
|---|---|---|
| Docker Client | Docker 客户端,用户操作入口;接收用户docker命令,发送 HTTP 请求给 Docker Daemon |
C/S 架构的客户端,不执行实际操作 |
| Docker Daemon | Docker 后台守护进程 (dockerd),Docker 核心服务,接收并处理客户端所有请求 | 服务端主体,内部包含 Docker Server、Engine |
| Docker Server | Daemon 内部 HTTP 服务模块 | 接收、路由、处理 API 请求 |
| http server | 接收 Client 的 HTTP 请求 | 通信入口 |
| router | 请求路由分发 | 将不同 API 转发给 Handler |
| Handler | 请求处理器 | 解析请求,交给 Engine |
| Engine | Docker 引擎,任务调度核心 | 将操作封装成 Job 执行 |
| Job | 最小任务单元 | 拉镜像、创建容器等操作都封装为 Job,可并发执行 |
| Docker Registry | 远程镜像仓库(如 Docker Hub) | pull拉取镜像、push上传镜像 |
| Graph | 本地镜像管理模块(旧版 Docker) | 管理本地所有镜像数据与元数据 |
| Repository(images) | 本地镜像仓库 | 存放镜像分层文件 |
| GraphDB | 镜像元数据数据库 | 记录镜像信息、镜像层依赖关系 |
| graphdriver | 存储驱动 | 管理镜像分层挂载、读写,图示例 aufs 联合文件系统 |
| networkdriver | 网络驱动 | 容器网络管理,创建网桥、分配网卡 / IP / 端口映射 |
| execdriver | 执行驱动 | 负责容器进程创建与生命周期管理,图中 native 原生驱动 |
| libcontainer | 底层容器库,直接调用 Linux 内核能力 | 早期 Docker 替代 LXC 的底层库 |
| namespaces | 命名空间 | 实现容器资源隔离(PID、网络、挂载等) |
| cgroups | 控制组 | 限制容器 CPU、内存、IO 等硬件资源配额 |
| netlink | Linux 内核网络接口 | 内核态配置网络设备 |
| apparmor | Linux 安全模块 | 限制容器文件访问权限,安全加固 |
| devices | 设备权限管理 | 控制容器对宿主机硬件设备的访问 |
| Docker container | Docker 容器 | 镜像运行实例,隔离的应用进程环境 |
| rootfs(layered) | 分层根文件系统 | 镜像只读层 + 容器读写层,写时复制机制 |
五、动手实践:从安装到运行第一个容器
5.1 安装 Docker(CentOS Stream 8 示例)
bash
# 1. 安装必要工具
yum install -y yum-utils device-mapper-persistent-data lvm2 vim
# 2. 添加 Docker CE 源(阿里云镜像)
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 更新缓存并安装
yum makecache
yum install -y docker-ce
# 4. 设置开机自启并启动
systemctl enable docker.service --now
# 5. 验证
docker --version # Docker version 26.1.3
systemctl status docker # Active: active (running)
注:devicemapper 存储驱动在 Docker 18.09 中已被废弃,无需安装其支持。
5.2 配置镜像加速器(华为云)
查找华为云加速器地址




bash
# Centos中操作添加华为加速器
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors":["https://01a06b0c3d7779a48ea78258e479c977.mirror.swr.myhuaweicloud.com"]}
EOF
systemctl daemon-reload
systemctl restart docker
# 验证:docker info 输出中看到 Registry Mirrors 即成功
docker info
5.3 运行第一个容器:hello-world
bash
docker run hello-world
执行过程:① 本地查找 hello-world 镜像,没找到 → ② 从 Docker Hub 下载 → ③ 启动容器。看到 "Hello from Docker!" 即成功。
bash
# 实验做完清理环境
docker rm -f $(docker ps -aq) # 删除所有容器
docker rmi -f hello-world # 删除 hello-world 镜像
5.4 运行第二个容器:httpd(WEB 服务器)
bash
docker run -d -p 80:80 httpd
# -d 后台运行;-p 把宿主机 80 端口映射到容器 80 端口
# 验证:浏览器或 curl 访问宿主机 IP
curl 192.168.108.30
# <html><body><h1>It works!</h1></body></html>
轻轻松松就拥有了一个 WEB 服务器。
5.5 容器生命周期与进入容器
bash
docker ps # 查看运行中的容器
docker ps -a # 查看所有状态的容器(含 Exited)
docker stop <id> # 停止容器(状态变为 Exited)
docker start <id> # 启动已停止的容器(状态变为 Up)
docker attach <id> # 直接进入已启动容器的命令终端(不启动新进程)
docker exec -it <id> bash # 在容器中打开新的终端(更常用)
5.6 Docker C/S 分离部署(Client 远程管理 Server)
Server 端(192.168.108.30)安装完整 Docker 后,修改 service 使 dockerd 监听 TCP:
bash
# 修改 /usr/lib/systemd/system/docker.service 的 ExecStart,最后追加:
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375
systemctl daemon-reload
systemctl restart docker.service
systemctl stop firewalld
lsof -i :2375 # 确认 dockerd 正在监听 2375
Client 端(192.168.108.31)只安装客户端:
bash
yum install -y docker-ce-cli
# 直接执行会报错(本地没有 daemon):
docker run hello-world
# Cannot connect to the Docker daemon at unix:///var/run/docker.sock
# 指定远程 Server 后正常执行:
docker -H 192.168.108.30 run hello-world
docker -H 192.168.108.30 images
说明:Client 只做管理,image 和 container 都存储在 Server 端。
六、总结
- 容器生态:核心技术(规范/Runtime/管理工具/定义工具/Registry/容器 OS)→ 平台技术(编排引擎/管理平台/容器 PaaS)→ 支持技术(网络/服务发现/监控/数据/日志/安全);
- 容器本质:轻量级、可移植、自包含的软件打包技术,进程级隔离、共享内核、秒级启动,是解决"服务 × 环境"矩阵问题的软件集装箱;
- 三大核心概念:镜像(只读模板)、容器(运行实例)、仓库(镜像存储);
- Docker 架构:Client/Server 模式,Client 发请求 → Daemon 干活 → Registry 供镜像 → Graph/Network/Exec driver + Libcontainer 具体实现;
- 一次 docker run:查本地 → 没有则从 Hub 拉取 → 保存镜像 → 启动容器。