Docker 作为现代应用开发和部署的事实标准,其核心思想源自集装箱运输理念。就像集装箱标准化了货物运输一样,Docker 标准化了软件交付流程。让我们深入剖析 Docker 的三大核心概念:
镜像本质上是一个只读模板,包含运行应用所需的一切:代码、运行时环境、系统工具、系统库和设置。你可以把它想象成游戏安装包——它包含了游戏运行所需的所有资源,但本身不会改变。
镜像采用分层存储机制,每一层都是对前一层的增量修改。这种设计带来两个关键优势:
实际操作中,我们常用 alpine(约5MB)、ubuntu(约72MB)等作为基础镜像。选择原则是:在满足需求的前提下,越小越好。例如:
bash复制# 查看镜像分层结构
docker history nginx:alpine
容器是镜像的运行实例,就像启动后的游戏进程。关键特性包括:
一个常见误区是认为容器就是轻量级虚拟机。实际上,容器本质上是受限制的进程,共享主机内核。这也是为什么Windows容器必须在Windows主机运行,Linux容器必须在Linux主机运行。
Docker Hub是默认的公共仓库,类似代码托管中的GitHub。企业通常会搭建私有仓库(如Harbor)来存储内部镜像。
镜像命名遵循[仓库地址]/用户名/镜像名:标签的格式。例如:
nginx:latest(官方镜像)registry.example.com/dev/backend:v1.2(私有仓库)提示:生产环境务必指定具体版本标签,避免使用latest可能导致的版本漂移问题
不同操作系统下的Docker实现差异较大:
Linux (推荐生产环境使用)
bash复制# Ubuntu示例
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo usermod -aG docker $USER # 避免每次sudo
macOS/Windows
国内用户通常会配置多个镜像源提高可用性:
json复制// /etc/docker/daemon.json
{
"registry-mirrors": [
"https://<你的ID>.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn"
],
"insecure-registries": ["私有仓库地址:端口"]
}
配置后需要重启服务:
bash复制sudo systemctl daemon-reload
sudo systemctl restart docker
验证配置生效:
bash复制docker info | grep Mirrors -A 2
典型工作流示例:
bash复制# 拉取指定版本(避免使用latest)
docker pull nginx:1.21-alpine
# 运行并暴露端口
docker run -d --name web -p 8080:80 \
-v ./html:/usr/share/nginx/html \
nginx:1.21-alpine
# 查看运行状态
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
关键参数解析:
-v:挂载卷实现数据持久化-p:端口映射格式为主机端口:容器端口--restart=always:设置自动重启策略日志查看
bash复制# 实时跟踪日志
docker logs -f --tail 100 web
# 按时间过滤
docker logs --since 2023-01-01T00:00:00 web
进入容器
bash复制# 使用bash交互(确保容器内有bash)
docker exec -it web bash
# 精简容器使用sh
docker exec -it web sh
资源监控
bash复制docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
以Python应用为例的优化Dockerfile:
dockerfile复制# 第一阶段:构建环境
FROM python:3.9 as builder
WORKDIR /app
COPY requirements.txt .
# 创建虚拟环境
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 第二阶段:运行环境
FROM python:3.9-slim
# 从builder复制虚拟环境
COPY --from=builder /opt/venv /opt/venv
WORKDIR /app
COPY . .
ENV PATH="/opt/venv/bin:$PATH"
CMD ["python", "app.py"]
优化点说明:
--no-cache-dir减少pip缓存合理利用缓存可以大幅加速构建:
bash复制# 强制不使用缓存
docker build --no-cache .
# 指定缓存来源
docker build --cache-from=myapp:latest .
缓存失效规则:
经验:将变化频率低的指令放在前面,如先COPY requirements.txt再安装依赖
卷(Volume)类型对比
| 类型 | 存储位置 | 生命周期 | 适用场景 |
|---|---|---|---|
| 匿名卷 | /var/lib/docker/volumes | 随容器删除 | 临时数据 |
| 命名卷 | /var/lib/docker/volumes | 独立管理 | 数据库文件 |
| 绑定挂载 | 主机指定路径 | 主机控制 | 开发环境 |
使用示例
bash复制# 创建命名卷
docker volume create db_data
# 使用卷
docker run -d -v db_data:/var/lib/mysql mysql:8.0
Docker提供多种网络驱动:
创建自定义网络:
bash复制docker network create --driver bridge \
--subnet 172.28.0.0/16 \
--gateway 172.28.5.1 \
my-net
dockerfile复制FROM alpine
RUN adduser -D appuser
USER appuser
bash复制docker run --read-only -v /tmp:/tmp alpine
bash复制docker run -it --cpus=".5" --memory="512m" alpine
Prometheus监控配置
dockerfile复制# 暴露监控端点
EXPOSE 9090
HEALTHCHECK --interval=30s CMD curl -f http://localhost:9090/health
ELK日志收集
bash复制docker run --log-driver=syslog \
--log-opt syslog-address=tcp://logserver:514 \
nginx
端口冲突
bash复制# 查找占用端口
sudo netstat -tulnp | grep 8080
# 查看容器映射
docker port web
存储空间不足
bash复制# 查看磁盘使用
docker system df
# 清理无用资源
docker system prune -a --volumes
调整存储驱动
bash复制# /etc/docker/daemon.json
{
"storage-driver": "overlay2"
}
优化容器启动速度
bash复制# 使用--init处理僵尸进程
docker run --init -d nginx
# 禁用不必要的设备
docker run --device-read-bps /dev/sda:1mb alpine
在实际生产环境中,我们通常会结合CI/CD流水线实现自动化构建部署。一个典型的流程是:代码提交触发镜像构建 -> 扫描镜像漏洞 -> 推送到仓库 -> 滚动更新服务。这需要配合Jenkins、GitLab CI等工具实现。