Fuquanyou Blog记录技术与生活
返回列表

Docker 运行机制介绍

发布于 2026/04/13 · 公开

Docker 运行机制介绍

1. 先用一句话理解 Docker

Docker 的核心是:把应用及其运行环境打包成镜像(image),再基于镜像创建并运行容器(container)。

  • 镜像:静态模板,像“应用安装包 + 运行说明”
  • 容器:镜像启动后的实例,是真正跑起来的进程

2. Docker 在 Linux 上怎么运行

Linux 是 Docker 最“原生”的环境。

2.1 本质

容器不是虚拟机,容器里的进程本质上还是宿主机 Linux 内核上的普通进程,只是被隔离了。

Docker 主要依赖 Linux 内核能力:

  • namespaces:做隔离(进程、网络、挂载点、主机名等)
  • cgroups:做资源限制(CPU、内存、IO)
  • capabilities/seccomp/apparmor:做权限和安全约束
  • 联合文件系统(如 overlay2):做镜像分层和高效复用

2.2 启动链路(简化)

  1. 你执行 docker run ...
  2. Docker CLI 把请求发给 Docker Daemon(dockerd
  3. Daemon 调用 containerd / runc
  4. runc 基于 Linux 内核创建隔离环境并启动进程
  5. 这个进程就是容器中的 PID 1(例如 nginxpython app.py

3. Docker 在 Windows 上怎么运行

Windows 有两种主流模式,容易混淆:

3.1 Linux 容器模式(最常用)

  • 通过 Docker Desktop 使用 WSL2(或早期 Hyper-V)提供一个 Linux 内核环境
  • 实际容器运行在这个 Linux 虚拟环境里,不是直接在 NT 内核上跑 Linux 容器
  • 你在 Windows 上敲 docker 命令,本质是在控制这个 Linux 后端

3.2 Windows 容器模式

  • 运行基于 Windows 内核的容器(镜像通常是 nanoserverwindowsservercore
  • 这时容器依赖 Windows 内核 ABI,不同于 Linux 容器

简单记忆:
日常开发大多数是 Windows + Docker Desktop + WSL2 + Linux 容器。


4. 镜像里到底包含什么

镜像通常包含:

  • 应用代码(或构建产物)
  • 运行时(如 JRE、Node、Python、Go 二进制)
  • 系统库/工具(glibcbashcurl 等)
  • 环境变量默认值
  • 启动命令(CMD / ENTRYPOINT
  • 文件系统分层(只读层)

镜像不包含

  • Linux/Windows 内核本身(容器共享宿主机或后端 VM 的内核)
  • 运行期会变化的数据(除非你写入镜像层,但通常不这么做)

5. 实际运行的到底是什么

运行时真正执行的是:容器内的主进程(PID 1)

例如:

  • docker run nginx:主进程是 nginx 前台进程
  • docker run python:3.12 python app.py:主进程是 python app.py

容器生命周期和这个主进程强绑定:

  • 主进程退出 => 容器退出
  • 主进程存活 => 容器存活

6. 镜像可以运行多次吗

可以,而且这是常态。

  • 一个镜像可以启动任意多个容器实例
  • 每个容器都有自己独立的可写层、网络命名空间、进程空间
  • 类似“同一个安装包,开多个独立程序实例”

示例(同镜像启动 3 个容器):

docker run -d --name web1 -p 8081:80 nginx
docker run -d --name web2 -p 8082:80 nginx
docker run -d --name web3 -p 8083:80 nginx

7. 容器数据存在哪里

容器文件系统通常是“镜像只读层 + 容器可写层”:

  • 可写层:容器删掉通常就丢失
  • Volume(卷):独立持久化,容器删了数据还在
  • Bind Mount:把宿主机目录直接挂进容器,开发场景常用

8. 项目里常见 Docker 文件是干什么的

8.1 Dockerfile

“如何构建镜像”的配方文件。常见指令:

  • FROM:基础镜像
  • WORKDIR:工作目录
  • COPY / ADD:拷贝文件
  • RUN:构建时执行命令(安装依赖等)
  • ENV:环境变量
  • EXPOSE:声明端口
  • CMD / ENTRYPOINT:容器启动命令

8.2 .dockerignore

构建镜像时忽略文件,减少构建上下文大小,提升速度,避免把无关/敏感文件打进镜像(如 node_modules.git、日志等)。

8.3 docker-compose.yml(或 compose.yml

定义多容器应用(服务、网络、卷、环境变量、依赖关系)。
一条命令可启动整套服务:

docker compose up -d

常见用于:web + db + redis + mq 联调环境。

8.4 .env(给 Compose 用)

docker compose 做变量替换(例如端口、密码、镜像 tag)。
注意:不等于容器内自动安全注入,敏感信息建议用 secret 管理策略。

8.5 entrypoint.sh / start.sh

容器启动脚本。常见用途:

  • 启动前等待依赖(数据库就绪)
  • 做一次性初始化(迁移、生成配置)
  • 最后 exec 主进程

8.6 Makefile / scripts/*.sh / scripts/*.ps1

对 Docker 命令做封装(构建、启动、清理、日志查看),统一团队操作习惯。


9. 容易踩的几个认知误区

  • 误区 1:容器 = 虚拟机
    不是。容器更轻量,核心是进程级隔离。

  • 误区 2:镜像里有完整操作系统内核
    没有。容器共享内核。

  • 误区 3:删容器不影响数据
    只有挂到卷/宿主机的数据才稳定持久化。

  • 误区 4:EXPOSE 8080 就能从宿主机访问
    不一定。还要发布端口(-p 8080:8080)。


10. 一套最小实战心智模型

  1. Dockerfile -> 产出镜像
  2. 用镜像 docker run -> 得到容器(进程)
  3. 多个容器用 docker compose 编排
  4. 数据放卷,不放容器可写层
  5. 开发环境用 mount,生产用不可变镜像 + 外部配置
Docker 运行机制介绍