什么是镜像仓库(Registry)
镜像仓库是存储和分发 Docker 镜像的服务。它解决了镜像的共享和分发问题:你在本机构建的镜像,通过 Registry 可以被世界上任何地方的机器拉取和运行。
- Registry 镜像仓库服务本身,可以是 Docker Hub、ghcr.io、私有服务器等。
-
Repository
仓库中的一个命名空间,存储同一应用的所有版本。如
nginx、username/myapp。 -
Tag
Repository 中的具体版本标识符,如
1.25、latest、alpine。
完整镜像引用格式:
# registry/namespace/repository:tag
docker.io/library/nginx:1.25 # Docker Hub 官方镜像(简写:nginx:1.25)
docker.io/username/myapp:1.0 # Docker Hub 个人镜像
ghcr.io/org/myapp:main # GitHub Container Registry
registry.aliyuncs.com/ns/myapp:v1 # 阿里云镜像仓库
192.168.1.100:5000/myapp:latest # 自建私有仓库
Docker Hub
Docker Hub(hub.docker.com)是默认的公共 Registry,提供:
- 官方镜像(Official Images):nginx、postgres、node、python 等,由 Docker 官方维护,经过安全审查
- 验证发布者(Verified Publishers):软件厂商官方镜像(如 MongoDB、Redis 官方)
- 个人/组织镜像:任何用户可免费发布公开镜像
- Rate Limit:免费账户每6小时可匿名拉取 100 次(登录后 200 次);付费账户无限制
推送镜像到 Docker Hub
# 1. 登录 Docker Hub
docker login
# 输入用户名和密码(或 Token)
# 2. 为镜像打标签(命名规则:username/repo:tag)
docker tag myapp:1.0 yourusername/myapp:1.0
docker tag myapp:1.0 yourusername/myapp:latest
# 3. 推送镜像
docker push yourusername/myapp:1.0
docker push yourusername/myapp:latest
# 4. 从任何机器拉取
docker pull yourusername/myapp:1.0
使用 Access Token 代替密码 — 在 Docker Hub Settings → Security → New Access Token 中创建访问令牌,将令牌(而非账号密码)用于 CI/CD 环境,可以精细控制权限(读/写/删),并随时撤销。
GitHub Container Registry(ghcr.io)
GitHub 提供的容器镜像服务,与 GitHub 生态深度集成:
- 免费存储公开镜像,私有镜像按存储量计费
- 可直接用 GitHub Actions 中的
GITHUB_TOKEN认证,无需额外配置 - 镜像与代码仓库关联,可在仓库 Packages 页面查看
- 支持细粒度权限管理
# 使用 GitHub Personal Access Token 登录
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# 推送到 ghcr.io
docker tag myapp:1.0 ghcr.io/your-org/myapp:1.0
docker push ghcr.io/your-org/myapp:1.0
私有镜像仓库
为什么需要私有仓库
- 代码保密:镜像包含专有代码,不能公开
- 内网隔离:生产服务器不能访问公网,需要内网 Registry
- 访问速度:内网拉取速度远快于公网
- 合规要求:数据合规要求数据不出境
方案一:registry:2(官方简单方案)
# 启动一个私有 Registry(无认证,仅内网使用)
docker run -d \
--name private-registry \
-p 5000:5000 \
-v registry-data:/var/lib/registry \
--restart unless-stopped \
registry:2
# 推送到私有仓库
docker tag myapp:1.0 localhost:5000/myapp:1.0
docker push localhost:5000/myapp:1.0
# 允许 Docker 使用 HTTP(不安全,仅测试)
# 在 /etc/docker/daemon.json 中添加:
# { "insecure-registries": ["192.168.1.100:5000"] }
方案二:Harbor(企业级推荐)
Harbor 是 CNCF 毕业项目,是功能最完整的开源私有 Registry:
| 功能 | 说明 |
|---|---|
| 角色权限管理 | 项目级别的用户/组 RBAC,精细控制读/写/管理权限 |
| 漏洞扫描 | 集成 Trivy/Clair 自动扫描镜像 CVE,阻止有漏洞镜像部署 |
| 镜像签名 | 集成 Notary,确保镜像真实性 |
| 复制策略 | 跨 Registry 自动同步镜像(用于多机房/多云) |
| 配额管理 | 限制每个项目的存储空间 |
| Helm Chart 仓库 | 同时存储容器镜像和 Helm Chart |
| 审计日志 | 所有操作可追踪 |
# 用 Docker Compose 快速部署 Harbor
wget https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-online-installer-v2.9.0.tgz
tar xzf harbor-online-installer-v2.9.0.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml
# 编辑 harbor.yml:设置 hostname、HTTPS 证书、admin 密码等
sudo ./install.sh
镜像命名规范总结
# 格式:[registry[:port]/][namespace/]repository[:tag][@digest]
nginx # 简写:docker.io/library/nginx:latest
nginx:1.25 # 指定版本
ubuntu:22.04 # OS 镜像
node:18-alpine # 官方镜像变体
username/myapp:1.0 # Docker Hub 个人镜像
org/service-name:v2.3.1 # 组织镜像,语义化版本
ghcr.io/org/myapp:sha-abc123 # GitHub CR,Git SHA 标签
harbor.company.com/project/app:prod-20241201 # 私有仓库,日期标签
# 使用摘要(digest)确保完全不可变
nginx@sha256:a3e8e3c525c4b5c8e8e3c525...
国内加速:配置 Registry Mirror
在国内直接从 Docker Hub 拉取镜像速度很慢,可以配置镜像加速器:
Docker Desktop 配置
打开 Docker Desktop → Settings → Docker Engine,在 JSON 配置中添加:
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://<your-id>.mirror.aliyuncs.com"
]
}
Linux(Docker Engine)配置
# 编辑 /etc/docker/daemon.json
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://hub-mirror.c.163.com"
]
}
EOF
# 重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证配置
docker info | grep -A 5 "Registry Mirrors"
Docker Scout 深入:镜像安全可观测性
Docker Scout(Docker 27 内置)提供了超越简单 CVE 扫描的镜像安全可观测性。
# 快速查看镜像安全评分和概览
docker scout quickview nginx:1.27
# 查看所有 CVE(含 CVSS 评分、修复建议)
docker scout cves nginx:1.27
# 只显示有修复版本的漏洞(可以立即行动的)
docker scout cves --only-fixed nginx:1.27
# 对比两个版本的安全差异
docker scout compare nginx:1.26 --to nginx:1.27
# 查看镜像的软件物料清单(SBOM)
docker scout sbom nginx:1.27
# 检查镜像是否包含特定软件包
docker scout cves nginx:1.27 --format json | jq '.vulnerabilities[] | select(.packageName=="openssl")'
SBOM(软件物料清单) — Software Bill of Materials,列出镜像中所有软件组件和版本的清单,是供应链安全合规的重要工具。Docker Scout 可以自动从镜像生成 SBOM,并以 SPDX 或 CycloneDX 格式输出。
镜像签名:cosign 与 Docker 内容信任
镜像签名验证确保你部署的镜像确实来自可信来源,没有在传输过程中被篡改。
-
Docker Content Trust (DCT)
基于 TUF(The Update Framework)的签名系统,集成在 Docker CLI 中。设置
DOCKER_CONTENT_TRUST=1后,所有推送和拉取操作都需要签名验证。 - cosign Sigstore 项目的签名工具,现代方案,支持 OCI 规范。可以无需私钥,通过 OIDC(Google/GitHub 登录)进行无密钥签名(keyless signing),签名信息存储在透明日志(Rekor)中。
# === cosign 工作流 ===
# 生成密钥对(传统方式)
cosign generate-key-pair
# 签名镜像(签名以 OCI artifact 方式存储在同一仓库)
cosign sign --key cosign.key myregistry/myapp:1.0
# 验证签名
cosign verify \
--key cosign.pub \
myregistry/myapp:1.0
# 无密钥签名(通过 GitHub Actions OIDC)
# 在 GitHub Actions workflow 中:
# - uses: sigstore/cosign-installer@v3
# - run: cosign sign --yes ${{ env.IMAGE }}:${{ env.TAG }}
OCI 规范与镜像格式
了解 OCI(Open Container Initiative)规范有助于理解为什么不同工具(Docker、Podman、containerd)可以互操作。
- OCI Image Spec 定义了容器镜像的格式:镜像 manifest(清单文件,描述镜像层和配置)、镜像 config(容器运行时配置)、镜像层(tar.gz 格式的文件系统差异)。
- OCI Distribution Spec 定义了 Registry API,即如何推送和拉取镜像。所有兼容 OCI 的 Registry(Docker Hub、ghcr.io、ECR、Harbor)都遵循此规范。
- 多架构镜像(Multi-arch Image) 通过 manifest list(或 OCI image index)将多个不同 CPU 架构(amd64、arm64、arm/v7)的镜像聚合到同一个标签下。客户端拉取时自动选择匹配本机架构的镜像。
# 查看镜像的 manifest(包含所有架构)
docker manifest inspect nginx:1.27
# 构建并推送多架构镜像(需要 buildx)
docker buildx build \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
-t myapp:1.0 \
--push \
.
# 验证推送后的多架构 manifest
docker manifest inspect myapp:1.0
Apple Silicon(arm64)上构建 amd64 镜像 — 在 M1/M2/M3 Mac 上使用 --platform linux/amd64 构建会触发 QEMU 模拟,速度很慢(可能慢 5-10 倍)。建议在 CI 中使用 amd64 主机构建 amd64 镜像,或在 Mac 上为 arm64 构建,利用 GitHub Actions 的多平台 runner。
本章小结 — 选择合适的 Registry:开源项目用 Docker Hub 或 ghcr.io,企业私有部署用 Harbor。Docker Scout 提供 CVE 扫描和 SBOM 生成,是供应链安全的重要工具。cosign 实现镜像签名验证,防止供应链攻击。无论哪种方案,都要建立清晰的镜像命名和标签策略,确保镜像可追溯。