Docker容器原理和启动策略
一、Docker 容器的原理
1. 容器与虚拟机的区别(基础理解)
项目 | 虚拟机(VM) | 容器(Container) |
---|---|---|
启动速度 | 慢(分钟级) | 快(秒级) |
资源隔离 | 独立的内核、资源 | 共享宿主机内核,进程级隔离 |
系统支持 | 各自完整的 OS | 共用宿主系统内核 |
镜像体积 | 几百 MB ~ GB | 通常几十 MB ~ 百 MB |
Docker 是一种“轻量级虚拟化”,核心是利用 Linux 的 内核特性 实现进程隔离和资源限制。
2. Docker 容器的核心技术
Docker 容器的原理主要基于以下几个 Linux 特性:
(1)Namespaces(命名空间)—— 隔离性
Docker 使用以下几种 namespace 来实现容器的“独立世界”:
pid
:进程号隔离net
:网络隔离(容器有自己的网络设备)mnt
:挂载点(文件系统)隔离ipc
:信号量、消息队列隔离uts
:主机名和域名隔离user
:用户 ID 映射隔离
这样容器就像是一个“独立的小系统”,进程和宿主机之间互不干扰。
(2)Cgroups(控制组)—— 资源限制
Cgroups 控制每个容器使用的 CPU、内存、磁盘 IO、网络带宽 等资源,防止某个容器“吃光资源”。
(3)UnionFS(联合文件系统)—— 镜像构建基础
UnionFS 支持将多个目录合并成一个文件系统,Docker 镜像就是由多个只读层 + 一个可写层组成,节省空间、提高构建效率。
如:
镜像层:
- ubuntu基础镜像(只读)
- 安装nginx(只读)
- 添加配置文件(只读)
容器层:
- 当前运行时的写层(可写)
(4)容器 = 镜像 + 可写层 + 隔离机制
容器启动时会基于镜像,加上一个 容器写层,再加上上述 namespace 和 cgroup 等机制,最终成为一个运行中的独立进程。
3. 容器运行架构
用户命令(docker cli)↓
Docker Daemon(服务端)↓
调用 containerd / runC↓
Linux 内核(通过 namespace + cgroup)↓
生成容器进程(共享内核,但逻辑隔离)
Docker CLI
提供命令行接口Docker Daemon
是守护进程,处理容器管理逻辑containerd
是容器运行时接口,负责容器生命周期runC
是实际调用 Linux 系统创建容器的工具(OCI 兼容)
二、Docker 容器的启动策略
Docker 容器的启动策略,指的是 容器在宿主机重启后是否自动重启,这由 --restart
参数控制。
1. 常见的启动策略
docker run --restart=xxx ...
策略 | 含义 |
---|---|
no (默认) | 宿主机重启后,不自动启动容器 |
always | 总是自动重启容器(除非人为 stop) |
on-failure[:max-retries] | 容器退出状态码非 0 时自动重启(可以指定最多重启次数) |
unless-stopped | 宿主机重启时启动容器,除非用户手动 stop 过 |
示例:
# 容器失败时自动重启最多3次
docker run --restart=on-failure:3 nginx# 永远自动重启(除非手动 stop)
docker run --restart=always nginx# 宿主机重启时自动启动(除非你手动 docker stop)
docker run --restart=unless-stopped nginx
2. 容器启动流程(详细)
假设你运行了:
docker run -d --name web --restart=always nginx
背后流程是:
- Docker Daemon 接收命令
- 检查镜像是否存在,若无则拉取
- 创建容器的读写层(overlay2)
- 分配 namespace、设置 cgroup
- 创建网络(默认 bridge 网络)
- 启动容器(调用 containerd -> runC)
- 宿主机重启时,Docker 会根据 restart 策略自动重启该容器
三、小结(图示)
┌─────────────┐│ Docker CLI │└────┬────────┘↓┌──────────────┐│ Docker Daemon│└────┬────┬────┘↓ ↓┌────────┐ ┌────────────┐│runC等工具│ │Containerd │└────────┘ └─────┬──────┘↓┌───────────────────────────────┐│ Linux Namespace + Cgroups ││ OverlayFS 文件系统 ││ 创建容器进程(隔离但共用内核) │└───────────────────────────────┘