
作者:王仕宇(JavaPub)
前言
很多开发者学习 Docker,只停留在:
bash
docker run nginx
然后认为 Docker 就是一个启动程序的工具。
但真正进入企业开发之后,你会发现:
- 为什么 Docker 启动速度这么快?
- 容器和虚拟机有什么区别?
- 为什么删除容器数据没了?
- 为什么线上 Docker 容器会越来越大?
- 为什么生产环境一定使用 Docker Compose?
- 为什么 Kubernetes 基于 Docker 思想发展?
理解 Docker 底层原理,才能真正掌握容器化技术。
一、Docker 到底解决了什么问题?
在传统开发模式中:
开发环境:
Mac
Node 20
MySQL 8
Redis 7
Python 3.12
测试环境:
Linux
Node 18
MySQL 5.7
Redis 6
Python 3.10
生产环境:
Linux
Node 16
MySQL 5.7
Redis 6
结果:
开发:
我本地可以运行。
上线:
为什么服务器不能运行?
Docker 解决的问题:
应用
+
运行环境
+
依赖
一起打包
形成:
Docker Image
无论在哪里:
开发机器
服务器
云服务器
Kubernetes
运行结果保持一致。
这就是:
Build Once, Run Anywhere
二、Docker 架构
Docker 主要由三部分组成:
Docker Client
|
|
Docker Daemon
|
----------------
Image Container
1. Docker Client
就是我们使用的命令:
bash
docker run nginx
实际上发送请求:
docker CLI
↓
Docker API
↓
Docker Daemon
2. Docker Daemon
后台服务:
Linux:
bash
systemctl status docker
负责:
- 创建容器
- 管理镜像
- 管理网络
- 管理存储
3. Docker Registry
镜像仓库:
例如:
Docker Hub:
hub.docker.com
流程:
docker pull nginx
本地没有
↓
Docker Hub下载
↓
保存Image
三、Docker 容器为什么这么快?
很多新人认为:
Docker = 小型虚拟机
实际上不是。
虚拟机架构
传统虚拟机:
物理服务器
↓
Hypervisor
↓
Guest OS
↓
应用
例如:
VMware
VirtualBox
需要完整操作系统。
Docker 架构
Docker:
服务器
↓
Linux Kernel
↓
Docker
↓
Container
↓
应用
多个容器共享:
- Linux Kernel
- 系统资源
所以启动:
虚拟机:
分钟级
Docker:
秒级
四、Docker 三大核心技术
Docker 能实现隔离,主要依靠 Linux:
- Namespace
- Cgroups
- UnionFS
1. Namespace:隔离环境
Namespace 负责:
看起来像独立系统。
例如:
容器 A:
PID:
1 nginx
2 worker
容器 B:
PID:
1 mysql
实际上:
宿主机:
PID:
100 nginx
200 mysql
但是容器内部认为:
自己就是系统
Namespace 类型:
| 类型 | 作用 |
|---|---|
| PID | 进程隔离 |
| NET | 网络隔离 |
| MNT | 文件系统隔离 |
| UTS | 主机名隔离 |
| IPC | 进程通信隔离 |
2. Cgroups:资源限制
如果一个容器占满 CPU:
服务器可能挂掉。
Cgroups:
控制:
- CPU
- 内存
- IO
例如:
限制 MySQL:
bash
docker run \
--memory=512m \
mysql
表示:
最多使用:
512MB RAM
限制 CPU:
bash
docker run \
--cpus=2 \
nginx
最多:
2个CPU核心
3. UnionFS:镜像分层
Docker 镜像不是一个完整文件。
例如:
nginx:
Layer 1
Ubuntu
Layer 2
nginx
Layer 3
配置文件
Layer 4
启动脚本
多个镜像共享基础层。
好处:
减少空间。
查看:
bash
docker history nginx
五、Docker 镜像到底是什么?
镜像:
本质:
一个只读模板。
例如:
Dockerfile:
dockerfile
FROM ubuntu
RUN apt update
RUN apt install nginx
COPY index.html /
CMD nginx
执行:
bash
docker build -t my-nginx .
生成:
Image
my-nginx
运行:
bash
docker run my-nginx
产生:
Container
关系:
Image
↓
Container
类似:
类
↓
对象
六、Dockerfile 最佳实践
1. 使用官方基础镜像
推荐:
dockerfile
FROM node:20-alpine
不要:
dockerfile
FROM ubuntu
自己安装node
原因:
- 镜像小
- 安全
- 快速
2. 减少镜像体积
错误:
dockerfile
RUN apt update
RUN apt install xxx
多个 Layer。
优化:
dockerfile
RUN apt update \
&& apt install xxx \
&& rm -rf /var/lib/apt/lists/*
3. 使用 .dockerignore
类似:
.gitignore
例如:
node_modules
.git
.env
避免进入镜像。
七、Docker 数据持久化
很多新人踩坑:
启动 MySQL:
bash
docker run mysql
创建数据:
users
orders
products
删除:
bash
docker rm mysql
数据全部消失。
原因:
容器是临时的。
解决:
Volume。
结构:
宿主机
/data/mysql
|
|
容器
/var/lib/mysql
创建:
bash
docker volume create mysql-data
使用:
bash
docker run \
-v mysql-data:/var/lib/mysql \
mysql
八、Docker 网络原理
容器默认:
container network
docker0
查看:
bash
ip addr
创建:
app
|
docker network
|
mysql
推荐:
bash
docker network create app-net
启动:
MySQL:
bash
docker run \
--network app-net \
mysql
应用:
bash
docker run \
--network app-net \
backend
然后:
代码连接:
properties
MYSQL_HOST=mysql
不需要写 IP。
九、Docker Compose 企业实践
实际项目:
不会启动:
docker run mysql
docker run redis
docker run nginx
而是:
docker-compose.yml
例如:
yaml
version: "3"
services:
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: 123456
volumes:
- mysql-data:/var/lib/mysql
redis:
image: redis
nginx:
image: nginx
ports:
- 80:80
volumes:
mysql-data:
启动:
bash
docker compose up -d
停止:
bash
docker compose down
十、生产环境 Docker 优化
1. 不使用 root 用户
Dockerfile:
dockerfile
USER app
提高安全性。
2. 健康检查
dockerfile
HEALTHCHECK CMD curl http://localhost
Docker 自动判断:
服务是否正常。
3. 日志管理
不要:
日志写文件
无限增长
推荐:
stdout
↓
Docker logging
↓
ELK
4. 固定版本
不要:
yaml
mysql:latest
生产:
yaml
mysql:8.0.36
避免升级导致故障。
十一、Docker 常见排查命令
查看日志
bash
docker logs -f app
查看资源
bash
docker stats
查看详细信息
bash
docker inspect app
查看进程
bash
docker top app
进入容器
bash
docker exec -it app sh
十二、Docker 与 Kubernetes 的关系
Docker:
负责:
运行一个容器
Kubernetes:
负责:
管理大量 Docker 容器
例如:
100 台服务器:
1000 个容器
Kubernetes 自动:
- 创建
- 删除
- 扩容
- 故障恢复
关系:
Docker
↓
Container
↓
Kubernetes
↓
云原生平台
十三、Docker 学习路线
第一阶段
掌握:
docker run
docker ps
docker images
docker logs
docker exec
第二阶段
学习:
Dockerfile
Volume
Network
Compose
第三阶段
深入:
Namespace
Cgroups
镜像优化
安全
CI/CD
Kubernetes
总结
Docker 不只是一个部署工具。
它改变了软件交付方式:
以前:
代码
↓
配置环境
↓
部署
↓
解决环境问题
现在:
代码
↓
Docker Image
↓
任何服务器运行
对于后端开发者:
Java、Go、Python、Node.js、AI 服务部署,
Docker 已经成为现代工程体系的重要基础。
作者:王仕宇 JavaPub