一、容器技术发展三大阶段
容器技术的发展可以分成 3 个阶段:
1️⃣ Jail 时代(1979--2005) → 解决 进程隔离问题
2️⃣ 云计算时代(2006--2013) → 解决 资源管理 + 容器化问题
3️⃣ 云原生时代(2014--至今) → 解决 容器编排 + 生态问题
二、Jail 时代(进程隔离技术)
核心目标:隔离进程运行环境
1️⃣ 1979 --- chroot(容器鼻祖)
-
由 Bell Labs 在 Unix V7 中提出
-
作用:
改变进程的 根目录
进程看到的 / 其实只是一个子目录
隔离效果:
-
进程只能访问自己的文件系统
-
不能访问宿主机文件
因此叫:
Chroot Jail(监狱)
意义:
第一次实现 文件系统隔离
所以:
chroot = 容器技术的鼻祖
2️⃣ 2000 --- FreeBSD Jail
系统:FreeBSD
相比 chroot 增强:
| 隔离类型 | chroot | FreeBSD Jail |
|---|---|---|
| 文件系统 | ✔ | ✔ |
| 进程 | ✘ | ✔ |
| 网络 | ✘ | ✔ |
| IP地址 | ✘ | ✔ |
特点:
每个 Jail:
-
独立文件系统
-
独立进程空间
-
独立网络
-
独立 root 用户
3️⃣ 2001 --- Linux VServer
Linux 上的 Jail 机制
隔离:
-
文件系统
-
网络
-
内存
4️⃣ 2004 --- Solaris Containers
系统:Solaris
新增能力:
-
资源控制
-
快照
-
克隆
📌 Jail 时代总结
主要技术:
chroot
Jail
VServer
Solaris Containers
特点:
-
主要解决 隔离问题
-
应用场景有限
-
没有形成生态
三、云计算时代(容器基础技术)
时间:2006--2013
核心目标:
资源管理 + 容器运行
1️⃣ 2006 --- Process Containers技术
公司:Google
作用:
限制进程资源:
-
CPU
-
内存
-
磁盘 IO
-
网络
后来改名:
cgroups
进入 Linux 内核:
Linux 2.6.24
意义:
实现 资源隔离
2️⃣ 2008 --- LXC(Linux Container)
技术:
-
cgroups
-
Namespace
实现:
真正意义的 Linux 容器
特点:
-
不需要修改 Linux 内核
-
单内核运行多个容器
同一年:
Google 推出
Google App Engine
内部使用调度系统:
Borg
关系:
LXC ≈ Docker 前身
Borg ≈ Kubernetes 前身
3️⃣ 2011 --- Warden
平台:
Cloud Foundry
特点:
-
管理多个容器
-
控制:
-
cgroups
-
namespace
-
进程生命周期
-
4️⃣ 2013 --- LMCTFY
项目:
Let Me Contain That For You
公司:Google
功能:
-
创建容器
-
管理子容器
-
容器嵌套
后来停止维护(2015)
5️⃣ 2013 --- Docker 诞生
公司:Docker, Inc.
Docker 最初:
- 使用 LXC
后来:
- 使用 libcontainer
Docker 最大创新:
不是容器本身,而是 完整生态:
| 技术 | 作用 |
|---|---|
| Image | 镜像 |
| Registry | 镜像仓库 |
| CLI | 命令行 |
| REST API | 管理接口 |
Docker 解决:
容器构建
容器分发
容器运行
因此迅速爆火。
四、云原生时代(容器编排)
时间:2014--至今
核心目标:
容器集群管理
1️⃣ Kubernetes 诞生
2014 年
Google 开源:
Kubernetes
来源:
Google 内部系统:
Borg
解决问题:
-
容器调度
-
服务发现
-
负载均衡
-
自动扩容
-
滚动更新
-
监控
一句话:
Docker 解决容器
Kubernetes 解决容器管理
2️⃣ Docker vs CoreOS 竞争
公司:CoreOS
发布:
容器引擎:
rkt(Rocket)
生态出现两派:
| 阵营 | 技术 |
|---|---|
| Kubernetes | |
| Docker | Swarm |
3️⃣ OCI 标准(2015)
组织:
Open Container Initiative
Docker 捐出:
libcontainer → runc
制定标准:
| 标准 | 作用 |
|---|---|
| Runtime Spec | 容器运行 |
| Image Spec | 镜像格式 |
| Distribution Spec | 镜像分发 |
目的:
避免 Docker 一家独大。
4️⃣ CNCF 成立(2015)
组织:
Cloud Native Computing Foundation
推动:
云原生生态
项目包括:
-
Kubernetes
-
Prometheus
-
etcd
5️⃣ CRI(2016)
K8S 定义接口:
Container Runtime Interface
作用:
让 Kubernetes 可以对接不同容器运行时。
6️⃣ containerd
Docker 捐献:
containerd
作用:
容器运行时
调用链:
Kubernetes
↓
CRI
↓
containerd
↓
runc
↓
Linux kernel
五、最终技术架构
现代 Kubernetes 结构:
Kubernetes
↓
CRI
↓
containerd
↓
runc
↓
Linux Kernel
六、生产环境用什么运行时?
例如:
腾讯云:
Tencent Kubernetes Engine
支持:
-
Docker
-
containerd
推荐:
containerd
原因:
| 优点 | 说明 |
|---|---|
| 组件少 | 调用链短 |
| 稳定 | 更少故障 |
| 资源少 | 更轻量 |
Docker 适合:
-
docker build
-
docker push
-
docker API
-
docker compose
七、最简单理解(核心总结)
容器技术发展逻辑:
1979
chroot
(文件隔离)
↓
2006
cgroups
(资源隔离)
↓
2008
LXC
(真正容器)
↓
2013
Docker
(容器生态)
↓
2014
Kubernetes
(容器编排)
↓
现在
云原生生态
一句话总结:
Docker 解决:如何运行容器
Kubernetes 解决:如何管理容器
一、基础概念
1️⃣ 物理机
-
实际的服务器或计算机。
-
提供硬件环境给虚拟机。
-
也称为"宿主"或"寄主"。
2️⃣ 虚拟化(Virtualization)
-
将一台物理机虚拟成 多台逻辑计算机。
-
每台逻辑机可以运行不同的操作系统。
-
应用程序在互相独立的空间内运行。
-
目的:提高资源利用率,实现隔离。
类比:
-
物理机:庄园
-
虚拟机:楼盘里的各套房子,共享宅基地和花园
3️⃣ 容器化(Containerization)
-
操作系统层虚拟化(OS-level virtualization)。
-
将操作系统内核虚拟化,用户空间被分割成多个 独立单元。
-
每个单元叫 容器(Container)。
-
容器共享操作系统内核,但拥有独立的应用环境。
类比:
- 容器:房子里面的胶囊公寓,共享厨房、卫生间和 WiFi,私人物品独立。
特点:
-
更轻量级
-
启动更快(秒级或毫秒级)
-
提供沙箱安全环境
4️⃣ Docker
-
当前容器技术的 事实标准。
-
将应用及依赖打包成镜像,可在任意服务器运行。
-
提供完整生态:镜像管理、仓库、CLI、API 等。
二、虚拟化与容器化的优势
-
资源利用率高
-
低利用率的物理机资源整合使用
-
减少硬件成本和运维成本
-
-
环境标准化
-
"一次构建,随处执行"
-
镜像包含完整运行环境,避免开发/测试/生产不一致问题
-
-
资源弹性伸缩
-
动态调整计算、存储、网络资源
-
例:双 11 大促,临时扩容 100 个容器
-
-
差异化环境提供
-
多套不同操作系统或应用环境
-
例:一个服务依赖 Ubuntu,另一个依赖 CentOS
-
-
沙箱安全
-
容器内执行危险操作不会影响宿主机
-
例:容器内执行
rm -rf /*不会摧毁服务器
-
-
轻量化和快速启动
-
容器无需启动完整操作系统
-
启动比虚拟机快很多
-
-
维护和扩展容易
-
镜像分层技术,重复部分复用
-
官方镜像丰富,可直接使用或定制
-
三、虚拟化技术层次
| 层次 | 功能 |
|---|---|
| 硬件层 | 提供硬件抽象、设备接口 |
| 操作系统层 | 系统调用接口,管理资源 |
| 程序库层 | 提供数据结构、函数接口 |
| 应用层 | 具体应用运行环境 |
四、常见虚拟化实现
1️⃣ 虚拟机(VM)
-
位置:硬件层 ↔ 操作系统层之间
-
"伪造"硬件接口,将整个操作系统封装起来
-
优点:跨平台
-
缺点:资源开销大、启动慢
例子:
- Windows 上运行 Android 虚拟机
2️⃣ 容器
-
位置:操作系统层 ↔ 函数库层之间
-
"伪造"操作系统接口,将应用及依赖封装
-
优点:轻量、启动快
-
缺点:必须共享宿主操作系统内核
技术实现:
- Linux Namespace + Cgroups
3️⃣ JVM 等虚拟机
-
位置:函数库层 ↔ 应用层之间
-
提供统一运行环境,解决跨平台问题
-
例子:Java 程序在不同系统上运行
五、虚拟化常见方式
主机虚拟化(Hypervisor)
通过虚拟化层在物理服务器上创建虚拟机。
类型
-
Type 1(裸机型)
-
直接运行在硬件上
-
Hypervisor 管理资源
-
客户机独立运行
-
例:Xen、VMware ESX
-
-
Type 2(托管型)
-
运行在宿主操作系统上
-
客户机作为宿主系统的进程运行
-
例:VMware Workstation
-
六、虚拟化 vs 容器对比
| 特性 | 虚拟机 | 容器 |
|---|---|---|
| 资源占用 | 高 | 低 |
| 启动速度 | 分钟级 | 秒级/毫秒级 |
| 隔离方式 | OS + 应用 | 应用级隔离 |
| 跨平台能力 | 强 | 受宿主系统限制 |
总结:
-
虚拟机封装整个操作系统 → 重量级、启动慢
-
容器只封装应用及依赖 → 轻量、启动快
一、为什么会有 CentOS 镜像?
1️⃣ 容器镜像不是完整操作系统
-
容器镜像包含 运行应用所需的用户空间环境,而不是完整内核。
-
它可以包含:
-
系统工具(bash、ssh、常用命令)
-
库文件(glibc 等)
-
包管理器(yum、apt)
-
应用依赖
-
注意:容器 共享宿主机的内核,不需要自己的内核,所以镜像体积远小于安装在物理机的操作系统。
2️⃣ CentOS 镜像 = 运行环境
-
开发者习惯在 CentOS 上部署应用,应用可能依赖 CentOS 的包管理器或默认库。
-
因此,Docker 提供 CentOS 基础镜像 ,里面有 CentOS 的用户空间,但 不包含内核。
-
你启动一个 CentOS 容器时,其内核其实还是宿主机的 Linux 内核。
3️⃣ 容器镜像层级
以一个应用运行的容器为例:
宿主机内核(Linux kernel) ← 共享
容器镜像(CentOS 基础镜像)
├─ 系统工具(bash, vim, yum)
├─ 系统库(glibc, libstdc++ 等)
└─ 应用依赖
应用(你要运行的服务)
关键点:
-
内核共享 → 容器比虚拟机轻量
-
用户空间隔离 → 看起来就像自己有一个 CentOS 系统
二、为什么需要不同系统镜像?
- 应用依赖差异化
-
有的应用需要 Ubuntu 的库,有的需要 CentOS 的库
-
容器可以让不同应用在同一宿主机上运行,而不用安装多个操作系统
- 环境一致性
-
开发环境和生产环境一致,避免"我电脑上可以跑"的问题
-
只要镜像是 CentOS 7,哪里启动都是一样的环境
- 快速部署
-
不用完整安装操作系统,直接用 CentOS 镜像运行秒级启动
-
方便 CI/CD、自动化部署
三、核心理解
✅ 容器里的 CentOS ≠ 真正的操作系统
-
它只是 用户空间
-
内核仍由宿主机提供
-
提供熟悉的系统环境,让应用可以"以为自己在 CentOS 上运行"
一、容器虚拟化概述
-
容器虚拟化是 操作系统层的虚拟化,不同于主机虚拟化(虚拟机)。
-
核心实现:
-
Namespace(命名空间) → 资源隔离
-
Cgroups(控制组) → 资源控制
-
二、Namespace(命名空间)
1️⃣ 概念
-
Linux 内核用来 隔离资源 的机制。
-
不同 namespace 的进程只能看到自己相关的资源,互相看不到。
-
通过 clone()、setns()、unshare() 系统调用创建和操作 namespace。
2️⃣ 常用 Namespace 类型
| Namespace | 调用参数 | 隔离资源 | 内核版本 |
|---|---|---|---|
| UTS | CLONE_NEWUTS | 主机名、域名 | 2.6.19 |
| IPC | CLONE_NEWIPC | 信号量、消息队列、共享内存 | 2.6.19 |
| PID | CLONE_NEWPID | 进程编号 | 2.6.24 |
| Network | CLONE_NEWNET | 网络设备、IP、端口 | 2.6.29 |
| Mount | CLONE_NEWNS | 文件系统挂载点 | 2.4.19 |
| User | CLONE_NEWUSER | 用户和用户组 | 3.8 |
3️⃣ Namespace 的作用(容器场景)
-
UTS:容器独立 hostname 和域名
-
IPC:同一个 namespace 内可通信,不同 namespace 不可通信
-
PID:每个容器有独立 PID,容器内 root 进程 PID 可为 1
-
Network:独立网络栈和 IP
-
Mount:独立文件系统
-
User:容器内用户隔离
NameSpace 隔离实战
一、实战目的
-
了解 隔离能力来源于 Linux 内核,而不是 Docker 本身。
-
通过实际操作理解 PID Namespace 和 Mount Namespace 的隔离效果。
二、基础工具命令
1️⃣ dd(数据复制/转换)
-
用途:读取、转换并输出数据。
-
常用参数:
-
if=文件:输入源 -
of=文件:输出目的 -
bs=大小:读写块大小 -
count=块数:指定复制块数 -
conv=ucase:转换小写字母为大写
-
-
示例:
生成 1 个 80MB 镜像文件
dd if=/dev/zero of=fdimage.img bs=8k count=10240
将文件内容转换为大写
dd if=testfile_2 of=testfile_1 conv=ucase
2️⃣ mkfs(创建文件系统)
-
用途:格式化磁盘或镜像文件
-
常用参数:
-t ext4:指定文件系统类型
-
示例:
格式化镜像文件为 ext4
mkfs -t ext4 ./fdimage.img
3️⃣ df(查看磁盘使用情况)
-
常用参数:
-
-h:人类可读 -
-T:显示文件系统类型
-
-
示例:
df -h # 查看使用情况
df -Th # 查看使用情况 + 文件系统类型
4️⃣ mount(挂载文件系统)
-
用途:将文件系统挂载到指定目录
-
常用参数:
-
-t:文件系统类型(可省略) -
-o loop:将文件当作块设备挂载 -
-o ro/-o rw:只读/读写挂载
-
-
示例:
挂载镜像文件到目录
mkdir -p /mnt/testext4
mount -o loop ./fdimage.img /mnt/testext4
5️⃣ unshare(运行隔离命名空间)
-
用途:在不共享父进程 namespace 的环境中运行程序
-
常用参数:
-
-iIPC 隔离 -
-mMount 隔离 -
-nNetwork 隔离 -
-pPID 隔离 -
-uUTS 隔离 -
-U用户隔离 -
--fork创建子进程执行 -
--mount-proc挂载/proc以支持 ps/top 等命令
-
-
示例:
UTS(主机名)隔离
unshare -u /bin/bash
hostname test1
hostname # 输出 test1
exit
hostname # 返回宿主机原名
PID Namespace 隔离
unshare --fork --pid --mount-proc /bin/bash
ps -ef # 只能看到 namespace 内进程
Mount Namespace 隔离
unshare --mount --fork /bin/bash
三、实战操作
1️⃣ PID 隔离
-
步骤:
-
查看宿主机进程:
ps -ef -
创建隔离 bash:
unshare --fork --pid --mount-proc /bin/bash
-
查看进程:
ps -ef- 启动进程 PID 1 变为 bash,说明隔离成功
-
退出:
exit
-
2️⃣ Mount 隔离
-
步骤:
-
查看宿主机磁盘挂载:
df -h -
创建隔离 bash:
unshare --mount --fork /bin/bash
- 创建镜像并格式化:
dd if=/dev/zero of=fdimage.img bs=8k count=10240
mkfs -t ext4 ./fdimage.img
- 挂载镜像:
mkdir -p /data/tmpmount
mount ./fdimage.img /data/tmpmount
- 创建文件:
echo "Hello world!" > /data/tmpmount/hello.txt
-
验证隔离:
-
窗口 B 查看文件:存在
-
窗口 A 查看文件:不存在
-
-
-
退出隔离 bash:
exit
💡 总结
-
NameSpace 是内核提供的隔离机制,Docker 只是封装和管理这些机制。
-
PID Namespace:每个容器有独立的进程空间
-
Mount Namespace:每个容器有独立文件系统视图
-
UTS/IPC/Network/User Namespace:分别隔离主机名、进程通信、网络、用户等
-
实战显示:隔离生效,宿主机无法看到容器内新进程或挂载文件
当bash退出后,文件系统还存在吗
1 镜像文件还在
你创建的文件:
dd if=/dev/zero of=fdimage.img bs=8k count=10240
这是一个 普通文件,在宿主机磁盘上。
所以即使你 exit 退出 namespace:
ls
fdimage.img
这个文件 一定还存在。
2 挂载会消失
你在 namespace 里执行:
mount ./fdimage.img /data/tmpmount
这个挂载是在 Mount Namespace B 里。
当你执行:
exit
发生的事情是:
-
namespace 里的 最后一个进程结束
-
这个 Mount Namespace 被销毁
-
namespace 内所有 挂载关系一起消失
所以:
| 项目 | 是否存在 |
|---|---|
| fdimage.img | ✅ 还在 |
| /data/tmpmount 挂载 | ❌ 消失 |
| hello.txt | ✅ 在镜像里 |
3 为什么 hello.txt 还在
因为你写入的是:
echo "Hello world!" > /data/tmpmount/hello.txt
实际上写到了:
fdimage.img 这个 ext4 文件系统里
所以只要你重新挂载:
mount -o loop fdimage.img /data/tmpmount
再看:
cat /data/tmpmount/hello.txt
你会看到:
Hello world!
4 整个过程本质
退出前:
Mount Namespace B
/data/tmpmount
│
▼
fdimage.img
│
▼
hello.txt
退出后:
宿主机
fdimage.img
└── hello.txt (还在里面)
但没有挂载点
5 一个非常关键的理解(容器核心)
Docker 容器退出后:
-
namespace 消失
-
挂载消失
-
文件系统还在(镜像层)
这就是为什么:
-
容器删了
-
镜像还在
三、Cgroups(控制组)
1️⃣ 概念
-
Linux 内核机制,用于 限制、统计和控制资源。
-
作用于进程组,通过内核钩子(hook)在运行时限制或统计资源使用。
2️⃣ 作用
-
资源限制:CPU、内存使用上限
-
优先级控制:CPU 分配、IO 优先级
-
资源统计:生成资源占用报告
-
控制:暂停/恢复进程
3️⃣ 常用子系统(Subsystems)
| 子系统 | 功能 |
|---|---|
| blkio | 块设备 IO 限制 |
| cpu | CPU 时间片分配 |
| cpuacct | CPU 资源统计 |
| cpuset | 分配独立 CPU / 内存节点 |
| devices | 设备文件访问限制 |
| freezer | 暂停/恢复任务 |
| memory | 内存限制与统计 |
| perf_event | 性能监控 |
| net_cls | 网络流量分类 |
| hugetlb | 大页内存限制 |
| pids | 进程数量限制 |
| rdma | RDMA 资源限制 |
一、Cgroups 资源控制(核心概念)
Cgroups(Control Groups)
是 Linux 内核提供的 资源限制机制,用于控制:
-
CPU
-
Memory
-
IO
-
PID
-
网络
-
设备
容器技术(Docker / Kubernetes)的 资源限制本质就是调用 Cgroups。
一句话理解:
Namespace = 资源隔离
Cgroups = 资源限制
例如:
docker run -m 100m --cpus=0.5 nginx
本质就是:
Linux Cgroups 限制
Memory = 100MB
CPU = 0.5
二、压力测试工具
1 pidstat(资源监控)
作用
监控进程资源使用情况:
-
CPU
-
Memory
-
IO
-
Thread
语法
pidstat [选项] [时间间隔] [次数]
常用参数
| 参数 | 含义 |
|---|---|
| -u | 查看 CPU |
| -r | 查看内存 |
| -d | 查看 IO |
| -p | 指定 PID |
| -C | 指定进程名 |
| -l | 显示完整命令 |
示例
查看 stress 进程内存:
pidstat -r -C stress -p ALL 1
查看 CPU:
pidstat -u -C stress -p ALL 1
-
pidstat:用来显示每个进程的统计信息,包括 CPU、内存、I/O 等。 -
-r:表示显示 内存使用情况(resident memory statistics),比如 RSS、虚拟内存大小等。 -
-C stress:表示只显示 命令名包含stress的进程。 -
-p ALL:表示显示 所有进程 的信息,而不是单个 PID。-
-p <pid>:通常你可以指定某个进程 ID,比如-p 1234。 -
-p ALL:特殊关键字,意思是所有符合条件的进程 (在这里,由于-C stress,实际上就是所有命令名包含stress的进程)。
-
-
1:表示每隔 1 秒刷新一次统计信息。
2 stress(压力测试工具)
用于模拟系统压力。
常用参数
| 参数 | 含义 |
|---|---|
| -c N | CPU 压力 |
| -m N | 内存压力 |
| --vm-bytes | 指定内存大小 |
| --vm-keep | 持续占用 |
| -i N | IO 压力 |
| -d N | 磁盘压力 |
| -t N | 运行时间 |
示例
CPU 压力:
stress -c 1
-c 1 的意思
-
-c代表 CPU workers(CPU 工作线程数量)。 -
1表示创建 1 个占用 CPU 的线程。 -
这个线程会不停地进行计算,占用 100% 的一个 CPU 核心。
所以:
stress -c 1
意思就是:启动一个 CPU 线程,让一个核心满负荷工作。
如果你的机器有 4 个核心,这条命令只会占满其中 1 个核心,其余核心空闲。
内存压力:
stress -m 1 --vm-bytes 50M
1️⃣ -m 1
-
-m代表 memory workers ,也就是 内存压力线程。 -
1表示创建 1 个线程 来分配和使用内存。
2️⃣ --vm-bytes 50M
-
这个参数指定 每个 memory worker 分配的内存大小。
-
50M表示每个线程占用 50MB 内存。
所以这条命令意思就是:
启动 1 个内存工作线程,并让它分配并占用 50MB 内存,持续进行读写操作,从而制造内存压力。
三、Cgroups 版本
Linux 有两个版本:
| 版本 | 特点 |
|---|---|
| cgroup v1 | 多层级控制 |
| cgroup v2 | 统一控制(新版本) |
查看支持情况
cat /proc/filesystems | grep cgroup
如果看到:
cgroup
cgroup2
说明支持 v2。
查看当前使用版本
stat -fc %T /sys/fs/cgroup/
结果:
cgroup2fs → 使用 cgroup v2
tmpfs → 使用 cgroup v1
四、查看进程的 Cgroup
查看当前 shell:
cat /proc/$$/cgroup
示例:
0::/user.slice/user-0.slice/session-2.scope
说明该进程属于:
/sys/fs/cgroup/user.slice/user-0.slice/session-2.scope
进入查看:
cd /sys/fs/cgroup/user.slice/user-0.slice/session-2.scope
可以看到各种资源控制文件:
cpu.max
memory.max
pids.max
memory.current
cpu.stat
五、Cgroups 内存控制
目标:
限制进程最大使用 20MB 内存
1 创建 cgroup
cd /sys/fs/cgroup
mkdir test_memory
2 设置内存限制
echo 20M > memory.max
等价:
20 * 1024 * 1024 = 20971520
3 启动内存压力
stress -m 1 --vm-bytes 50M
该进程尝试使用:
50MB
4 查看进程 PID
pidstat -r -C stress -p ALL 1
例如:
PID = 4746
5 将进程加入 cgroup
echo 4746 > cgroup.procs
6 结果
因为限制:
最大 20MB
但进程申请:
50MB
所以:
进程被 OOM kill
进程退出。
当然也会有另一种情况,就是进程没有被杀死,而是申请的内存被限制到20m
六、Cgroups CPU 控制
目标:
限制 CPU 使用率 30%
1 创建 cgroup
cd /sys/fs/cgroup
mkdir test_cpu
2 启动 CPU 压力
stress -c 1
CPU:
100%
3 查看 CPU
pidstat -u -C stress -p ALL 1
示例:
%CPU = 99%

第一个进程是stress程序本身,第二个进程是cpu压力进程
4 设置 CPU 限制
CPU 限制公式:
CPU 使用率 = quota / period
默认:
period = 100000
限制:
30%
所以:
quota = 30000
设置:
echo "30000 100000" > cpu.max
5 加入 cgroup
查看 PID:
4782
加入:
echo 4782 > cgroup.procs
6 结果
CPU 使用率从:
100%
变为:
30%
说明限制成功。
重启pidstat

七、总结(容器底层核心)
容器底层就是这两件事:
| 技术 | 作用 |
|---|---|
| Namespace | 资源隔离 |
| Cgroups | 资源限制 |
Docker 做的事情本质就是:
创建 namespace
创建 cgroup
运行进程
例如:
docker run -m 100m --cpus=0.5 nginx
实际上就是:
memory.max = 100M
cpu.max = 50000 100000
八、容器核心架构(一定要记住)
Docker
│
▼
┌────────────────┐
│ Containerd │
└────────────────┘
│
▼
┌────────────────┐
│ runc │
└────────────────┘
│
┌──────────┴──────────┐
▼ ▼
Namespace Cgroups
(隔离) (限制)
四、LXC(Linux Containers)
1️⃣ 概念
-
LXC 是 操作系统层的虚拟化工具集
-
使用 Namespace + Cgroups 提供隔离和资源管理
-
可以将应用和所需依赖打包成容器,形成独立沙箱
2️⃣ 特点
-
简化容器创建和管理
-
隔离性比虚拟机弱,但比传统进程强
-
后续 Docker 在 LXC 基础上增强了易用性和生态系统
五、容器虚拟化总结
-
Namespace → 隔离资源(进程、网络、文件系统等)
-
Cgroups → 控制资源使用(CPU、内存、IO)
-
容器 = Namespace + Cgroups + 用户空间环境
-
LXC → 早期容器管理工具,Docker 是 LXC 的增强版
💡 核心理解:
-
容器是轻量级虚拟化,只隔离用户空间,不需要独立内核
-
Namespace 提供隔离,Cgroups 提供资源限制
-
LXC、Docker 等是操作接口和管理工具,方便使用和部署
Docker 概述
-
本质:Docker 本身不是容器,它是对 Linux 容器技术(如 LXC)的增强与封装,使容器使用更加简单易用。
-
核心目标:Build、Ship、Run Any App, Anywhere(一次封装,到处运行)。
-
实现语言:Go
-
早期版本:基于 LXC
-
镜像机制:
-
镜像文件包含操作系统用户空间所需组件。
-
Docker 创建容器时直接使用镜像启动,不再通过模板安装操作系统。
-
镜像集中存储在仓库,创建容器命令简化为
docker run/docker stop。
-
Docker 引擎迭代
| 版本 | 说明 |
|---|---|
| LXC | Docker 早期使用的 Linux 容器管理引擎 |
| libcontainer | Docker 自建容器引擎,用于替代 LXC |
| runc | CNCF 标准化容器引擎,由 libcontainer 核心功能拆分而来 |
| Moby | Docker 公司开源项目,Docker Engine 基于此项目 |
| docker-ce | 社区版 Docker(开源) |
| docker-ee | 企业版 Docker(收费) |
Docker 与虚拟机对比
| 特性 | 传统虚拟机 | Docker 容器 |
|---|---|---|
| 磁盘占用 | 几 GB - 几十 GB | 几十 MB - 几百 MB |
| CPU/内存占用 | 高,需要虚拟层调用 | 低,直接使用宿主机资源 |
| 启动速度 | 分钟级 | 秒级 |
| 安装/管理 | 复杂,需要专业运维 | 简单,命令操作即可 |
| 应用部署 | 手动部署 | 自动化部署 |
| 隔离性 | 系统级 | 进程级 |
| 封装程度 | 打包整个操作系统 | 打包应用代码及依赖 |
原因:Docker 无需加载 Guest OS,直接利用宿主机内核,减少了虚拟层和 OS 内核开销,因此启动快、资源利用率高。
Docker 与 JVM 对比
| 特性 | JVM | Docker 容器 |
|---|---|---|
| 性能 | JVM 本身消耗 CPU/内存 | 几乎无损耗 |
| 虚拟层面 | 只模拟 JVM 平台 | 模拟整个操作系统 |
| 代码无关性 | 仅支持特定代码 | 支持任意应用程序(同平台) |
| 主机隔离性 | 不隔离宿主机 | 利用 Linux Namespace 实现隔离 |
Docker 优势
-
易用性:一次封装,到处运行
-
高效:启动快,资源占用低
-
可移植:镜像可跨平台部署
-
自动化:便于 CI/CD 与微服务管理
1️⃣ Docker 架构概览
Docker 采用 客户端-服务器 (C/S) 架构,主要组件有:
| 组件 | 作用 | 对应生活案例 |
|---|---|---|
| Docker Client | 通过命令行或工具发送指令给 Docker Daemon | 我们去酒店前台办理入住/退房 |
| Docker Daemon | 核心后台服务,负责创建、管理容器 | 酒店前台,处理入住、退房 |
| Docker Host | 运行 Docker 守护进程和容器的物理或虚拟机 | 酒店的建筑和地块 |
| Docker Image | 容器的模板,包含应用和依赖 | 酒店的标准房型,如大床房、标间 |
| Docker Container | 镜像运行后的实例,可以独立操作 | 客人入住的具体房间,个性化使用 |
| Docker Registry | 存放镜像的仓库 | 酒店提供的房型目录,或 Docker Hub |
生活案例总结:
-
镜像 = 房型(标准化)
-
容器 = 实际入住的房间(个性化)
-
客户端 = 客人
-
守护进程 = 前台服务
-
主机 = 酒店建筑
2️⃣ Docker 设计背后的动机
Docker 出现不是偶然,而是时代背景推动:
-
数据爆炸
-
全球数据量快速增长(2018 → 2025 年增 5 倍以上)
-
中国企业级数据量增长特别快,需要高效处理
-
-
计算能力提升
-
大型云服务商(阿里云、腾讯云)拥有数百万台服务器
-
快速扩容能力变得关键
-
-
软件需求爆发
-
研发模式从瀑布到敏捷 → 发布频繁,迭代快
-
需要版本管理、快速回滚、共享软件
-
环境搭建复杂,语言和依赖多样
-
3️⃣ Docker 的解决方案
Docker 针对以上问题,提供了几类解决方案:
| 问题 | Docker 如何解决 |
|---|---|
| 频繁的软件发布、回滚 | 镜像(Image)打包应用及依赖,带版本标签 |
| 软件共享 | Docker Hub(公共仓库)或私有仓库 |
| 环境复杂 | 镜像内包含完整运行环境,一条命令即可启动 |
| 数据处理 | 可以在大规模主机上快速部署容器,利用云计算资源 |
核心思想:
用 镜像 标准化应用,用 容器 快速运行和隔离,用 仓库 统一管理和分发。
💡 小结
Docker 把环境、依赖和应用打包在镜像里,让开发者不用担心"我的电脑能跑,服务器不行",容器则像房间一样隔离运行,Docker Hub 则像房型目录,方便快速获取和分发。
1️⃣ Docker 安装
-
Docker 可以在 Linux、Windows、macOS 上安装。
-
安装完成后,通常通过以下方式验证:
docker --version # 查看 Docker 版本
docker info # 查看 Docker 系统信息
-
如果国内访问 Docker Hub 速度慢,可以配置 国内镜像加速器:
-
阿里云、网易云、百度云等提供镜像加速服务
-
配置方法:
-
编辑
/etc/docker/daemon.json -
添加:
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
]
}
-
重载配置并重启 Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl status docker
-
-
2️⃣ Docker Registry(镜像仓库)
(1) 基本概念
-
Registry:存储、管理和分发 Docker 镜像
-
Repository:镜像仓库中的一个具体项目,包含多个镜像版本
-
镜像名称 + 标签 :唯一标识一个镜像,如
nginx:latest -
认证:支持用户注册、登录、登出
-
索引:方便检索镜像
生活类比:
-
Registry = 超市
-
Repository = 某个货架
-
Tag = 商品不同版本或规格
(2) 镜像结构
一个 Docker 镜像包含:
-
元数据(Metadata)
- 由 Dockerfile 构建,记录镜像层、checksum 等信息
-
数据层(Blob)
- 真正的可执行文件和依赖,占用存储空间
3️⃣ 镜像仓库分类
按是否对外开放
-
公有仓库:例如 Docker Hub、阿里云公有镜像,任何人可访问
-
私有仓库:公司内部使用,仅内部人员可访问
按提供者类型
-
Sponsor Registry:第三方注册提供,面向社区
-
Mirror Registry:第三方镜像加速,仅供客户使用
-
Vendor Registry:官方或厂商提供,如 Google、RedHat
-
Private Registry:私有内部仓库,无防火墙或安全层,仅公司内部使用
4️⃣ 镜像仓库工作流程
使用流程
-
登录仓库:
docker login -
拉取镜像:
docker pull <镜像名>:<tag> -
制作镜像:通过 Dockerfile 构建,或
docker commit -
上传镜像:
docker push <镜像名>:<tag>
拉取机制
-
启动容器时,Docker Daemon 先查本地镜像
-
如果不存在,则从 Registry 下载并保存到本地
常用环境对应
| 环境 | 作用 |
|---|---|
| 开发环境 | 开发人员写代码、调试 |
| 测试环境 | QA 测试软件功能 |
| 预发布环境 | 模拟生产环境做最后验证 |
| 生产环境 | 真正面向用户提供服务 |
5️⃣ 常用镜像仓库
1. 公有仓库
-
Docker Hub:
-
海量官方和认证组织镜像
-
提供检索、版本管理、自动构建、Webhook 支持
-
可以注册私有仓库
-
2. 国内加速器
-
阿里云、网易云、百度云提供加速地址
-
适合国内拉取镜像更快
3. 私有仓库
-
Harbor:企业级,支持角色管理、LDAP 集成、审计日志
-
Nexus:兼容 Maven、Docker 等仓库
-
Docker Registry:Docker 官方提供私有镜像仓库
💡 总结
-
Docker Registry 是 Docker 镜像的"仓库",包含多个 Repository
-
镜像有版本(Tag),由元数据和数据层组成
-
镜像可以公有或私有,方便共享和管理
-
国内用户常用加速器提高下载速度
-
私有仓库适合企业内部使用,支持 CI/CD 流程
Docker 镜像仓库命令整理
一、命令清单
| 命令 | 别名 | 功能 | 重要程度 |
|---|---|---|---|
| docker login | - | 登录镜像仓库 | ⭐ 必须掌握 |
| docker pull | docker image pull | 拉取镜像 | ⭐ 必须掌握 |
| docker push | docker image push | 推送镜像 | ⭐ 必须掌握 |
| docker search | - | 查找镜像 | 了解 |
| docker logout | - | 退出仓库登录 | ⭐ 必须掌握 |
二、docker login(登录仓库)
1 功能
登录 Docker 镜像仓库。
如果不指定仓库地址,默认登录 Docker Hub。
由于国内访问 Docker Hub 可能受限,可以使用:
-
阿里云镜像仓库
-
腾讯云镜像仓库
2 语法
docker login [OPTIONS] [SERVER]
3 关键参数
| 参数 | 说明 |
|---|---|
| -u | 用户名 |
| -p | 密码 |
4 示例
docker login -u 用户名 -p 密码
三、docker pull(拉取镜像)
1 功能
从镜像仓库 拉取或更新镜像 到本地。
2 语法
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
3 别名
docker image pull
4 关键参数
| 参数 | 说明 |
|---|---|
| -a | 拉取所有 tag 的镜像 |
| --disable-content-trust | 忽略镜像校验(默认开启校验) |
5 示例
docker pull nginx:1.23.3
说明:
-
nginx → 镜像名
-
1.23.3 → 版本 tag
四、docker push(推送镜像)
1 功能
将 本地镜像上传到镜像仓库。
注意:
必须 先登录仓库 才能推送。
2 语法
docker push [OPTIONS] NAME[:TAG]
3 别名
docker image push
4 关键参数
| 参数 | 说明 |
|---|---|
| -a | 推送所有 tag |
| --disable-content-trust | 忽略镜像校验 |
5 示例
docker push myapache:v1
说明:
-
myapache → 镜像名
-
v1 → 版本号
需要先给镜像打好标签才可以推送
五、docker search(查找镜像)
1 功能
在 Docker Hub 搜索镜像。
⚠️ 注意
国内网络一般无法直接访问 Docker Hub。
2 语法
docker search [OPTIONS] TERM
3 关键参数
| 参数 | 说明 |
|---|---|
| --no-trunc | 显示完整镜像描述 |
| -f | 过滤条件 |
4 示例
docker search -f stars=10 nginx
含义:
搜索 名称包含 nginx 且 star ≥ 10 的镜像
六、docker logout(退出登录)
1 功能
退出 Docker 镜像仓库登录。
如果不指定仓库地址,默认退出 Docker Hub。
2 语法
docker logout [SERVER]
3 示例
docker logout
七、最常用的 3 个命令(必须熟)
实际工作 / 面试 / 实验中最常用的是:
docker login
docker pull
docker push
基本流程:
1 登录仓库
docker login
2 拉取镜像
docker pull nginx
3 推送镜像
docker push myimage:v1
一、镜像命令(部分)
在学习镜像仓库之前,需要先了解一些 镜像相关命令,为后续 Docker 实战做准备。
1 docker images(查看镜像)
功能
列出 本地已有的镜像。
语法
docker images [OPTIONS] [REPOSITORY[:TAG]]
别名
docker image ls
docker image list
常用参数
| 参数 | 说明 |
|---|---|
| -a | 列出所有镜像(包括中间层镜像) |
| --digests | 显示镜像摘要信息 |
| -f | 根据条件过滤镜像 |
| --format | 指定输出格式 |
| --no-trunc | 显示完整镜像信息 |
| -q | 只显示镜像 ID |
示例
查看本地所有镜像
docker images
示例输出:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 142MB
ubuntu 22.04 6b7dfa7e8fdb 3 weeks ago 77MB
查看 ubuntu 相关镜像
docker images ubuntu
2 docker image inspect(查看镜像详情)
功能
查看 镜像的详细信息(JSON格式)。
例如:
-
镜像ID
-
创建时间
-
架构
-
层信息
-
环境变量
语法
docker image inspect [OPTIONS] IMAGE [IMAGE...]
示例
docker image inspect nginx:1.23.3
3 docker tag(镜像打标签)
功能
给本地镜像 重新打标签,并归入某个仓库。
通常用于:
-
上传镜像到仓库
-
修改镜像版本
语法
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
别名
docker image tag
示例
docker tag ubuntu:22.04 myregistry.com/myubuntu:22.04
含义:
原镜像
ubuntu:22.04
新标签
用于之后 push 到仓库。
二、容器命令(部分)
学习仓库前需要了解一些 容器基础命令。
1 docker run(运行容器)
功能
创建并运行一个新的容器。
语法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
别名
docker container run
常用参数(重点)
| 参数 | 说明 |
|---|---|
| -d | 后台运行容器 |
| -i | 交互模式 |
| -t | 分配终端 |
| -p | 端口映射 |
| -P | 随机端口映射 |
| --name | 指定容器名称 |
| -e | 设置环境变量 |
| -v | 挂载数据卷 |
| -m | 限制内存 |
| --network | 指定网络 |
| --rm | 退出后自动删除容器 |
常见组合
-it
用于进入容器交互终端
docker run -it ubuntu bash
-d
后台运行容器
docker run -d nginx
示例
1 创建 nginx 容器
docker run --name mynginx -d nginx:latest
含义:
--name mynginx 容器名字
-d 后台运行
nginx:latest 镜像
2 端口映射 + 目录挂载
docker run -p 80:80 -v /data:/data -d nginx:latest
含义:
-p 80:80 宿主机80 → 容器80
-v /data:/data 挂载目录
-d 后台运行
2 docker ps(查看容器)
功能
列出 正在运行的容器。
语法
docker ps [OPTIONS]
别名
docker container ls
docker container list
docker container ps
常用参数
| 参数 | 说明 |
|---|---|
| -a | 显示所有容器 |
| -f | 按条件过滤 |
| -l | 显示最近创建容器 |
| -n | 显示最近 n 个容器 |
| -q | 只显示容器 ID |
| -s | 显示容器大小 |
| --no-trunc | 不截断输出 |
示例
查看运行中的容器
docker ps
查看所有容器
docker ps -a
三、最常用的 Docker 命令(新手必须记)
日常最常用的就是这几个:
docker images 查看镜像
docker pull 下载镜像
docker run 运行容器
docker ps 查看容器
docker tag 打标签
docker push 推送镜像
Docker 镜像仓库实战整理
实战一:搭建一个 Nginx 服务
1️⃣ 基础知识
-
Web 服务器:提供网站文件、文档和下载服务的程序。
-
WWW 服务器:World Wide Web 服务器,是最常用的 Web 服务。
-
Nginx:
-
高性能 HTTP 服务器、反向代理
-
支持 IMAP、POP3、SMTP
-
可用于网站发布、负载均衡
-
-
代理类型:
-
正向代理:代理客户端(客户端知道目标)
-
反向代理:代理服务器(客户端不知道后端服务器细节)
-
2️⃣ Nginx 安装
Ubuntu:
apt install nginx -y
CentOS:
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum install -y nginx
3️⃣ 启动 Nginx
- 查看是否启动:
ps -ef | grep nginx
- 手动启动:
nginx
nginx -v # 查看版本
- 停止 Nginx(杀掉 master 进程):
kill <master_pid>
4️⃣ 配置首页
- 默认目录(Ubuntu 可能需要修改):
/etc/nginx/sites-available/default
- 默认页面目录(CentOS 默认即可):
/usr/share/nginx/html
- 示例 index.html:
<h1>Welcome to nginx!</h1>
5️⃣ Docker 操作 Nginx
- 查找镜像:
docker search nginx
- 拉取镜像:
docker pull nginx:1.23.3
- 查看本地镜像:
docker images
- 运行镜像:
docker run --name nginx1 --rm -it -p 80:80 nginx:1.23.3 bash
- 启动容器内的 Nginx:
nginx
- 访问 Nginx 页面:
curl 127.0.0.1
- 注意:退出容器 shell 后,再
curl 127.0.0.1可能无法访问,因为服务在容器内部。
6️⃣ 其他拉取方式
- 拉取组织或用户定制镜像:
docker pull bitnami/nginx:1.23.4
- 通过 digest 拉取镜像:
docker pull nginx@sha256:<digest>
- 查看镜像 ID:
docker image inspect <IMAGE_ID>
实战二:Docker Hub 上创建私有仓库
1️⃣ 安装 BusyBox(示例基础镜像)
- Ubuntu:
apt install -y busybox
- CentOS:
wget https://busybox.net/downloads/binaries/1.28.1-defconfig-multiarch/busybox-x86_64 --no-check-certificate
mv busybox-x86_64 busybox
chmod +x busybox
./busybox
- 常用命令:
busybox ls
busybox ifconfig
busybox ifconfig | busybox grep lo
- 卸载 BusyBox(不使用时):
apt --purge autoremove busybox
2️⃣ 创建 Docker Hub 仓库
-
创建仓库,激活邮箱
-
查看仓库信息
3️⃣ 推送镜像到仓库
- 拉取 BusyBox 镜像:
docker pull busybox
- 给镜像打标签:
docker tag busybox:latest <dockerhub_username>/mybusybox:v0.1
- 登录 Docker Hub:
docker login -u <username>
- 推送镜像:
docker push <dockerhub_username>/mybusybox:v0.1
-
查看 Docker Hub 仓库,确认上传成功
-
登出:
docker logout
实战三:腾讯云私有仓库
-
注册腾讯云账号并登录容器镜像服务
-
创建个人私有仓库
-
登录:
docker login ccr.ccs.tencentyun.com --username=<腾讯云用户ID>
- 打标签 & 推送:
docker tag busybox:latest ccr.ccs.tencentyun.com/<namespace>/mybusybox:v0.2
docker push ccr.ccs.tencentyun.com/<namespace>/mybusybox:v0.2
-
查看仓库确认上传成功
-
登出:
docker logout ccr.ccs.tencentyun.com
实战四:阿里云私有仓库
-
注册阿里云账号
-
创建容器镜像服务实例 & 设置登录密码
-
创建镜像仓库(命名空间)
-
登录:
docker login --username=<阿里云账号> registry.cn-hangzhou.aliyuncs.com
- 打标签 & 推送:
docker tag busybox:latest registry.cn-hangzhou.aliyuncs.com/<namespace>/busybox:v0.3
docker push registry.cn-hangzhou.aliyuncs.com/<namespace>/busybox:v0.3
-
查看仓库确认上传成功
-
登出:
docker logout registry.cn-hangzhou.aliyuncs.com
实战经验
-
基础镜像选择:
-
大公司通常有内部镜像(如欧拉、TLinux等)
-
基础镜像经过安全扫描
-
个人项目一般使用官方镜像或公司内部推荐镜像即可
-
Docker Image(镜像)
1️⃣ 镜像概念
-
Docker 镜像(Image)本质:
-
只读文件(read-only),包含文件系统、源码、库文件、依赖、工具等应用运行所需的所有内容。
-
可以理解为一个模板,通过模板可以实例化出多个容器。
-
内部是 分层文件系统(Union FS):每一层叫 layer。
-
-
镜像层(Layer)特点:
-
每层都是只读的。
-
构建镜像时,每个操作都会新增一层。
-
上层覆盖下层的内容,用户看到的是整体效果。
-
联合文件系统减少存储占用,可共享基础层。
-
-
生活案例:
-
镜像像 Java/C++ 的类,容器像对象。
-
分层像房子地板:基础钢筋、水泥、保温、采暖管 → 最上层地板砖或木地板。
-
2️⃣ 为什么需要镜像
-
解决 本地和云端环境一致性问题。
-
部署应用不再依赖繁琐手工配置。
-
镜像就是一个压缩包,打包操作系统和应用,保证跨环境一致性。
-
Docker 的最大贡献:定义了容器镜像分层存储格式,基于 UnionFS。
3️⃣ 镜像命令概览
| 命令 | 别名 | 功能 | 备注 |
|---|---|---|---|
| docker images | docker image ls/list | 列出本地镜像 | 必须掌握 |
| docker tag | docker image tag | 给镜像打标签 | 必须掌握 |
| docker pull | docker image pull | 拉取镜像 | 必须掌握 |
| docker push | docker image push | 推送镜像 | 必须掌握 |
| docker rmi | docker image rm/remove | 删除本地镜像 | 必须掌握 |
| docker build | docker image build | 通过 Dockerfile 制作镜像 | 必须掌握 |
| docker save | docker image save | 保存镜像成 tar 文件 | 必须掌握 |
| docker load | docker image load | 导入 tar 文件镜像 | 必须掌握 |
| docker image inspect | - | 查看镜像详细信息 | 必须掌握 |
| docker history | docker image history | 查看镜像历史 | - |
| docker import | docker image import | 从归档文件创建镜像 | - |
| docker image prune | - | 删除不使用的镜像 | - |
4️⃣ 常用镜像命令详解
docker images
docker images [OPTIONS] [REPOSITORY[:TAG]]
-
别名:
docker image ls/list -
参数:
-
-a:列出所有镜像(含中间层) -
--digests:显示镜像摘要 -
-f:条件过滤 -
--format:输出模板 -
--no-trunc:显示完整信息 -
-q:只显示镜像 ID
-
-
示例:
docker images
docker images ubuntu
docker tag
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
-
别名:
docker image tag -
示例:
docker tag ubuntu:22.04 myregistry.com/myubuntu:22.04
docker rmi
docker rmi [OPTIONS] IMAGE [IMAGE...]
-
别名:
docker image rm/remove -
参数:
-
-f:强制删除 -
--no-prune:不删除中间镜像
-
-
示例:
docker rmi maxhou/mybusybox:v0.1
docker save / load
- 保存镜像:
docker save -o mynginx_1.22.1.tar nginx:1.22.1
- 导入镜像:
docker load -i mynginx_1.22.1.tar
docker image inspect
- 查看镜像详细信息:
docker image inspect nginx:1.23.3
- 自动区分镜像或容器。
docker history
- 查看镜像历史:
docker history nginx:1.21.1
-
参数:
-
-H:人类可读格式 -
--no-trunc:完整显示 -
-q:只显示镜像 ID
-
docker import
- 从归档文件创建镜像:
docker import my_ubuntu_v3.tar maxhou/ubuntu:v4
-
参数:
-
-c:运行 Docker 指令创建镜像 -
-m:提交说明文字
-
docker image prune
- 删除未使用的镜像:
docker image prune
docker image prune -a # 删除所有未使用镜像
docker build
- 通过 Dockerfile 创建镜像:
docker build -t mynginx:v1 .
-
参数:
-
--build-arg:构建时变量 -
-f:Dockerfile 路径 -
--label:设置镜像元数据 -
--no-cache:不使用缓存 -
--pull:更新基础镜像 -
-q:只输出镜像 ID -
-t:镜像名:标签 -
--network:构建时网络模式
-
1️⃣ 查找镜像
命令:
docker search busybox
作用:
-
在 Docker Hub 或指定仓库里搜索镜像。
-
返回镜像名字、描述、官方标识(Official)、自动化构建(Automated)、点赞数(Stars)等信息。
-
帮助你选择合适的基础镜像。
2️⃣ 下载镜像(Pull)
命令:
docker pull busybox:1.36.0
作用:
-
从远程仓库拉取镜像到本地。
-
拉取过程是 分层下载:镜像每一层(layer)都会单独下载,重复使用的层不会重复下载,节省网络和存储。
示例输出:
1.36.0: Pulling from library/busybox
Digest: sha256:...
Status: Image is up to date
Digest是镜像的 SHA256 摘要,用于保证完整性。
3️⃣ 查看镜像列表和存储位置
命令:
docker images busybox
-
列出本地已下载的镜像,包括镜像 ID、标签(Tag)、创建时间、大小。
-
本地存储位置默认是
/var/lib/docker(你的例子中修改为/data/var/lib/docker)。 -
repositories.json文件记录了镜像名称、标签和对应的 SHA256 ID。
过滤镜像示例:
docker image ls -f before=ubuntu:18.04
docker image ls -f since=ubuntu:18.04
- 可以列出在指定镜像之前或之后创建的镜像,便于管理历史镜像。
4️⃣ 查看镜像详情和分层
命令:
docker image inspect busybox:1.36.0
docker history busybox:1.36.0
作用:
-
inspect查看镜像详细信息,包括:-
镜像 ID
-
标签(Tag)
-
大小
-
创建时间
-
图形驱动(GraphDriver)和存储层(Overlay2)路径
-
镜像层信息(RootFS)
-
-
history查看镜像的分层结构,每一条命令对应一层文件系统。
5️⃣ 镜像打标签(Tag)
命令:
docker tag busybox:1.36.0 ccr.ccs.tencentyun.com/maxhou6/busyboxbymaxhou:v3.0
作用:
-
给镜像加上新的名字/标签,方便推送到仓库或区分版本。
-
镜像本身不复制,只是加了引用标签。
6️⃣ 推送镜像(Push)
命令:
docker push ccr.ccs.tencentyun.com/maxhou6/busyboxbymaxhou:v3.0
作用:
-
将本地镜像上传到远程仓库,方便共享或部署。
-
只上传新层,已有层会被跳过。
7️⃣ 运行容器(Run)
命令:
docker run -it --rm ccr.ccs.tencentyun.com/maxhou6/busyboxbymaxhou:v3.0 sh
参数说明:
-
-it:交互式终端 -
--rm:容器退出后自动删除 -
sh:容器内启动 shell
作用:
-
实例化镜像为一个容器,容器在上层创建可写层。
-
运行时可以查看网络接口(ifconfig)、主机名(hostname)等环境信息。
8️⃣ 删除镜像(RMI)
命令:
docker rmi busybox:1.36.0
注意事项:
-
删除镜像前必须确保没有容器在使用该镜像。
-
可以使用
-f强制删除未使用的镜像。
✅ 总结流程
| 步骤 | 命令 | 作用 |
|---|---|---|
| 查找镜像 | docker search <name> |
找合适的基础镜像 |
| 下载镜像 | docker pull <name:tag> |
拉取到本地,分层下载 |
| 查看镜像 | docker images / docker image inspect |
查看列表、详细信息、分层 |
| 打标签 | docker tag <src> <target> |
便于版本管理和推送 |
| 推送镜像 | docker push <target> |
上传到远程仓库 |
| 运行容器 | docker run ... |
实例化镜像,创建容器 |
| 删除镜像 | docker rmi <name> |
清理本地镜像 |
一、实战一:离线迁移镜像
这个场景在企业里非常常见,例如:
-
服务器 不能访问外网
-
内网部署 Kubernetes
-
生产环境禁止联网
这时候就需要 离线镜像迁移。
1️⃣ 在服务器1导出镜像
命令:
docker save -o busybox.tar busybox
作用:
-
将 Docker 镜像 导出为 tar 文件
-
方便拷贝到其他机器
生成文件:
busybox.tar
示例:
-rw------- busybox.tar 5MB
如果是 nginx:
docker save -o nginx.tar nginx:1.22.1
2️⃣ 复制到另一台服务器
使用 scp 复制:
scp busybox.tar root@43.138.218.166:/data/maxhou
含义:
scp 本地文件 远程服务器:目录
执行流程:
服务器A ---> busybox.tar ---> 服务器B
3️⃣ 在服务器2导入镜像
命令:
docker load -i busybox.tar
输出:
Loading layer
Loaded image: busybox:1.36.0
意思是:
Docker 会从 tar 文件中恢复:
-
镜像
-
镜像层
-
标签
4️⃣ 查看镜像
docker images
可以看到:
busybox 1.36.0 7cfbbec8963d 4.86MB
说明导入成功。
5️⃣ 运行镜像测试
docker run -it --rm busybox:1.36.0 sh
进入容器:
/ #
查看文件系统:
ls /
输出:
bin dev etc home lib lib64 proc root sys tmp usr var
说明:
镜像运行正常。
二、实战二:镜像压缩与共享机制
这是 Docker 最核心的技术之一。
Docker 镜像其实是:
分层压缩存储
1️⃣ 拉取 nginx 镜像
docker pull nginx:1.21.1
输出:
Pulling from library/nginx
说明:
从 Docker Hub 下载。
2️⃣ 查看镜像
docker images
输出:
nginx 1.21.1 133MB
3️⃣ 为什么 Docker Hub 只有 50MB?
这是很多人疑惑的问题:
Docker Hub 显示:
Compressed size
≈ 50MB
本地:
Uncompressed size
≈ 130MB
原因:
Docker 在网络传输时 压缩层。
流程:
仓库
(压缩层 tar.gz)
↓
网络传输
↓
本地
(解压成 layer)
所以:
| 位置 | 大小 |
|---|---|
| Docker Hub | 压缩大小 |
| 本地 | 解压后大小 |
4️⃣ 一个镜像打多个 tag
命令:
docker tag nginx:1.22.1 maxhou/mybitnginx:1.22.1
docker tag nginx:1.22.1 maxhou/mybitnginx:1.22.2
docker tag nginx:1.22.1 maxhou/mybitnginx:1.22.3
docker tag nginx:1.22.1 maxhou/mybitnginx:1.22.4
本质:
多个标签指向同一个镜像 ID
例如:
nginx:1.22.1
maxhou/mybitnginx:1.22.1
maxhou/mybitnginx:1.22.2
其实都是:
8c9eabeac475
所以:
不会复制镜像。
5️⃣ 推送镜像
命令:
docker push maxhou/mybitnginx -a
参数:
-a = push all tags
输出:
Layer already exists
说明:
这些层 已经存在仓库里。
Docker 不会重复上传。
6️⃣ 镜像层共享原理
例如:
nginx:1.22.1
nginx:1.23.3
它们的层结构:
Layer1 linux
Layer2 nginx base
Layer3 config
Layer4 version difference
其中:
Layer1
Layer2
Layer3
是共享的。
只有:
Layer4
不同。
所以:
Docker 非常省空间。
7️⃣ Mounted from library/nginx
推送时看到:
Mounted from library/nginx
意思是:
Docker Hub 发现:
这个 layer 已经存在官方 nginx 仓库
于是:
直接 引用(mount),不会重新上传。
好处:
上传速度更快
节省存储
三、两个实战的核心总结
1️⃣ 离线迁移
核心命令:
docker save
scp
docker load
流程:
服务器A
↓ docker save
image.tar
↓ scp
服务器B
↓ docker load
镜像恢复
2️⃣ 镜像压缩共享
Docker 的三大优化:
1️⃣ 分层存储
layer1
layer2
layer3
2️⃣ 网络压缩
仓库 50MB
本地 130MB
3️⃣ 层共享
多个镜像共享 layer
最重要的一句话(Docker 镜像核心)
Docker 镜像本质:
分层文件系统 + 压缩传输 + 层共享
所以 Docker 才会:
-
快
-
省空间
-
易迁移
Docker 容器(Container)整理笔记
1️⃣ 容器概念
-
容器是 镜像的运行实体。
-
镜像是静态只读文件,而容器有 可写层,运行着实际的应用进程。
-
每个容器独立存在,支持 命名空间隔离和资源限制。
-
一个镜像可以实例化出多个容器,每个容器内部内容可不同。
容器类比
-
镜像 = 类(Java/C++ 类)
-
容器 = 对象(类的实例化)
-
镜像是毛坯房,容器是每家人装修后的房子
2️⃣ 为什么需要容器
-
镜像本身不能提供服务,需要容器运行后才能对外服务。
-
容器带来好处:
-
隔离应用环境
-
资源限制(CPU、内存等)
-
便于快速部署和迁移
-
3️⃣ 容器生命周期
| 状态 | 描述 | 常用命令 |
|---|---|---|
| created | 初建状态 | docker create |
| running | 运行状态 | docker run / docker start |
| stopped | 停止状态 | docker stop |
| paused | 暂停状态(冻结 CPU,但保留内存、网络) | docker pause / docker unpause |
| deleted | 删除状态 | docker rm |
生命周期转换命令
-
docker create→ 创建容器,不启动 -
docker run→ 创建并启动容器 -
docker start→ 已停止容器重新运行 -
docker stop→ 停止运行中的容器 -
docker restart→ 重启容器 -
docker pause/docker unpause→ 暂停 / 恢复容器 -
docker kill→ 强制停止(类似断电,容易丢数据)
4️⃣ 容器异常情况
4.1 容器 OOM(Out-of-Memory)
-
容器超出分配内存上限会触发 OOM,由宿主机内核终止容器。
-
处理方法:
-
设置
--oom-kill-disable禁用 OOM Killer -
配合
-m设置内存上限,避免占用过多主机资源
-
4.2 容器异常退出
-
容器内部有一个 Init 进程,所有子进程都依赖它。
-
Init 退出 → 容器退出
-
Docker 不区分正常/异常退出
-
设置
--restart参数 → 容器可自动重启
4.3 容器暂停
-
暂停容器仅冻结 CPU 使用,其他资源保持
-
容器处于"冰封"状态
5️⃣ 常用容器命令整理
| 命令 | 别名 | 功能 | 备注 |
|---|---|---|---|
docker create |
docker container create |
创建容器 | --- |
docker run |
docker container run |
运行容器 | 必须掌握 |
docker start |
docker container start |
启动容器 | 必须掌握 |
docker stop |
docker container stop |
停止容器 | 必须掌握 |
docker restart |
docker container restart |
重启容器 | 必须掌握 |
docker rm |
docker container rm |
删除容器 | 必须掌握 |
docker exec |
docker container exec |
在容器中执行命令 | 必须掌握 |
docker attach |
docker container attach |
连接运行中容器 | --- |
docker commit |
docker container commit |
将容器保存为镜像 | 必须掌握 |
docker cp |
docker container cp |
容器与宿主机文件拷贝 | 必须掌握 |
docker diff |
docker container diff |
查看容器文件变动 | --- |
docker logs |
docker container logs |
查看日志 | 必须掌握 |
docker pause/unpause |
docker container pause/unpause |
暂停/恢复容器 | --- |
docker stats |
docker container stats |
查看资源占用 | 必须掌握 |
docker top |
docker container top |
查看容器进程 | 必须掌握 |
docker port |
docker container port |
查看端口映射 | --- |
docker inspect |
docker container inspect |
查看容器详情 | 必须掌握 |
docker rename |
docker container rename |
重命名容器 | --- |
docker update |
docker container update |
更新容器配置 | --- |
docker wait |
docker container wait |
阻塞直到容器停止并打印退出码 | --- |
docker prune |
docker container prune |
删除所有停止的容器 | --- |
Docker 容器命令详解(完整版)
1️⃣ docker create
-
功能:创建容器但不启动它
-
语法:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
-
别名 :
docker container create -
关键参数:
-
-i:交互模式 -
-t:分配伪终端 -
-P:随机端口映射 -
-p:指定端口映射host:container -
--name:指定容器名 -
-h:设置容器 hostname -
-e:设置环境变量 -
--cpuset-cpus:绑定 CPU -
-m:内存限制 -
--network:指定网络类型 -
--link:连接其他容器 -
-v / --volume:挂载卷 -
--rm:退出时自动删除 -
--restart:自动重启
-
-
示例:
docker create --name mynginx nginx:latest
2️⃣ docker run
-
功能:创建并启动容器
-
语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-
别名 :
docker container run -
关键参数 :同
docker create,额外:-d:后台运行
-
示例:
docker run --name mynginx -d nginx:latest
docker run -p 80:80 -v /data:/data -d nginx:latest
3️⃣ docker ps
-
功能:列出容器
-
别名 :
docker container ls/docker container list -
关键参数:
-
-a:显示所有容器 -
-f:条件过滤 -
--format:自定义输出 -
-l:最近一个容器 -
-n:最近 n 个容器 -
-q:仅显示 ID -
-s:显示文件大小
-
-
示例:
docker ps -a
4️⃣ docker logs
-
功能:查看容器日志
-
别名 :
docker container logs -
关键参数:
-
-f:跟踪日志 -
--since:指定开始时间 -
-t:显示时间戳 -
-n:显示最近 N 条
-
-
示例:
docker logs -f mynginx
docker logs --since="2016-07-01" --tail=10 mynginx
5️⃣ docker attach
-
功能:连接运行中的容器
-
别名 :
docker container attach -
关键参数:
--sig-proxy=false:退出时不杀死容器
-
示例:
docker attach --sig-proxy=false mynginx
6️⃣ docker exec
-
功能:在容器中执行命令
-
别名 :
docker container exec -
关键参数:
-
-d:后台运行 -
-i:保持 STDIN 打开 -
-t:分配终端 -
-e:环境变量 -
-u:指定用户 -
-w:工作目录
-
-
示例:
docker exec -it mynginx bash
docker exec -it mynginx echo "Hello bit"
7️⃣ docker start / stop / restart / kill
| 命令 | 功能 | 备注 |
|---|---|---|
start |
启动停止容器 | docker container start mynginx |
stop |
停止运行容器 | 发送 SIGTERM |
restart |
重启容器 | docker container restart mynginx |
kill |
强制退出容器 | 发送 SIGKILL |
8️⃣ docker top
-
功能:查看容器内运行的进程
-
别名 :
docker container top -
示例:
docker top mynginx
9️⃣ docker stats
-
功能:显示容器资源使用情况(CPU、内存、网络 I/O)
-
别名 :
docker container stats -
关键参数:
-
-a:显示所有容器 -
--format:自定义输出格式 -
--no-stream:显示当前状态后退出
-
-
示例:
docker stats
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
🔟 docker inspect
-
功能:查看容器详细信息
-
别名 :
docker container inspect -
关键参数:
-
-f:自定义模板(table/json) -
-s:显示总大小
-
-
示例:
docker container inspect mynginx
1️⃣1️⃣ docker port
-
功能:查看容器端口映射
-
别名 :
docker container port -
示例:
docker port mynginx
1️⃣2️⃣ docker cp
-
功能:容器与宿主机文件拷贝
-
别名 :
docker container cp -
示例:
docker cp /www/ mynginx:/www/
docker cp mynginx:/www/ /wwwbak/
1️⃣3️⃣ docker diff
-
功能:查看容器文件变化
-
示例:
docker diff mynginx
1️⃣4️⃣ docker commit
-
功能:从容器创建新镜像
-
关键参数:
-
-a:作者 -
-m:提交说明 -
-c:Dockerfile 指令 -
-p:提交时暂停容器
-
-
示例:
docker commit c3f279d17e0a maxhou/mynginx:v01
1️⃣5️⃣ docker pause / unpause
-
功能:暂停或恢复容器进程
-
别名 :
docker container pause/unpause -
示例:
docker pause mynginx
docker unpause mynginx
1️⃣6️⃣ docker rm / container prune
-
功能:删除容器
-
关键参数:
-f:强制删除运行容器
-
示例:
docker stop mynginx
docker rm mynginx
docker rm $(docker ps -a -q)
docker container prune -f
1️⃣7️⃣ docker export
-
功能:导出容器为 tar 文件
-
别名 :
docker container export -
示例:
docker export -o mynginx202203.tar mynginx
1️⃣8️⃣ docker wait
-
功能:阻塞直到容器停止,打印退出码
-
别名 :
docker container wait -
示例:
docker wait mynginx
1️⃣9️⃣ docker rename
-
功能:重命名容器
-
别名 :
docker container rename -
示例:
docker rename mynginx myweb
2️⃣0️⃣ docker update
-
功能:更新容器资源配置
-
别名 :
docker container update -
关键参数:
-
--cpus:CPU 数量 -
--cpuset-cpus:绑定 CPU -
--memory:内存限制 -
--memory-swap:交换内存 -
--cpu-period/--cpu-quota:CPU 调度限制
-
-
示例:
docker update -m 400m myweb
🚀 一、核心理解(一定要搞懂)
在 Docker 里,容器操作本质就三类:
✅ 1. 生命周期管理(最重要)
create → start → stop → rm
但实际开发中 90% 用 run 代替 create+start
👉 所以核心链路是:
docker run → docker ps → docker stop → docker rm
🔥 二、最常用命令(必须会背)
1️⃣ 启动容器(最核心)
docker run -d -p 80:80 --name mynginx nginx
👉 含义拆解:
| 参数 | 作用 |
|---|---|
-d |
后台运行(推荐) |
-p |
端口映射 |
--name |
起名字 |
nginx |
镜像 |
📌 面试常问:
run 和 create 区别?
👉 答:
-
create:只创建
-
run:创建 + 启动(常用)
2️⃣ 查看容器
docker ps # 运行中的
docker ps -a # 所有
3️⃣ 停止 / 删除
docker stop mynginx
docker rm mynginx
📌 强制删除:
docker rm -f mynginx
4️⃣ 进入容器(高频!)
docker exec -it mynginx bash
👉 面试点:
| 命令 | 区别 |
|---|---|
| exec | 开新终端(推荐) |
| attach | 连接主进程(危险,会关容器) |
5️⃣ 查看日志
docker logs -f mynginx
👉 实时日志(排错必用)
6️⃣ 查看 IP(你刚问的)
docker inspect mynginx
找:
"IPAddress": "172.17.0.2"
或更高级写法:
docker inspect -f '{{.NetworkSettings.IPAddress}}' mynginx
🧠 三、运行模式(重点理解)
1️⃣ 前台模式(attached)
docker run nginx
特点:
-
日志直接打印
-
Ctrl+C = 容器停止 ❌
👉 ❗只用于调试
2️⃣ 后台模式(detached)⭐推荐
docker run -d nginx
特点:
-
后台运行
-
更安全稳定
3️⃣ 交互模式
docker run -it ubuntu bash
👉 进入容器"操作系统"
⚡ 四、超实用技巧(面试加分)
1️⃣ 批量删除容器
docker rm $(docker ps -aq)
2️⃣ 删除已停止容器
docker rm $(docker ps -q --filter status=exited)
3️⃣ 自动删除容器
docker run --rm nginx
👉 用完自动清理(非常实用)
4️⃣ 自动重启
docker run -d --restart=always nginx
👉 服务器必备
5️⃣ 文件拷贝
docker cp 本地路径 容器:路径
docker cp 容器:路径 本地路径
🔍 五、容器状态(必须会看)
| 状态 | 含义 |
|---|---|
| Created | 已创建 |
| Up | 运行中 |
| Exited | 已停止 |
| Paused | 已暂停 |
🎯 六、最重要的一句话总结
👉 Docker 容器操作 = 启动 + 查看 + 进入 + 停止 + 删除
核心命令就这几个:
run / ps / exec / logs / stop / rm
🚀 一、整体思路(必须先理解)
在 Docker 中做这三类实战,本质是:
✅ 三种典型场景
| 场景 | 本质 |
|---|---|
| MySQL | 运行现成服务(数据库) |
| Redis | 运行缓存服务 |
| C++容器 | 自己构建开发环境 |
👉 一句话总结:
Docker = 运行服务 + 搭环境 + 封装环境
🐬 二、MySQL 容器(重点:参数)
⭐ 核心命令
docker run --name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-p 3306:3306 \
-d mysql:5.7
🔥 必须理解的点
1️⃣ 为什么必须设置密码?
-e MYSQL_ROOT_PASSWORD=123456
👉 因为 MySQL 官方镜像强制要求
否则容器直接启动失败 ❌
2️⃣ 端口映射
-p 3306:3306
👉 含义:
| 主机 | 容器 |
|---|---|
| 3306 | 3306 |
你访问:
localhost:3306
其实是在访问:
容器:3306
3️⃣ 为什么可以远程连接?
因为:
-p 8200:3306
👉 本质:
宿主机8200 → 容器3306
4️⃣ 登录流程(你做的这一步)
docker exec -it mysql bash
mysql -p
👉 实际流程:
进入容器 → 启动客户端 → 连接数据库
⚠️ 实战最大坑(很重要)
👉 你的数据会丢!
因为你没挂载数据卷 ❌
✅ 正确写法(生产级)
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /mydata/mysql:/var/lib/mysql \
mysql:5.7
👉 这样数据才会保存到宿主机
⚡ 三、Redis 容器(简单但高频)
⭐ 核心命令
docker run -d --name redis -p 6379:6379 redis:7.0
🔥 关键理解
Redis 是什么?
Redis:
👉 内存数据库(超级快)
操作流程
docker exec -it redis bash
redis-cli
set key 1
get key
⚠️ 同样的问题
👉 数据也会丢!
✅ 正确写法
docker run -d \
--name redis \
-p 6379:6379 \
-v /mydata/redis:/data \
redis:7.0
🧠 四、C++ 容器(理解最重要)
这是最有价值的部分🔥
🧩 本质在做什么?
👉 你在做:
用 Docker 造一台"干净的 Linux 开发机"
⭐ 核心流程
1️⃣ 启动系统
docker run -it ubuntu:22.04 bash
👉 得到一个:
Ubuntu 系统
2️⃣ 配软件源
sed -i 's@archive.ubuntu.com@mirrors.ustc.edu.cn@g' /etc/apt/sources.list
👉 本质:
- 国外源 → 国内镜像(更快)
3️⃣ 安装开发环境
apt update
apt install gcc vim -y
4️⃣ 写代码 + 编译
#include <stdio.h>
int main(){
printf("hello docker!\n");
}
gcc demo.c -o demo
./demo
🔥 这一部分的核心意义
👉 你已经学会:
| 能力 | 含义 |
|---|---|
| 环境隔离 | 每个容器都是独立系统 |
| 环境复现 | 别人一键跑你的环境 |
| 无污染开发 | 不影响宿主机 |
🚀 一、这一节在干嘛?(核心理解)
在 Docker 里:
👉 默认情况下:
容器 = 可以吃光你整台机器的 CPU 和内存 ❗
所以必须做:
✅ 资源限制(CPU / 内存)
🔍 二、查看资源(先学会"看")
1️⃣ 查看进程
docker top mynginx5 aux
👉 本质:
看容器里跑了哪些进程(类似 ps aux)
2️⃣ 实时资源监控(非常重要🔥)
docker stats
👉 输出:
| 指标 | 含义 |
|---|---|
| CPU % | CPU 使用率 |
| MEM USAGE | 当前内存 |
| LIMIT | 最大内存 |
| NET I/O | 网络 |
| BLOCK I/O | 磁盘 |
| PIDS | 进程数 |
🧠 三、限制内存(重点)
✅ 命令
docker update -m 300m --memory-swap 600m mynginx5
🔥 参数解释(面试高频)
| 参数 | 含义 |
|---|---|
-m 300m |
最大内存 300MB |
--memory-swap 600m |
内存 + swap 总共 600MB |
⚠️ 关键理解
真实可用 = 内存 + swap
👉 如果写:
-m 300m --memory-swap 300m
👉 表示 ❌ 完全禁止 swap
⚡ 四、打满 CPU(你这段很经典)
for i in `seq 1 $(cat /proc/cpuinfo |grep "physical id" |wc -l)`
do
dd if=/dev/zero of=/dev/null &
done
🔍 本质在干嘛?
👉 这句:
dd if=/dev/zero of=/dev/null
含义:
疯狂读数据 + 丢弃 → 纯 CPU 消耗
👉 多进程跑 → 吃满所有 CPU
🔥 五、限制 CPU(重点)
✅ 命令
docker update --cpu-period=100000 --cpu-quota=10000 mynginx5
🧠 关键公式(必须懂)
CPU使用率 = quota / period
📌 你的例子
10000 / 100000 = 0.1 = 10%
👉 所以 CPU 被限制到 10%
✅ 更简单写法(推荐记这个)
docker update --cpus="0.5" mynginx5
👉 表示:
最多使用 0.5 个 CPU
🚨 六、面试常考点总结
❓ Docker 如何限制资源?
👉 答:
-
内存:-m
-
CPU:--cpus 或 quota/period
❓ 为什么要限制?
👉 答:
防止单个容器拖垮整个服务器
❓ 如何查看资源?
👉 答:
docker stats
🎯 七、最佳实践(非常重要🔥)
✅ 启动时就限制(推荐)
docker run -d \
--name mynginx \
-p 80:80 \
-m 300m \
--cpus="0.5" \
nginx
👉 比 docker update 更规范
🧠 八、一句话总结
docker stats 看资源
docker update 改资源
-m 控内存
--cpus 控CPU
一、docker create / start / run 区别
1️⃣ docker create
👉 只创建容器,不运行
docker create nginx
-
容器存在,但是 Stopped 状态
-
类似"创建但不开机"
2️⃣ docker start
👉 启动已经存在的容器
docker start 容器名
-
只能启动 已有容器
-
常配合
create使用
3️⃣ docker run
👉 创建 + 启动(最常用)
docker run -d nginx
本质相当于:
docker create nginx
docker start 容器
✔ 如果本地没有镜像 → 会自动拉取(pull)
✅ 总结一句话:
| 命令 | 功能 |
|---|---|
| create | 创建容器 |
| start | 启动容器 |
| run | 创建 + 启动(常用) |
二、docker load / import 区别(重点🔥)
先理解两个"导出"命令:
🔹 docker save
👉 导出的是 镜像
docker save nginx > nginx.tar
特点:
-
✅ 保留完整历史(layers)
-
✅ 包含元数据
-
❌ 文件较大
🔹 docker export
👉 导出的是 容器快照
docker export 容器ID > container.tar
特点:
-
❌ 不保留历史
-
❌ 丢失元数据
-
✅ 只保留当前状态(类似快照)
🔻 对应导入命令:
1️⃣ docker load
👉 用于导入 save 导出的镜像
docker load < nginx.tar
✔ 恢复完整镜像(推荐)
2️⃣ docker import
👉 用于导入 export 的容器文件
docker import container.tar new_image
✔ 生成新镜像
❌ 没有历史记录(像"压平"的镜像)
✅ 总结对比:
| 命令 | 来源 | 是否保留历史 | 用途 |
|---|---|---|---|
| load | save | ✅ 保留 | 镜像迁移 |
| import | export | ❌ 不保留 | 快照恢复 |
三、docker rm / rmi / prune 区别
1️⃣ docker rm
👉 删除容器
docker rm 容器名
2️⃣ docker rmi
👉 删除镜像
docker rmi nginx
3️⃣ docker prune
👉 清理"垃圾"
docker system prune
会删除:
-
停止的容器
-
未使用的网络
-
悬空镜像(dangling images)
✅ 总结:
| 命令 | 删除对象 |
|---|---|
| rm | 容器 |
| rmi | 镜像 |
| prune | 无用资源(清理) |
🚀 一句话速记(很重要)
👉 面试可以这样说:
-
run = create + start -
load保历史,import不保历史 -
rm删容器,rmi删镜像,prune清垃圾
🚀 Docker Volume(存储卷)总结
一、什么是存储卷(核心一句话)
👉 把宿主机目录 ↔ 容器目录 绑定起来,实现数据共享与持久化
📌 特点:
-
容器写数据 = 写到宿主机
-
宿主机改数据 = 容器同步看到
-
绕过容器文件系统(UnionFS)
二、为什么需要存储卷(4大原因🔥)
1️⃣ 数据持久化(最重要)
-
容器删除 → 数据也没了 ❌
-
使用 Volume → 数据还在 ✅
👉 典型场景:
-
MySQL
-
Redis
-
Kafka
2️⃣ 性能更好
-
容器默认文件系统(UnionFS)性能较差
-
Volume 直接操作宿主机磁盘 → 更快
3️⃣ 宿主机与容器交互方便
-
不用再用
docker cp -
直接共享目录
4️⃣ 容器之间共享数据
- 多个容器可以挂同一个 Volume
三、三种存储卷类型(重点🔥)
1️⃣ volume(匿名卷 / 管理卷)
docker run -v /container/path nginx
📌 特点:
-
由 Docker 自动管理
-
存在路径:
/var/lib/docker/volumes/ -
❌ 用户不可控路径
-
✅ 使用简单
👉 适合:临时数据
2️⃣ bind mount(绑定挂载 ⭐常用)
docker run -v /宿主机路径:/容器路径 nginx
📌 特点:
-
路径自己指定
-
宿主机和容器完全同步
-
✅ 灵活、可控
👉 最常用方式🔥
3️⃣ tmpfs mount(内存卷)
docker run --tmpfs /container/path nginx
📌 特点:
-
存在内存中
-
容器停止 → 数据消失
-
⚡ 性能最高
👉 适合:缓存 / 临时数据
四、对比总结(必背表格)
| 类型 | 存储位置 | 是否持久化 | 特点 |
|---|---|---|---|
| volume | Docker管理目录 | ✅ | 简单但不可控 |
| bind mount | 宿主机指定目录 | ✅ | ⭐最常用 |
| tmpfs | 内存 | ❌ | ⚡最快 |
📝 Docker Volume 管理卷速查
一、Volume 基本概念
-
Volume 是宿主机目录与容器目录的绑定,实现数据持久化与共享。
-
类型:
-
volume :Docker 管理卷,宿主机默认
/var/lib/docker/volumes。 -
bind mount:绑定宿主机指定路径。
-
tmpfs:临时内存卷,容器停止即丢失。
-
二、Volume 管理命令
| 命令 | 别名 | 功能 | 备注 |
|---|---|---|---|
docker volume create [VOLUME] |
- | 创建卷 | -d 指定驱动,--label 设置元数据 |
docker volume inspect [VOLUME] |
- | 查看卷详情 | -f 指定输出格式 |
docker volume ls |
docker volume list |
列出卷 | -q 只显示名字,--filter 过滤 |
docker volume rm [VOLUME] |
- | 删除卷 | -f 强制删除,卷被容器使用无法删除 |
docker volume prune |
- | 清理未使用卷 | -f 强制删除,--filter 过滤 |
三、创建卷方式
1️⃣ 命令行创建
docker volume create my-vol
docker volume inspect my-vol
docker volume ls
docker volume rm my-vol
docker volume prune
2️⃣ 创建容器时挂载
-v 参数
docker run -d --name devtest -v myvol2:/app nginx:latest
查看挂载
docker inspect devtest
-
语法:
-v 卷名:容器目录[:ro] -
ro:只读
--mount 参数
docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
docker inspect devtest
-
type:
volume、bind或tmpfs -
source/src:卷名
-
target/destination/dst:容器目录
-
ro/readonly:只读
3️⃣ Dockerfile 匿名卷
-
使用
VOLUME /app在镜像中创建挂载点 -
无法指定宿主机路径,Docker 自动生成
四、操作案例
1️⃣ 命令创建管理卷
docker volume create test_volume
docker container run --name nginx1 -d -p 80:80 -v test_volume:/usr/share/nginx/html nginx:1.22.1
docker inspect nginx1 # 查看挂载
cd /var/lib/docker/volumes/test_volume/_data
echo "Hello bit" > index.html
docker stop nginx1
docker rm nginx1
✅ 结论:宿主机与容器数据同步
2️⃣ -v 创建只读卷
docker run --name nginx2 -d -p 80:80 -v test_volume2:/usr/share/nginx/html:ro nginx:1.22.1
宿主机可以修改,但容器内无法修改
docker exec -it nginx2 bash
rm index.html # 报错:Read-only
docker stop nginx2
docker rm nginx2
3️⃣ --mount 创建卷
docker run --name nginx3 -d -p 8081:80 --mount type=volume,source=test_volume3,target=/usr/share/nginx/html nginx:1.22.1
docker volume inspect test_volume3
echo "Hello bit volume by mount" > /var/lib/docker/volumes/test_volume3/_data/index.html
docker stop nginx3
docker rm nginx3
✅ 结论:宿主机与容器数据同步
五、卷生命周期
-
创建容器时挂载卷,宿主机会自动创建目录并同步容器数据。
-
停止/删除容器,卷仍保留数据。
-
删除卷:
docker volume rm VOLUME_NAME -
卷共享:多个容器挂载同一卷,数据实时同步。
docker run --name nginx2 -d -v test_volume2:/usr/share/nginx/html nginx:1.22.1
docker run --name nginx3 -d -v test_volume2:/usr/share/nginx/html nginx:1.22.1
echo "Hello Bit from share volume" > /var/lib/docker/volumes/test_volume2/_data/index.html
docker stop nginx2 nginx3
docker rm nginx2 nginx3
✅ 结论:多个容器共享同一卷,内容同步。
📝 Docker 绑定卷(Bind Mount)速查
一、Bind Mount 概念
-
Bind Mount 是将宿主机目录直接挂载到容器目录。
-
特点:
-
宿主机已有目录必须存在(
--mount必须,-v可自动创建)。 -
容器中原有目录内容会被覆盖(与 Volume 不同)。
-
宿主机修改文件,容器实时可见,删除容器不影响宿主机文件。
-
二、创建绑定卷方式
1️⃣ -v 参数
docker run -d -it --name devtest -v /宿主机目录:/容器目录 nginx:latest
-
语法:
-v <host-dir>:<container-dir>[:ro] -
ro:只读
2️⃣ --mount 参数
docker run -d -it --name devtest \
--mount type=bind,source=/宿主机目录,target=/容器目录 \
nginx:latest
-
type=bind -
source:宿主机目录 -
target:容器目录 -
readonly或ro:只读挂载
⚠️ 注意:
--mount比-v更严格,宿主机目录不存在会报错。
三、操作案例
1️⃣ 创建绑定卷容器(--mount)
创建宿主机目录
mkdir -p /data/myworkdir/fs/webapp1
创建容器并挂载
docker run -d -p 80:80 --name bind1 \
--mount type=bind,source=/data/myworkdir/fs/webapp1,target=/usr/share/nginx/html \
nginx:1.22.1
- 查看挂载信息:
docker inspect bind1
- 容器中目录为空:
docker exec -it bind1 ls /usr/share/nginx/html
- 宿主机添加文件:
echo "Hello bit bind mount" > /data/myworkdir/fs/webapp1/index.html
-
浏览器访问,容器读取到宿主机内容。
-
删除容器:
docker stop bind1
docker rm bind1
宿主机文件仍存在
ls /data/myworkdir/fs/webapp1
2️⃣ 创建绑定卷容器(-v)
docker run -d -p 8080:80 --name bind2 \
-v /data/myworkdir/fs/webapp2:/usr/share/nginx/html \
nginx:1.22.1
-
宿主机目录不存在,
-v自动创建。 -
容器原有文件被覆盖。
-
宿主机写入文件后,容器实时可访问。
-
删除容器不影响宿主机文件。
四、绑定卷共享
- 多个容器挂载同一个宿主机目录,实现数据共享:
docker run -d -p 80:80 --name bind3 -v /data/myworkdir/fs/webapp1:/usr/share/nginx/html nginx:1.22.1
docker run -d -p 81:80 --name bind4 -v /data/myworkdir/fs/webapp1:/usr/share/nginx/html nginx:1.22.1
- 修改宿主机文件:
echo "bind mount after edit" > /data/myworkdir/fs/webapp1/index.html
- 两个容器都能访问最新内容:
curl 127.0.0.1:80
curl 127.0.0.1:81
- 删除容器不会影响宿主机数据:
docker stop bind3 bind4
docker rm bind3 bind4
五、Bind Mount vs Volume 对比
| 特性 | Bind Mount | Volume |
|---|---|---|
| 宿主机目录必须存在 | ✅(--mount 必须) |
❌ 可自动创建 |
| 容器目录原有文件 | 被覆盖 | 保留(第一次挂载时复制到卷) |
| 容器删除后数据 | 宿主机数据保留 | 卷保留,需手动删除 |
| 容器间共享 | ✅(同目录) | ✅(同卷) |
绑定卷删除
绑定卷不是 Docker 管理的卷,所以它没有名称,Docker 不会单独管理它 。也就是说,你无法用 docker volume rm 删除它,因为它本质上只是容器挂载宿主机目录而已。
要"删除"绑定卷,有几个思路:
1️⃣ 删除容器
- 容器停止后,挂载点就不再被占用。
docker stop bind1
docker rm bind1
⚠️ 注意:容器删除 不会删除宿主机上的文件,宿主机数据仍然存在。
2️⃣ 手动删除宿主机目录或文件
- 因为 Bind Mount 就是宿主机目录直接挂在容器里,所以删除它就是删除宿主机上的文件/目录:
rm -rf /data/myworkdir/fs/webapp1
- 删除后,容器无法访问该目录,如果容器还在运行,访问会报错。
3️⃣ 避免残留的挂载引用
- 如果你想彻底清理绑定卷,最好先删除使用它的容器,再删除宿主机目录:
docker ps -a | grep bind # 查看相关容器
docker stop <容器名>
docker rm <容器名>
rm -rf /宿主机目录
✅ 总结
-
Volume :Docker 管理,可以用
docker volume rm删除。 -
Bind Mount:宿主机目录挂载,Docker 不管理,删除靠宿主机操作。
1️⃣ tmpfs 卷的特点
-
存储位置 :完全在 内存中,不在宿主机硬盘或 Docker 卷管理目录里。
-
生命周期:
-
容器停止或删除 → 数据消失。
-
重启容器 → tmpfs 是新的空目录。
-
-
不可共享:
- 不能像普通卷那样在多个容器间共享。
-
只适用于 Linux:
- Windows 和 macOS Docker Desktop 不支持 tmpfs(或者是模拟的内存卷)。
2️⃣ 创建方式
方式一:--tmpfs
docker run -d -it --name tmptest --tmpfs /app nginx:1.22.1
-
/app就是容器内的临时挂载点 -
里面写入的内容都在内存中
方式二:--mount
docker run -d -it --name tmptest2 \
--mount type=tmpfs,destination=/app,tmpfs-size=1m,tmpfs-mode=1777 \
nginx:latest
-
type=tmpfs:指定 tmpfs 卷 -
destination:挂载到容器路径 -
tmpfs-size:内存大小限制 -
tmpfs-mode:权限(八进制)
3️⃣ tmpfs 卷的操作特点
| 操作 | 行为 |
|---|---|
| 写入文件 | 文件存储在内存中,快速,但易丢失 |
| 查看宿主机 | 找不到 tmpfs 中的文件 |
| 容器停止或删除 | tmpfs 文件立即丢失 |
| 容器重启 | tmpfs 文件为空 |
4️⃣ 示例:临时卷使用
docker run -d --name tmpfs1 --tmpfs /app nginx:1.22.1
进入容器
docker exec -it tmpfs1 bash
echo "hello tmpfs" > /app/index.html
cat /app/index.html # 输出 hello tmpfs
停止容器
docker stop tmpfs1
再次进入容器
docker start tmpfs1
docker exec -it tmpfs1 bash
ls /app # 空,文件已消失
5️⃣ tmpfs 与 Volume / Bind Mount 的对比
| 类型 | 容器内数据 | 容器删除后 | 宿主机可访问 | 多容器共享 |
|---|---|---|---|---|
| Volume | 磁盘 | 保留 | /var/lib/docker/volumes | 可以 |
| Bind Mount | 宿主机目录 | 保留 | 直接在宿主机目录 | 可以 |
| tmpfs | 内存 | 丢失 | 不可访问 | 不可以 |
小结
-
tmpfs 是真正的内存卷,适合临时数据、缓存、session 等。
-
不会占用宿主机磁盘,但容器停止就会丢失。
-
无法像 Volume 或 Bind Mount 那样进行持久化或跨容器共享。
MySQL****灾难恢复
1️⃣ 实战目的
-
核心:掌握挂载卷对数据库数据的持久化和恢复能力。
-
目标:即便容器被删除,MySQL 的业务数据仍然保留在宿主机上,可以重新创建容器恢复数据。
2️⃣ 核心操作流程
步骤 1:准备镜像
docker pull mysql:5.7
- 使用 MySQL 5.7 官方镜像。
步骤 2:创建容器并挂载卷
docker container run --name mysql-demo \
-e MYSQL_ROOT_PASSWORD=bite \
-itd \
-v /data/myworkdir/mysql-data:/var/lib/mysql \
mysql:5.7
-
-v /宿主机路径:/容器路径:挂载卷,把容器/var/lib/mysql的数据存储到宿主机/data/myworkdir/mysql-data。 -
-e MYSQL_ROOT_PASSWORD:设置 MySQL root 密码。
步骤 3:在容器中创建数据库和表
mysql -u root -p
CREATE DATABASE user;
USE user;
CREATE TABLE student(sno CHAR(3), sname VARCHAR(10));
INSERT INTO student VALUES('1','zs'),('2','ls');
SELECT * FROM student;
- 数据写入容器内
/var/lib/mysql,同时也写入宿主机映射目录。
步骤 4:查看宿主机卷
ll /data/myworkdir/mysql-data/user
-
可以看到 MySQL 数据库和表的文件已经存储在宿主机。
-
容器删除或重启都不会影响这些数据。
步骤 5:容器删除后的数据恢复
- 删除原容器:
docker stop mysql-demo
docker rm mysql-demo
- 使用相同挂载卷重新创建容器:
docker container run --name mysql-demo-new \
-e MYSQL_ROOT_PASSWORD=bite \
-itd \
-v /data/myworkdir/mysql-data:/var/lib/mysql \
mysql:5.7
- 连接 MySQL,查看数据:
mysql -u root -p
USE user;
SELECT * FROM student;
- 数据依然存在,容器可以正常读取。
3️⃣ 知识点总结
| 类型 | 何时使用 | 特点 |
|---|---|---|
| Volume | 不关心宿主机具体路径 | Docker 管理卷,持久化存储,容易跨容器 |
| Bind Mount | 需要规划具体宿主机路径 | 数据直接映射到宿主机指定目录 |
| tmpfs | 临时数据、缓存、敏感信息 | 存在内存中,容器停止后数据丢失 |
扩展思考
-
跨主机使用问题:
-
Docker 默认卷在本地主机,不会自动在其他主机共享。
-
可使用 NFS、S3 或分布式存储解决跨主机访问。
-
-
启动参数管理:
- 容器启动选项复杂,最好保存成脚本或用容器编排工具(如 Kubernetes、Docker Compose)。
-
有状态应用运维难度:
-
数据库主从、集群管理仍需运维经验。
-
复杂场景需要了解节点数量、数据库数量、主从关系等。
-
✅ 实战经验
-
挂载卷是数据库容灾的基础:容器可随时删除重建,数据安全依然保留。
-
Volume 与 Bind Mount 各有优势:
-
Volume 简单易用
-
Bind Mount 可自定义路径和大小
-
-
备份和恢复策略:
-
即便容器删除,数据在宿主机仍可恢复
-
定期备份宿主机挂载目录,提高灾难恢复能力
-
常见问题
- 什么时候用 Volume ,什么时候用 bind 、 tmpfs ?
volume : volume 是 docker 的宿主机文件系统一部分,用于不需要规划具体目录的场
景
bind : bind mount 完全是依赖于主机的目录结构和操作系统,用于目录需要提前规划,
比如 mysql 的目录需要个空间大的,其他服务有不占用的时候,用 volume 就不太合
适了
tmpfs :用于敏感文件存储,文件不想存储的宿主机和容器的可写层之中
扩展思考:存储卷在实际研发中带来了哪些问题
1. 跨主机使用
docker 存储卷是使用其所在的宿主机上的本地文件系统目录,也就是宿主机有一块磁
盘,这块磁盘并没有共享给其他的 docker 主机,容器在这宿主机上停止或删除,是可
以重新再创建的,但是不能调度到其他的主机上,这也是 docker 本身没有解决的问题,
所以 docker 存储卷默认就是 docker 所在主机的本地,但是自己搭建一个共享的 NFS
来存储 docker 存储的数据,也可以实现, 但是这个过程强依赖于运维人员的能力 。
所以未来应用的存储和数据往往分离,越来越多的分布式存储方案出现,如 s3 系列,
nfs 等。
2. 启动参数未知
容器有一个问题,一般与进程的启动不太一样,就是容器启动时选项比较多,如果下
次再启动时,很容器会忘记它启动时的选项,所以最好有一个文件来保存容器的启动,
这就是容器编排工具的作用。
一般情况下,是使用命令来启动操作 docker, 但是可以通过文件来读,也就读文件来启
动,读所需要的存储卷等,但是它也只是操作一个容器,如果要几十上百个容器操作,
就需要 专业的容器编排工具
这种一般像开源的 k8s ,各个云厂商也有自己的企业版编排软件。
3. 复杂场景仍然需要运维
对于有状态要持久的集群化组件,如 mysql 的主从。部署维护一个 Mysql 主从需要运
维知识、经验整合进去才能实现所谓的部署,扩展或缩容,出现问题后修复,必须要
了解集群的规模有多大,有多少个主节点,有多少个从节点,主节点上有多少个库,
这些都要一清二楚,才能修复故障,这些就 强依赖于运维经验
这种复杂的场景往往还是需要人力,很难有完美的工具出现。
Docker 网络管理笔记
一、为什么需要 Docker 网络管理
容器默认网络与宿主机及其他容器相互隔离,但在实际使用中,我们常常需要考虑:
- 容器之间如何通信
- 容器与宿主机通信
- 容器与外部网络通信
- 容器中运行的网络应用(如 nginx、Web 应用、数据库)如何被外部访问
- 容器如何打破隔离,实现自定义网络
- 容器不需要网络时如何实现
- 容器需要定制化网络(如特殊集群网络、局域网)
总结:网络管理可以解决通信、隔离、访问和定制化需求,是容器使用的重要组成部分。
二、Docker 网络架构
Docker 网络提供容器独立的虚拟网络环境,包括:
- 网络设备(网卡)
- IP 协议栈
- 端口套接字
- 路由表
- 防火墙与 DNS 配置
Docker 网络架构由三部分组成:
1. CNM(Container Network Model)
CNM 定义 Docker 网络的三个基础组件:
| 组件 | 功能 |
|---|---|
| Sandbox | 提供容器的虚拟网络栈,包括 IP、端口、路由、防火墙、DNS 等,实现网络隔离 |
| Network | 虚拟子网,用于容器间通信 |
| Endpoint | 虚拟网络接口,容器通过它接入网络,一个 Endpoint 只能接入一个 Network,多网络容器需要多个 Endpoint |
示例:容器 B 有两个 Endpoint,分别连接 NetworkA 和 NetworkB。容器 A 可与 B 的 NetworkA 通信,但无法与 C 通信。
2. Libnetwork
- CNM 的标准实现,开源库,Go 语言编写
- 实现 Sandbox、Network、Endpoint
- 提供本地服务发现、Ingress 负载均衡及网络管理功能
3. 驱动(Driver)
- 负责数据层的实现:连通性和隔离性
- 内置驱动(原生驱动):Bridge、Host、Overlay、MacVlan、IPVlan、None
- 扩展 Docker 网络功能,创建和管理网络资源
三、常见 Docker 网络类型
| 类型 | 描述 | 使用场景 |
|---|---|---|
| bridge | 默认网络驱动,创建 Linux 网桥,容器间可通信,可配置对外访问 | 同一宿主机容器通信 |
| host | 容器使用宿主机网络,移除网络隔离 | 容器需访问主机网络,保留其他资源隔离 |
| container | 新容器共享已存在容器网络,不创建独立网卡 | 容器间共享 IP/端口等网络资源 |
| none | 拥有 Network Namespace,但无网络配置 | 完全隔离,无网络需求 |
| overlay | 跨主机容器网络,支持 Docker Swarm 集群 | 跨宿主机容器通信,多节点协同工作 |
Docker 安装后默认创建
docker0网桥,用于容器与宿主机通信。
四、Docker 网络管理命令
| 命令 | 功能 | 示例 |
|---|---|---|
docker network create |
创建自定义网络 | docker network create --driver=bridge --subnet=192.168.0.0/16 br0 |
docker network inspect |
查看网络详情 | docker network inspect mynetwork |
docker network connect |
将容器连接到网络 | docker network connect --ip 10.10.36.122 multi-host-network container2 |
docker network disconnect |
断开容器网络 | docker network disconnect -f multi-host-network my_container1 |
docker network ls |
列出网络 | docker network ls 或 docker network list |
docker network rm |
删除网络 | docker network rm br0 |
docker network prune |
删除未使用网络 | docker network prune -f |
关键参数说明
-d, --driver:指定网络驱动--subnet:网段(CIDR)--gateway:网关地址--ip/--ip6:指定容器 IP-f, --force:强制执行-q:只显示网络 ID--format:自定义输出格式--filter:过滤条件
五、总结
- Docker 网络管理是容器通信、隔离和访问控制的基础
- 架构由 CNM、Libnetwork 和驱动组成
- 常见网络模式:bridge、host、container、none、overlay
- 提供完整命令集,可创建、连接、断开、删除、查看网络
重点:合理配置网络能满足不同容器应用场景下的通信、隔离和安全需求。
Docker 网络命令基本操作笔记
1. 创建网络并指定 IP 地址段
docker network create --subnet=172.18.0.0/16 mynetwork
--subnet:指定网络的 IP 地址段(CIDR)mynetwork:自定义网络名称
2. 查看现有网络
docker network ls
输出示例:
NETWORK ID NAME DRIVER SCOPE
722af9bec715 mynetwork bridge local
6bdab7287628 bridge bridge local
...
3. 创建容器并加入自定义网络
docker run -itd --name mynginx --network mynetwork nginx:1.22.1
--name:指定容器名称--network:指定加入的网络
4. 查看容器网络信息
docker inspect mynginx
Networks下可以看到容器所属网络信息:IPAddress:容器 IPGateway:网关MacAddress:MAC 地址
5. 创建容器但不加入自定义网络
docker run -itd --name mynginx2 nginx:1.22.1
- 默认使用 Docker 自带的
docker0桥接网络
6. 查看默认网络的容器信息
docker inspect mynginx2
- 可以看到容器使用的
bridge网络 - IP 地址在
docker0网段,例如172.17.0.x
7. 将已有容器加入自定义网络
docker network connect mynetwork mynginx2
- 可选参数:
--ip指定 IP 地址 - 容器可以同时属于多个网络
8. 查看加入自定义网络后的容器信息
docker inspect mynginx2
Networks会显示两个网络:bridge(默认网络)mynetwork(自定义网络)
9. 断开容器网络
docker network disconnect mynetwork mynginx2
- 容器会移除指定网络,只保留其他已连接的网络
10. 删除网络
docker network rm mynetwork
- 如果网络中还有容器连接,会提示错误:
Error: network mynetwork has active endpoints
- 需要先停止并删除所有连接的容器:
docker stop mynginx mynginx2
docker rm mynginx mynginx2
docker network rm mynetwork
11. 总结操作流程
| 步骤 | 命令 | 说明 |
|---|---|---|
| 创建网络 | docker network create |
指定子网和驱动 |
| 查看网络 | docker network ls |
列出所有网络 |
| 创建容器加入网络 | docker run --network |
容器直接加入指定网络 |
| 查看容器网络 | docker inspect |
查看 IP、网关、MAC 等信息 |
| 容器加入已有网络 | docker network connect |
可动态加入网络 |
| 断开网络 | docker network disconnect |
移除容器网络连接 |
| 删除网络 | docker network rm |
网络必须没有容器连接 |
Docker Bridge 网络详解笔记
1. 网络介绍
- Bridge 网络 是 Docker 内置的网络类型,底层基于 Linux 内核的 Linux Bridge 技术。
- 功能:
- 连接同一桥接网络的容器,实现容器间通信。
- 提供与未连接容器的隔离。
- 默认情况下,如果创建容器未指定
--network,容器会加入默认 bridge 网络 (对应 Linux 内核中的docker0网桥)。
生活类比
- Bridge 就像一个立交桥,连接不同"路口",容器就像车辆,可以通过桥进行互通。
2. 默认 Bridge 网络
- 查看支持的 Docker 网络:
docker network ls
输出示例:
NETWORK ID NAME DRIVER SCOPE
62025acd24c8 bridge bridge local
785122438a77 host host local
9ff4f20749be none null local
bridge网络对应内核中的docker0网桥。- 容器自动连接到
docker0,通过它进行容器间通信。
3. 容器间通信示例
3.1 创建两个容器
docker container run -itd --name c1 busybox
docker container run -itd --name c2 busybox
3.2 查看容器 IP
docker container exec -it c1 ip a
docker container exec -it c2 ip a
示例 IP:
- c1:
172.17.0.2 - c2:
172.17.0.3
3.3 测试容器间通信
docker container exec -it c1 ping 172.17.0.3
输出:
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.113 ms
✅ 说明 c1 与 c2 可以通信。
4. 查看 bridge 网络信息
docker network inspect bridge
重要字段:
Subnet:网络子网,例如172.17.0.0/16Gateway:网关,例如172.17.0.1Containers:已连接的容器信息
停止容器会自动断开与 docker0 的连接:
docker container stop c1
docker network inspect bridge
5. 创建自定义 Bridge 网络
5.1 创建新网络
docker network create -d bridge new-bridge
-d bridge:指定桥接驱动- 网络创建后,默认分配一个新的子网(如
172.18.0.0/16)
⚠️ 如果出现 iptables 错误,可重启 Docker:
systemctl restart docker
5.2 查看自定义网络
docker network inspect new-bridge
重要字段:
Subnet:172.18.0.0/16Gateway:172.18.0.1Containers: 记录加入该网络的容器
6. 容器连接自定义 Bridge
docker container run -itd --name c3 --network new-bridge busybox
docker container inspect c3 | grep "Networks" -A 17
- 容器 c3 会被分配 IP:
172.18.0.x - 容器可以通过该网络与其他连接到
new-bridge的容器通信
7. 总结
| 功能 | 默认 Bridge | 自定义 Bridge |
|---|---|---|
| 网络驱动 | bridge | bridge |
| 对应网桥 | docker0 | br-<ID> |
| 子网 | 172.17.0.0/16 | 可自定义,如 172.18.0.0/16 |
| 容器通信 | 同一网络内互通 | 同一自定义网络内互通 |
| 创建命令 | 自动创建 | docker network create -d bridge <name> |
| 查看命令 | docker network inspect bridge |
docker network inspect <name> |
✅ 重点理解:
- 默认 bridge 网络对应 docker0
- 自定义 bridge 网络可指定子网
- 容器只能与同一网络内的容器直接通信
Docker DNS 解析与端口转发笔记
1. DNS 解析
1.1 默认 bridge 网络
- 默认 bridge 网络 (docker0)不支持 Docker 内部 DNS 解析。
- 容器之间无法通过 容器名通信,只能通过 IP 地址通信。
1.2 自定义 bridge 网络
- 自定义 bridge 网络支持 Docker 内部 DNS 服务。
- 可以直接通过 容器名进行互相访问,DNS 服务会自动解析容器名到 IP 地址。
1.3 实验环境
| 容器 | 网络 | IP 地址示例 |
|---|---|---|
| c1 | bridge | 172.17.0.3 |
| c2 | bridge | 172.17.0.2 |
| c3 | new-bridge | 172.18.0.2 |
| c4 | new-bridge | 172.18.0.3 |
1.4 验证 DNS
默认 bridge 网络(不支持 DNS)
docker container exec -it c1 ping c2
输出: ping: bad address 'c2'
自定义 bridge 网络(支持 DNS)
docker container exec -it c3 ping c4
输出: PING c4 (172.18.0.3): 56 data bytes
✅ 说明 c3 能够通过容器名 c4 进行访问。
2. 端口暴露与转发
2.1 暴露方式
| 参数 | 作用 |
|---|---|
-P |
暴露容器所有端口到宿主机随机端口(动态端口) |
-p <hostPort>:<containerPort> |
将容器端口映射到宿主机指定端口 |
- 查看端口映射:
docker port <容器名>
2.2 端口转发原理
- 连接 bridge 网络的容器只能与同网络容器通信。
- 如果容器需要提供外部服务,需要端口转发,将容器端口映射到宿主机端口。
- 示例:
- 容器内部 80 端口映射到宿主机 8088 端口
- 容器内部 80 端口映射到宿主机 8089 端口
- 浏览器访问宿主机对应端口即可访问容器服务。
2.3 操作示例
docker container run --name test-nginx --rm -d -p 8088:80 nginx
--rm:容器停止后自动删除--name:指定容器名-p 8088:80:将容器 80 端口映射到宿主机 8088 端口- 访问宿主机的 8088 端口即可看到 nginx 首页。
✅ 重点理解
- 默认 bridge 网络不支持 DNS,自定义 bridge 网络支持。
- Docker DNS 解析仅在同一自定义网络内生效。
- 端口映射是容器提供外部服务的关键方式。
-P与-p的区别:动态端口 vs 指定端口。
🧠 Docker Host 网络(重点理解版)
1️⃣ 什么是 Host 网络(核心一句话)
✅ 容器直接使用宿主机的网络,不再有自己的网络隔离
2️⃣ 和 Bridge 的本质区别
| 项目 | Bridge 网络 | Host 网络 |
|---|---|---|
| 网络隔离 | ✅ 有(独立 Namespace) | ❌ 没有 |
| IP 地址 | 容器自己 IP(172.x) | 和宿主机一样 |
| 网卡 | 虚拟网卡 eth0 | 直接用宿主机网卡 |
| 端口 | 需要 -p 映射 |
❌ 不需要 |
| 性能 | 有 NAT 损耗 | ✅ 更高 |
3️⃣ 你实验里发生了什么(帮你拆解)
✅ c1(bridge 网络)
docker run --name c1 -itd busybox
👉 网络情况:
- IP:
172.17.0.2 - 网卡:虚拟 eth0
- 连接:docker0
✔ 特点:
- 有"自己的小世界"
- 和宿主机隔离
✅ c2(host 网络)
docker run --name c2 -itd --network=host busybox
👉 关键变化:
你看到的:
inet 10.0.8.12/22 ← 宿主机IP
docker0 ← 宿主机网桥
br-xxxx ← 所有网络
👉 说明:
❗ c2 已经"变成宿主机的一部分"了
✔ 没有:
- 独立 IP ❌
- 独立网卡 ❌
- 网络隔离 ❌
4️⃣ 为什么 Host 网络性能高
Bridge 网络路径:
容器 → veth → docker0 → NAT → 宿主机 → 外网
Host 网络路径:
容器 → 宿主机网卡 → 外网
👉 少了:
- NAT 转换
- 网桥转发
✅ 所以更快
5️⃣ Host 网络最大特点(记住这3条就够)
✅ 特点1:没有端口映射
docker run -p 8080:80 ...
👉 在 host 网络下:
❌ 完全没意义
因为:
容器端口 = 宿主机端口
✅ 特点2:端口会冲突(很重要⚠️)
比如:
宿主机已经用了 80 端口
nginx
再起一个容器
docker run --network host nginx
👉 ❌ 直接启动失败
✅ 特点3:没有网络隔离(安全性降低)
- 容器可以:
- 直接访问宿主机端口
- 监听宿主机端口
- 风险更大
6️⃣ 使用场景(面试高频🔥)
✅ 适合用 host 网络的情况:
- 高性能服务
- 游戏服务器
- 高并发 API
- 需要直接访问宿主机网络
- 监控工具(Prometheus node-exporter)
- 网络分析工具
- 端口很多,不想一个个映射
- 比如某些中间件
❌ 不适合的情况:
- 多容器部署(容易端口冲突)
- 微服务架构(推荐自定义 bridge)
- 需要安全隔离的场景
7️⃣ 一句话总结(非常重要)
💡 Bridge = 虚拟网络(安全但有损耗)
💡 Host = 直接用宿主机(快但不安全)
🎯 最后帮你串起来(和你前面学的结合)
你现在已经学了三种网络:
| 网络模式 | 特点 |
|---|---|
| bridge(默认) | 能通信但不能用名字 |
| 自定义 bridge | ✅ 推荐,支持 DNS |
| host | 性能最高,但无隔离 |
🧠 Docker Host vs Bridge(带实操观察版)
🎯 核心结论(先记住)
判断 host 和 bridge 的本质方法:进入容器看网络(ifconfig / ip a)
🔍 关键观察步骤(必须会)
1️⃣ 进入容器
docker exec -it c1 sh
docker exec -it c2 sh
2️⃣ 查看网络信息(重点)
ip a
或
ifconfig
🧪 实验对比(重点记忆🔥)
✅ bridge 网络容器(如 c1)
eth0@ifxxx
inet 172.17.0.2/16
🔑 你要观察到:
- ✅ 有 独立 IP(172.x)
- ✅ 有 eth0 虚拟网卡
- ❌ 看不到宿主机网卡(如 10.x / ens33)
👉 说明:
✔ 容器在"自己的网络空间"(隔离的)
✅ host 网络容器(如 c2)
eth0
inet 10.0.8.12/22 ← 宿主机 IP
docker0
br-xxxx
🔑 你要观察到:
- ❌ 没有 172.x 容器 IP
- ✅ IP = 宿主机 IP
- ✅ 能看到:
- docker0
- br-xxx
- 宿主机网卡
👉 说明:
❗ 容器和宿主机共用网络 Namespace
一、Docker container(other container)网络模式
1️⃣ 核心概念(一句话)
👉 一个容器直接复用另一个容器的网络环境(Network Namespace)
2️⃣ 本质原理
- Docker 每个容器默认都有独立的 Network Namespace
container模式做了两件事:- 找到目标容器的 Network Namespace
- 新容器加入这个 namespace
👉 本质:两个容器用的是同一套网络
3️⃣ 关键特征(非常重要)
✔ 两个容器:
- IP 完全一样 ✅
- MAC 地址一样 ✅
- 网卡一样(eth0)✅
✔ 它们之间:
- ❌ 没有网络隔离
- ✅ 可以用
localhost直接通信(性能高)
✔ 和其他容器 / 宿主机:
- ✅ 仍然隔离
4️⃣ 实验流程(你这个案例整理版)
创建第一个容器(提供网络)
docker run -itd --name netcontainer1 busybox
创建第二个容器(复用网络)
docker run -itd --name netcontainer2 \
--network container:netcontainer1 busybox
进入容器查看网络(关键步骤)
docker exec -it netcontainer1 sh
ifconfig
docker exec -it netcontainer2 sh
ifconfig
👉 结论:
- IP 一样
- MAC 一样
- 完全共享网络
5️⃣ 重要现象(考试爱考)
❗ 停掉 netcontainer1
docker stop netcontainer1
再进 netcontainer2:
ifconfig
👉 结果:
- ❌ eth0 消失
- ✅ 只剩 lo(本地回环)
👉 原因:
👉 网络 namespace 来自 netcontainer1,它没了 → 网络也没了
❗ 重启恢复
docker restart netcontainer1
docker restart netcontainer2
👉 网络恢复正常
6️⃣ 优缺点总结
👍 优点
- 通信快(走 localhost)
- 无需端口映射
- 适合强耦合服务
👎 缺点
- 强依赖(主容器挂了,全挂)
- 不灵活
- 不适合生产主流架构
7️⃣ 使用场景
👉 常见:Sidecar 模式(面试加分点)
- 日志收集容器
- 监控容器
- 网络代理容器
👉 特点:
👉 多个容器组成一个"逻辑整体"
二、Docker none 网络模式
1️⃣ 核心概念
👉 容器完全没有网络
2️⃣ 特征
容器内只有:
lo (127.0.0.1)
👉 没有:
- eth0 ❌
- IP ❌
- 外网 ❌
3️⃣ 使用方式
docker run -itd --name c3 --network none busybox
查看:
docker exec -it c3 ip a
👉 只看到 lo
4️⃣ 使用场景
🔒 高安全场景
- 生成密码
- 加密计算
- 敏感数据处理
👉 防止数据被网络窃取
⚙️ 自定义网络
- 第三方程序自己管理网络
- Kubernetes / SDN 场景
三、对比总结(重点)
| 模式 | 网络情况 | 隔离性 | 特点 |
|---|---|---|---|
| bridge | 独立 IP | 有隔离 | 默认模式 |
| host | 用宿主机 | 无隔离 | 性能最高 |
| container | 共享容器 | 半隔离 | 依赖强 |
| none | 无网络 | 完全隔离 | 最安全 |
四、一句话记忆
👉 container 模式:
👉 "两个容器用一张网卡"
👉 none 模式:
👉 "这个容器断网了"
🚀 Docker Compose 笔记(整理版)
一、什么是 Docker Compose
一句话理解:
👉 用一个 docker-compose.yml 管理多个容器,一键启动整个应用。
核心作用:
- 定义多个容器(服务)
- 管理它们的关系(依赖、网络、数据)
- 一条命令启动 / 停止
二、核心概念(必考)
1️⃣ Service(服务)
- 一个容器的抽象(可以多个实例)
- 对应
docker run的一个容器
👉 例子:
- web(后端)
- db(数据库)
- redis(缓存)
2️⃣ Project(项目)
- 一组相关服务的集合
- 一个
docker-compose.yml= 一个项目
👉 类比:
项目 = 整个系统
服务 = 每个容器
三、为什么要用 Compose
❌ 不用 Compose
docker run mysql
docker run redis
docker run nginx
问题:
- 命令多
- 顺序麻烦
- 不好管理
✅ 用 Compose
docker compose up
👉 自动:
- 按顺序启动
- 自动建网络
- 自动关联容器
四、基本使用流程(非常重要)
1️⃣ 写配置文件
docker-compose.yml
2️⃣ 启动
docker compose up -d
3️⃣ 停止
docker compose down
五、核心功能
Compose 可以管理整个生命周期:
- 启动:
up - 停止:
down - 重启:
restart - 查看:
ps - 日志:
logs - 执行命令:
exec
六、docker-compose.yml 结构
version: "3.8"
services:
web:
image: nginx
ports:
- "8080:80"
db:
image: mysql
volumes:
networks:
七、常用字段(重点掌握🔥)
1️⃣ image(镜像)
image: nginx:latest
2️⃣ build(构建镜像)
build: .
高级写法:
build:
context: .
dockerfile: Dockerfile
3️⃣ command(覆盖 CMD)
command: ["python", "app.py"]
4️⃣ entrypoint(覆盖入口)
entrypoint: /start.sh
👉 区别(面试常问):
- command → 参数
- entrypoint → 主程序
5️⃣ environment(环境变量)
environment:
MYSQL_ROOT_PASSWORD: 123456
或:
environment:
- MYSQL_ROOT_PASSWORD=123456
6️⃣ env_file(从文件读取)
env_file: .env
7️⃣ ports(端口映射)
ports:
- "8080:80"
👉 规则:
宿主机:容器
8️⃣ expose(仅内部暴露)
expose:
- "3306"
👉 特点:
- ❌ 外部访问不了
- ✅ 其他容器可以访问
9️⃣ volumes(数据卷)
volumes:
- ./data:/var/lib/mysql
👉 作用:
- 数据持久化
- 宿主机 ↔ 容器同步
🔟 networks(网络)
networks:
- mynet
👉 作用:
- 容器互联
- 服务名可直接访问(DNS)
1️⃣1️⃣ depends_on(依赖)
depends_on:
-
db
-
redis
👉 启动顺序:
db → redis → web
⚠️ 注意:
- 只保证启动顺序
- 不保证"服务可用"
👉 高级写法(推荐):
depends_on:
db:
condition: service_healthy
1️⃣2️⃣ healthcheck(健康检查)
healthcheck:
test: ["CMD", "mysql", "-uroot", "-p123456", "-e", "SELECT 1"]
interval: 10s
timeout: 5s
retries: 5
八、完整实战示例(重点🔥)
version: "3.8"
services:
web:
build: .
ports:
- "8080:8080"
depends_on:
db:
condition: service_healthy
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123456
volumes:
- ./mysql:/var/lib/mysql
healthcheck:
test: ["CMD", "mysql", "-uroot", "-p123456", "-e", "SELECT 1"]
interval: 10s
retries: 5
九、使用场景
✅ 1. 本地开发
- 一键启动环境(MySQL + Redis + 后端)
✅ 2. 测试环境
- 快速搭建完整系统
✅ 3. 服务编排(单机)
- 小型项目
十、重要总结(面试速记🔥)
⭐ Compose解决什么问题?
👉 多容器管理
⭐ 核心对象
- service(服务)
- project(项目)
⭐ 最常用命令
docker compose up -d
docker compose down
docker compose ps
docker compose logs
⭐ 高频考点
✅ ports vs expose
- ports → 对外
- expose → 仅内部
✅ command vs entrypoint
- command → 参数
- entrypoint → 主程序
✅ depends_on
- ✔ 控制启动顺序
- ❌ 不保证可用
十一、记忆口诀(帮你快速记)
👉 Compose = 一键启动一堆容器
👉 三大核心:
服务 + 网络 + 数据
👉 写配置 = 写 docker run 的集合
🚀 Docker Compose 命令整理(高效版)
一、命令总格式(先记这个)
docker compose [OPTIONS] COMMAND [ARGS...]
常用全局参数
-f docker-compose.yml # 指定配置文件
-p myproject # 指定项目名
二、核心命令(必须熟练🔥)
1️⃣ 启动项目:up(最重要)
docker compose up -d
👉 功能(一步到位):
- 构建镜像
- 创建容器
- 启动服务
- 建立网络
常用参数
-d # 后台运行(必用)
--build # 强制重新构建镜像
--no-recreate # 不重新创建容器
--force-recreate # 强制重新创建
2️⃣ 停止并删除:down
docker compose down
👉 功能:
- 停止所有容器
- 删除容器 + 网络
常用参数
-v # 删除数据卷(危险⚠️)
3️⃣ 查看运行状态:ps
docker compose ps
👉 查看当前项目所有容器
4️⃣ 查看日志:logs
docker compose logs -f
👉 类似 tail -f
5️⃣ 进入容器执行命令:exec
docker compose exec web bash
👉 进入正在运行的容器
6️⃣ 重启服务:restart
docker compose restart
👉 可指定服务:
docker compose restart web
三、容器生命周期管理
启动 / 停止
docker compose start # 启动已停止容器
docker compose stop # 停止容器
docker compose restart # 重启
强制操作
docker compose kill # 强制停止
docker compose rm # 删除已停止容器
暂停恢复
docker compose pause
docker compose unpause
四、构建 & 镜像相关
docker compose build # 构建镜像
docker compose pull # 拉取镜像
docker compose push # 推送镜像
docker compose images # 查看镜像
五、调试 & 运维常用命令
运行一次性命令(很常用🔥)
docker compose run web ls
👉 特点:
- 会新建容器执行命令
- 不影响正在运行容器
常用参数
--rm # 执行完自动删除
-e KEY=VAL # 环境变量
-p 8080:80 # 端口映射
查看进程
docker compose top
查看端口映射
docker compose port web 80
拷贝文件
docker compose cp web:/app/file .
查看事件流(高级)
docker compose events
六、项目信息
docker compose ls # 查看所有项目
docker compose config # 查看解析后的配置
docker compose version # 查看版本
七、命令分类总结(面试用🔥)
🚀 启动类
up / start
🛑 停止类
stop / down / kill
🔄 运维类
ps / logs / exec / top
🏗 构建类
build / pull / push
🧪 临时执行
run
八、重点对比(必会🔥)
🔹 up vs run
| 命令 | 用途 |
|---|---|
| up | 启动整个项目 |
| run | 临时执行命令 |
🔹 stop vs down
| 命令 | 区别 |
|---|---|
| stop | 只停止容器 |
| down | 删除容器+网络 |
🔹 exec vs run
| 命令 | 区别 |
|---|---|
| exec | 在已有容器执行 |
| run | 新建容器执行 |
九、实战常用组合(🔥重点)
启动项目
docker compose up -d
查看日志
docker compose logs -f
进入容器
docker compose exec web bash
停止并清理
docker compose down
十、一句话记忆
👉 Compose 常用就 6 个命令:
up / down / ps / logs / exec / restart
🚀 Docker Compose 实战案例(标准流程版)
一、整体目标(先搞清楚在干嘛)
👉 搭建一个三层服务:
Nginx(web) + MySQL(数据库) + Redis(缓存)
👉 特点:
- 三个容器
- 同一网络
- web 依赖 db + redis
- 带健康检查(进阶点🔥)
二、步骤总览(先记流程)
-
创建目录
-
写 docker-compose.yml
-
校验配置
-
准备数据(html)
-
启动服务
-
访问验证
-
停止 / 启动 / 删除
三、详细步骤(实战)
1️⃣ 创建项目目录
mkdir -p /data/myworkdir/compose/base
cd /data/myworkdir/compose/base
👉 本质:
- 一个目录 = 一个 Compose 项目
2️⃣ 编写 docker-compose.yml
version: "3.8"
services:
web:
image: nginx:1.24.0
environment:
TEST: 1
ports:
- 8979:80
networks:
- mytestnet
volumes:
- ./mynginxhome:/usr/share/nginx/html
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "bit@123"
networks:
- mytestnet
volumes:
- /data/maxhou/mysqldata/varlib/:/var/lib/mysql
healthcheck:
test: mysql --user=root --password='bit@123' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
redis:
image: redis:7
networks:
- mytestnet
healthcheck:
test: redis-cli ping
interval: 10s
timeout: 5s
retries: 10
networks:
mytestnet:
🔥 关键点解析(一定要懂)
1. depends_on + healthcheck(高级点)
depends_on:
mysql:
condition: service_healthy
👉 意思:
mysql 健康 → web 才启动
⚠️ 面试重点:
- depends_on 默认 ❌ 不保证可用
- 加 healthcheck 才算真正依赖
2. volumes(数据挂载)
./mynginxhome:/usr/share/nginx/html
👉 本质:
宿主机目录 → 容器目录
3. ports(端口映射)
8979:80
👉 访问:
4. networks(网络)
mytestnet
👉 三个容器可以互相访问:
mysql:3306
redis:6379
3️⃣ 校验配置(很重要🔥)
docker compose config
👉 作用:
- 检查语法
- 展开默认配置
❌ 常见错误
version must be a string
✔ 修复:
version: "3.8" # 必须加引号
4️⃣ 准备网页内容
mkdir -p ./mynginxhome
cd ./mynginxhome
echo "Hello bit" > index.html
👉 原理:
- 挂载到 nginx 默认首页目录
5️⃣ 启动服务(核心)
docker compose up -d
👉 过程:
创建网络 → 启动 mysql → 启动 redis → 启动 web
👉 输出重点:
Healthy = 健康检查通过
6️⃣ 访问验证
浏览器访问:
👉 看到:
Hello bit
说明成功 ✅
7️⃣ 停止服务
docker compose stop
👉 特点:
- 只停止
- 容器还在
8️⃣ 再次启动
docker compose start
👉 特点:
- 不重新创建
- 直接启动已有容器
9️⃣ 删除服务(彻底清理)
docker compose down
👉 删除:
- 容器
- 网络
⚠️ 不删数据卷(除非 -v)
四、流程图(帮你理解)
docker compose up
↓
创建网络
↓
启动 mysql → 健康
↓
启动 redis → 健康
↓
启动 web
五、核心知识总结(面试🔥)
⭐ 为什么 web 最后启动?
👉 因为:
depends_on + healthcheck
⭐ 为什么要用 volumes?
👉 防止数据丢失(MySQL)
⭐ 为什么用 networks?
👉 容器之间通信(通过服务名)
⭐ stop vs down
| 命令 | 效果 |
|---|---|
| stop | 停止容器 |
| down | 删除容器+网络 |
六、一句话总结
👉 这个案例本质就是:
用 Compose 一键启动 Web + DB + Redis,并保证启动顺序和数据持久化