镜像分发与存储 #
镜像存储原理 #
分层存储架构 #
text
┌─────────────────────────────────────────────────────┐
│ 镜像分层存储 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Container Layer │ │
│ │ (可读写层) │ │
│ ├─────────────────────────────────────────────┤ │
│ │ Image Layer N │ │
│ │ (只读层) │ │
│ ├─────────────────────────────────────────────┤ │
│ │ Image Layer N-1 │ │
│ │ (只读层) │ │
│ ├─────────────────────────────────────────────┤ │
│ │ Image Layer 2 │ │
│ │ (只读层) │ │
│ ├─────────────────────────────────────────────┤ │
│ │ Image Layer 1 │ │
│ │ (只读层/基础层) │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘
存储驱动 #
| 驱动 | 说明 | 适用场景 |
|---|---|---|
| overlay2 | 默认推荐,性能最好 | 大多数Linux发行版 |
| aufs | 早期默认驱动 | Ubuntu 14.04及以下 |
| devicemapper | 块设备存储 | 企业级存储 |
| btrfs | 文件系统级存储 | 需要快照功能 |
| zfs | 高级文件系统 | 需要高级存储功能 |
查看存储驱动 #
bash
# 查看当前存储驱动
docker info | grep "Storage Driver"
# 查看存储驱动详情
docker info -f '{{.Driver}}'
配置存储驱动 #
json
// /etc/docker/daemon.json
{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
镜像存储位置 #
默认存储路径 #
bash
# Linux默认路径
/var/lib/docker/
# macOS默认路径
~/Library/Containers/com.docker.docker/Data/
# Windows默认路径
C:\ProgramData\Docker\
目录结构 #
text
/var/lib/docker/
├── aufs/ # AUFS存储驱动数据
├── containers/ # 容器数据
├── image/ # 镜像元数据
│ └── overlay2/
│ ├── distribution/
│ ├── imagedb/
│ │ ├── content/
│ │ └── metadata/
│ ├── layerdb/
│ └── repositories.json
├── overlay2/ # Overlay2存储驱动数据
│ ├── <layer-id>/
│ │ ├── diff/ # 层数据
│ │ ├── link # 层链接
│ │ ├── lower # 下层引用
│ │ └── merged/ # 合并视图
├── volumes/ # 数据卷
└── network/ # 网络配置
更改存储路径 #
json
// /etc/docker/daemon.json
{
"data-root": "/mnt/docker-data"
}
bash
# 重启Docker服务
sudo systemctl restart docker
镜像分发机制 #
Registry架构 #
text
┌─────────────────────────────────────────────────────┐
│ Registry 架构 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ Push/Pull ┌─────────────┐ │
│ │ Docker │ ──────────────→ │ Registry │ │
│ │ Client │ ←────────────── │ Server │ │
│ └─────────────┘ └──────┬──────┘ │
│ │ │
│ ↓ │
│ ┌─────────────┐ │
│ │ Storage │ │
│ │ Backend │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────┘
镜像推送流程 #
text
┌─────────────────────────────────────────────────────┐
│ 镜像推送流程 │
├─────────────────────────────────────────────────────┤
│ │
│ 1. 检查本地镜像 │
│ │ │
│ ↓ │
│ 2. 认证到Registry │
│ │ │
│ ↓ │
│ 3. 检查哪些层已存在 │
│ │ │
│ ↓ │
│ 4. 上传缺失的层 │
│ │ │
│ ↓ │
│ 5. 上传manifest │
│ │ │
│ ↓ │
│ 6. 完成推送 │
│ │
└─────────────────────────────────────────────────────┘
镜像拉取流程 #
text
┌─────────────────────────────────────────────────────┐
│ 镜像拉取流程 │
├─────────────────────────────────────────────────────┤
│ │
│ 1. 认证到Registry │
│ │ │
│ ↓ │
│ 2. 获取manifest │
│ │ │
│ ↓ │
│ 3. 解析manifest获取层列表 │
│ │ │
│ ↓ │
│ 4. 检查本地已有哪些层 │
│ │ │
│ ↓ │
│ 5. 下载缺失的层 │
│ │ │
│ ↓ │
│ 6. 组装镜像 │
│ │
└─────────────────────────────────────────────────────┘
镜像仓库操作 #
Docker Hub #
bash
# 登录Docker Hub
docker login
# 登出Docker Hub
docker logout
# 推送镜像到Docker Hub
docker tag myapp:v1.0 username/myapp:v1.0
docker push username/myapp:v1.0
# 拉取私有镜像
docker pull username/myapp:v1.0
私有仓库 #
bash
# 启动私有仓库
docker run -d -p 5000:5000 --name registry \
-v /data/registry:/var/lib/registry \
registry:2
# 推送镜像到私有仓库
docker tag myapp:v1.0 localhost:5000/myapp:v1.0
docker push localhost:5000/myapp:v1.0
# 拉取镜像
docker pull localhost:5000/myapp:v1.0
配置非HTTPS仓库 #
json
// /etc/docker/daemon.json
{
"insecure-registries": [
"localhost:5000",
"registry.example.com:5000"
]
}
镜像传输优化 #
镜像压缩 #
bash
# 导出压缩镜像
docker save myapp:v1.0 | gzip > myapp.tar.gz
# 导入压缩镜像
docker load < myapp.tar.gz
层共享 #
dockerfile
# 使用相同基础镜像实现层共享
FROM node:18-alpine
# 多个镜像共享相同的基础层
并行推送/拉取 #
bash
# 并行推送多个镜像
docker push myapp:v1.0 &
docker push myapp:v2.0 &
wait
# 使用skopeo并行操作
skopeo copy docker://myapp:v1.0 docker://registry.example.com/myapp:v1.0
镜像签名与验证 #
Docker Content Trust #
bash
# 启用内容信任
export DOCKER_CONTENT_TRUST=1
# 推送签名镜像
docker push myapp:v1.0
# 拉取签名镜像
docker pull myapp:v1.0
# 查看签名信息
docker trust inspect myapp:v1.0
# 禁用内容信任
export DOCKER_CONTENT_TRUST=0
签名密钥管理 #
bash
# 生成密钥
docker trust key generate mykey
# 添加签名者
docker trust signer add --key mykey.pub user myapp
# 移除签名者
docker trust signer remove user myapp
# 撤销签名
docker trust revoke myapp:v1.0
镜像安全扫描 #
docker scout #
bash
# 快速查看
docker scout quickview myapp:v1.0
# 查看CVE漏洞
docker scout cves myapp:v1.0
# 查看建议
docker scout recommendations myapp:v1.0
# 比较镜像
docker scout compare myapp:v1.0 myapp:v2.0
Trivy扫描 #
bash
# 安装trivy
brew install trivy
# 扫描镜像
trivy image myapp:v1.0
# 输出JSON格式
trivy image --format json --output results.json myapp:v1.0
# 只扫描高危漏洞
trivy image --severity HIGH,CRITICAL myapp:v1.0
镜像清理策略 #
自动清理 #
bash
# 清理悬空镜像
docker image prune -f
# 清理所有未使用镜像
docker image prune -a -f
# 设置过期时间
docker image prune -a --filter "until=168h"
# 完整清理
docker system prune -a --volumes
定时清理脚本 #
bash
#!/bin/bash
# clean-docker-images.sh
# 清理7天前的镜像
docker image prune -a --filter "until=168h" -f
# 清理停止的容器
docker container prune -f
# 清理未使用的网络
docker network prune -f
# 清理构建缓存
docker builder prune -f
echo "Cleanup completed at $(date)"
Cron定时任务 #
bash
# 编辑crontab
crontab -e
# 每天凌晨2点执行清理
0 2 * * * /path/to/clean-docker-images.sh >> /var/log/docker-cleanup.log 2>&1
镜像分发最佳实践 #
1. 使用语义化版本 #
bash
# 推荐的标签策略
myapp:1.0.0 # 具体版本
myapp:1.0 # 次版本
myapp:1 # 主版本
myapp:latest # 最新版本
myapp:1.0.0-alpine # 带变体标识
2. 多架构镜像 #
bash
# 创建多架构镜像
docker buildx build --platform linux/amd64,linux/arm64 \
-t myapp:v1.0 --push .
3. 镜像瘦身 #
dockerfile
# 使用alpine基础镜像
FROM alpine:3.18
# 多阶段构建
FROM builder AS build
FROM alpine:3.18
COPY --from=build /app /app
4. 使用镜像缓存 #
bash
# 利用远程镜像作为缓存
docker build --cache-from myapp:latest -t myapp:v1.0 .
小结 #
本节学习了Docker镜像的存储和分发:
- 镜像分层存储原理
- 存储驱动和存储位置
- 镜像分发机制
- 镜像仓库操作
- 镜像安全和清理
下一步 #
接下来,让我们学习 容器基础操作,了解Docker容器的基本管理方法。