写在前面
本文是 Docker 系列第一篇。容器化是云原生的基石,K8s、微服务、CI/CD 都建立在它之上。本文讲清楚 Docker 是什么、容器的底层原理(namespace/cgroups)、核心概念和基本用法。
系列定位:本系列已有 K8s 系列,Docker 是它的前置基础。K8s 系列里提到的容器概念,这里能找到根源。
一、Docker 是什么
1.1 定义
1
2
3
4
5
6
| Docker = 容器化平台
把应用 + 依赖(库、环境、配置)打包成一个「容器」
容器在任何装了 Docker 的机器上都能一致运行
解决的核心问题:
"在我机器上能跑啊!" → 容器保证了环境一致
|
1.2 容器 vs 虚拟机
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| 虚拟机(VM):
硬件级虚拟化
每个 VM 完整操作系统(内核 + 用户空间)
重、慢、占资源(GB 级)
容器(Container):
操作系统级虚拟化
共享宿主机内核,只隔离进程
轻、快、省资源(MB 级)
虚拟机 容器
┌──────────────┐ ┌──────────────┐
│ App │ App │ │ App │ App │
│ 库 │ 库 │ │ 库 │ 库 │
│ 完整OS │完整OS │ │ 容器运行时 │
│ Hypervisor │ │ 宿主机OS内核 │
│ 物理硬件 │ │ 物理硬件 │
└──────────────┘ └──────────────┘
启动分钟级、GB 启动秒级、MB
|
二、核心概念
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| 镜像(Image)
只读模板,包含应用 + 依赖 + 环境
分层存储(Layer)
类比:面向对象的「类」、程序的「安装包」
容器(Container)
镜像的运行实例
可读写(在镜像层上加一层)
类比:「对象」、安装包「运行起来」
仓库(Registry)
存放镜像的地方
Docker Hub(公共)、Harbor(私有)、阿里云/腾讯云镜像服务
类比:代码的 GitHub、npm registry
Dockerfile
描述如何构建镜像的文本文件
一系列指令(FROM/RUN/COPY...)
|
三、容器底层原理
容器不是凭空实现的,它依赖 Linux 内核三个特性:
3.1 Namespace(隔离)
1
2
3
4
5
6
7
8
9
10
11
| Namespace 让容器"以为"自己独占系统
PID Namespace — 进程隔离(容器内 PID 从 1 开始,看不到宿主机进程)
NET Namespace — 网络隔离(独立的网卡、IP、端口、路由)
IPC Namespace — 进程间通信隔离
MOUNT Namespace — 文件系统挂载点隔离
UTS Namespace — 主机名隔离
USER Namespace — 用户隔离(容器内 root ≠ 宿主机 root)
Cgroup Namespace — cgroup 视图隔离
→ 容器 = 一个被 namespace 包裹的进程
|
3.2 Cgroups(资源限制)
1
2
3
4
5
6
7
8
| Cgroups(Control Groups)限制容器能用多少资源
CPU — 限制 CPU 核数/份额
内存 — 限制内存上限(超了 OOM Kill)
磁盘IO — 限制读写速率
网络 — 限速
→ 防止一个容器吃光宿主机资源
|
3.3 联合文件系统(UnionFS)
1
2
3
4
5
6
7
| 镜像分层存储的基础
镜像由多个只读层叠加
容器在镜像上加一个可写层(Copy-on-Write)
多个容器共享相同的镜像层(省空间)
例:基础镜像层 + 安装依赖层 + 应用代码层 + 容器可写层
|
1
2
3
| 一句话总结容器本质:
容器 = Namespace(隔离)+ Cgroups(限制)+ UnionFS(分层镜像)
它不是虚拟机,是一个被特殊隔离和限制的进程
|
四、安装
1
2
3
4
5
6
7
8
9
10
11
| # Linux(Ubuntu/Debian)
curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker
# 将当前用户加入 docker 组(免 sudo)
sudo usermod -aG docker $USER
# 重新登录生效
# 验证
docker version
docker run hello-world
|
1
2
3
4
5
6
| macOS / Windows:
安装 Docker Desktop(图形化,内置 Docker Engine)
Windows 用 WSL2 后端性能更好
国内加速(镜像仓库):
配置 registry-mirrors 指向国内镜像源
|
五、基本命令
5.1 镜像命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 搜索镜像
docker search nginx
# 拉取镜像(默认 Docker Hub)
docker pull nginx
docker pull nginx:1.25 # 指定版本
docker pull nginx:latest
# 列出本地镜像
docker images
# 删除镜像
docker rmi nginx
# 构建镜像(见 Dockerfile 篇)
docker build -t myapp:1.0 .
|
5.2 容器命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # 运行容器
docker run -d --name web -p 8080:80 nginx
# -d 后台运行
# --name web 容器名
# -p 8080:80 端口映射(宿主机:容器)
# nginx 镜像名
# 列出运行中的容器
docker ps
docker ps -a # 包括已停止的
# 启动/停止/重启
docker start web
docker stop web
docker restart web
# 进入容器
docker exec -it web bash # 开个终端进去
# 查看日志
docker logs web
docker logs -f web # 跟踪输出
# 删除容器
docker rm web
docker rm -f web # 强制删除运行中的
# 查看容器详情/资源占用
docker inspect web
docker stats # 实时资源(CPU/内存)
|
六、第一个容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 跑一个 Nginx
docker run -d --name mynginx -p 8080:80 nginx
# 访问 http://localhost:8080 → 看到 Nginx 欢迎页
# 这个 Nginx 跑在容器里,和宿主机隔离
# 进入容器看
docker exec -it mynginx bash
ls /usr/share/nginx/html # 网站文件
exit
# 查看日志
docker logs mynginx
# 停止并删除
docker stop mynginx && docker rm mynginx
|
1
2
3
4
5
| 发生了什么:
1. docker pull nginx(拉镜像)
2. 创建容器(隔离 namespace、限制 cgroups、挂载镜像层)
3. 端口映射(宿主机 8080 → 容器 80)
4. Nginx 进程在容器内跑(PID 1)
|
七、端口、数据、环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 端口映射(-p 宿主机:容器)
docker run -p 8080:80 -p 8443:443 nginx
# 数据卷(持久化,容器删了数据还在)
docker run -v /host/data:/container/data nginx
docker run -v mydata:/var/lib/mysql mysql # 命名卷
# 环境变量
docker run -e MYSQL_ROOT_PASSWORD=123456 mysql
# 工作目录、用户
docker run -w /app -u appuser myimage
# 重启策略
docker run --restart=always nginx # 总是自动重启
|
八、小结
- Docker:容器化平台,解决环境一致性问题
- 容器 vs 虚拟机:容器共享内核、轻量(MB)、秒启动;VM 完整 OS、重(GB)
- 核心概念:镜像(模板)、容器(实例)、仓库(存储)、Dockerfile(构建脚本)
- 底层原理:Namespace(隔离)+ Cgroups(限制)+ UnionFS(分层)
- 基本命令:pull/run/ps/exec/logs/build
下一篇讲 Dockerfile——如何把你的应用打包成镜像。