镜像仓库是容器生态系统的核心组件。
🏛️ 什么是镜像仓库?
镜像仓库 是专门存储、管理和分发 Docker/OCI 镜像的集中式服务。
类比理解
| 概念 | 类比 | 说明 |
|---|---|---|
| 镜像 | 软件安装包(如 .deb, .rpm) |
应用的打包格式 |
| 镜像仓库 | 应用商店(如 Ubuntu APT, npm, PyPI) | 存储和分发安装包的地方 |
| Docker Hub | Docker 的"官方应用商店" | 默认的公共仓库 |
📊 镜像仓库的架构
1. 核心组件
┌─────────────────────────────────────────┐
│ Docker Client │
│ docker pull/push/login/logout │
└───────────────┬─────────────────────────┘
│ HTTPS/API
┌───────────────▼─────────────────────────┐
│ Registry Server │
│ ┌─────────────────────────────────┐ │
│ │ Authentication & Authorization │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Image Storage (Blobs) │ │
│ │ • Layers (.tar.gz) │ │
│ │ • Manifests (JSON) │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Catalog & Search API │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
2. 镜像的存储结构
bash
# 镜像在仓库中的存储方式
registry.example.com/
├── library/ # 官方镜像组织
│ ├── nginx/
│ │ ├── latest → manifest.json
│ │ ├── 1.25 → manifest.json
│ │ └── alpine → manifest.json
│ └── ubuntu/
│ ├── 22.04 → manifest.json
│ └── jammy → manifest.json
└── mycompany/ # 个人/组织镜像
├── backend/
│ └── v1.2.3 → manifest.json
└── frontend/
└── latest → manifest.json
🌐 主要的镜像仓库类型
1. 公共仓库
| 仓库 | 特点 | URL |
|---|---|---|
| Docker Hub | 默认公共仓库,官方+社区镜像 | docker.io |
| GitHub Container Registry | 与GitHub集成,免费私有仓库 | ghcr.io |
| Google Container Registry | Google Cloud集成 | gcr.io |
| Amazon ECR | AWS集成,安全性高 | .dkr.ecr.region.amazonaws.com |
| Azure Container Registry | Azure云集成 | .azurecr.io |
2. 私有/自建仓库
| 方案 | 特点 |
|---|---|
| Docker Registry | 官方开源,轻量简单 |
| Harbor | 企业级,带UI、扫描、复制等 |
| Quay.io | RedHat企业方案 |
| Nexus Repository | 通用制品仓库,支持多种格式 |
🔧 实际操作命令
1. 拉取镜像(从仓库到本地)
bash
# 从Docker Hub拉取
$ docker pull nginx:latest
# 等价于
$ docker pull docker.io/library/nginx:latest
# 从其他仓库拉取
$ docker pull ghcr.io/username/app:latest
$ docker pull gcr.io/google-containers/busybox
2. 推送镜像(从本地到仓库)
bash
# 1. 标记镜像(添加仓库前缀)
$ docker tag myapp:latest myregistry.com/myteam/myapp:v1.0
# 2. 登录仓库
$ docker login myregistry.com
Username: admin
Password: ******
# 3. 推送
$ docker push myregistry.com/myteam/myapp:v1.0
3. 查看仓库中的镜像
bash
# Docker Hub搜索
$ docker search nginx
# 查看本地已拉取的镜像
$ docker images
# 查看镜像的仓库来源
$ docker image inspect nginx --format='{{.RepoTags}}'
🛡️ 仓库的安全机制
1. 认证(Authentication)
bash
# 登录到不同仓库
$ docker login docker.io
$ docker login ghcr.io -u username -p token
$ echo $GITHUB_TOKEN | docker login ghcr.io -u username --password-stdin
2. 镜像签名与验证
bash
# 使用Docker Content Trust (DCT)
$ export DOCKER_CONTENT_TRUST=1
$ docker pull nginx:latest # 会自动验证签名
3. 漏洞扫描
现代企业级仓库(如Harbor)提供:
- 自动CVE漏洞扫描
- 镜像签名验证
- 策略合规检查
📁 镜像在仓库中的实际存储
OCI 分发规范结构
registry.example.com/v2/
├── _catalog # 所有仓库列表
├── <repository-name>/ # 每个仓库
│ ├── tags/list # 该仓库的所有标签
│ ├── manifests/ # 清单文件
│ │ └── <tag> # 每个标签对应的清单
│ └── blobs/ # 实际的层文件
│ ├── sha256:abc123... # 镜像层(tar.gz压缩)
│ ├── sha256:def456... # 配置层
│ └── sha256:7890ab... # 另一个层
查看仓库API(示例)
bash
# 列出某个仓库的所有标签
$ curl https://registry.hub.docker.com/v2/repositories/library/nginx/tags/
# 获取某个镜像的清单
$ curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
https://registry.hub.docker.com/v2/library/nginx/manifests/latest
🏢 企业级仓库实践
1. 镜像命名规范
bash
# 推荐格式
<registry>/<project>/<component>:<version>-<environment>
# 示例
harbor.mycompany.com/devops/backend:1.5.0-prod
harbor.mycompany.com/apps/frontend:2.1.0-staging
2. 多环境仓库策略
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 开发仓库 │───▶│ 测试仓库 │───▶│ 生产仓库 │
│ harbor-dev │ │ harbor-qa │ │ harbor-prod │
└─────────────┘ └─────────────┘ └─────────────┘
↑ ↑ ↑
开发者推送 测试通过 生产发布
3. 镜像生命周期管理
- 保留策略:自动清理旧镜像
- 不可变标签:生产镜像一旦推送永不修改
- 漏洞阻断:有高危漏洞的镜像禁止部署
🚀 最佳实践建议
1. 仓库选择
yaml
# 个人/小团队:GitHub Container Registry(免费私有)
# 初创公司:Docker Hub付费计划或自建Harbor
# 企业:Harbor + 多集群复制
2. 镜像标签策略
bash
# 避免使用 latest(不明确)
# 使用语义化版本
myapp:1.2.3
myapp:1.2.3-alpine
myapp:1.2.3-20240115 # 带日期
# Git commit作为标签
myapp:git-a1b2c3d
3. 性能优化
bash
# 使用 registry-mirror 加速
$ dockerd --registry-mirror=https://mirror.gcr.io
# 在Kubernetes中使用 ImagePullSecrets
apiVersion: v1
kind: Secret
metadata:
name: regcred
data:
.dockerconfigjson: <base64-encoded-auth>
💡 关键理解点
- 仓库 ≠ 镜像:仓库是存储服务,镜像是存储内容
- 分层存储:相同的层只存储一次,多个镜像共享
- 拉取优化:只拉取本地没有的层
- 缓存机制:本地会缓存已拉取的层
- 标准接口:所有仓库都遵循OCI分发规范
镜像仓库是容器编排的基石,没有可靠的镜像仓库,就不可能有稳定的容器化部署。