Appearance
镜像仓库
镜像仓库负责保存、分发和管理镜像。Docker Hub 用来拉公共镜像,公司内部服务放到私有仓库(Harbor、云厂商镜像仓库或自建 registry)里。镜像仓库不是单纯的文件服务器——除了存镜像,还要处理认证、权限、标签、漏洞扫描、保留策略和审计记录。
仓库在链路里的位置
镜像加速源和镜像仓库不是一回事。registry-mirrors 解决的是从 Docker Hub 拉公共镜像慢的问题;Harbor、云厂商仓库解决的是内部镜像保存、权限、分发、审计和清理。
仓库类型
| 类型 | 说明 |
|---|---|
| Docker Hub | 公共镜像主要来源 |
| Harbor | 常见企业私有仓库,支持项目、权限、扫描、复制、垃圾回收 |
| 云厂商仓库 | 和云上 IAM、集群、镜像加速集成方便 |
| registry | Docker 官方轻量仓库,功能简单,适合实验 |
教学和小实验用 registry 够用,公司内部环境更偏向 Harbor——权限、项目隔离、清理策略和漏洞扫描这些能力后面都会用上。
登录、推送和拉取
bash
docker login registry.example.com # 输入用户名和密码或 token
docker tag demo-app:1.0 registry.example.com/ops/demo-app:1.0
docker push registry.example.com/ops/demo-app:1.0
docker pull registry.example.com/ops/demo-app:1.0镜像名里的 ops 通常对应仓库里的项目或命名空间。权限控制一般也按项目划分——应用、基础镜像、测试镜像分开,不全部塞进一个项目。
Harbor 部署
Harbor 常用 Docker Compose 部署。部署前准备好域名、证书、数据目录和配置文件。
目录规划:
text
/opt/harbor/
├── harbor.yml
├── common/
└── data/harbor.yml 里几个关键字段:
yaml
hostname: registry.example.com
https:
port: 443
certificate: /opt/harbor/certs/registry.example.com.crt
private_key: /opt/harbor/certs/registry.example.com.key
harbor_admin_password: change_this_password
database:
password: change_this_db_password
data_volume: /opt/harbor/data| 字段 | 说明 |
|---|---|
hostname | 客户端访问仓库的域名或地址 |
https | HTTPS 证书配置 |
harbor_admin_password | 初始管理员密码 |
database.password | Harbor 内置数据库密码 |
data_volume | 镜像和组件数据目录 |
安装:
bash
cd /opt/harbor
./prepare # 根据 harbor.yml 生成组件配置
./install.sh
docker compose ps生产环境通常使用 HTTPS。内网临时环境如果使用 HTTP,要明确 Docker daemon 的 insecure registry 配置范围——默认信任范围放得太大,后续迁移和审计都会麻烦。
客户端证书和 insecure registry
使用自签证书时,客户端要信任 Harbor 的 CA 证书:
bash
sudo mkdir -p /etc/docker/certs.d/registry.example.com
sudo cp registry.example.com.crt /etc/docker/certs.d/registry.example.com/ca.crt
sudo systemctl restart docker如果使用 HTTP 或自签证书又不配 CA,Docker 会报证书或协议错误。临时 insecure registry 配置写在 /etc/docker/daemon.json:
json
{
"insecure-registries": ["registry.example.com"]
}改完重启 Docker:
bash
sudo systemctl restart docker
docker info | grep -A3 "Insecure Registries"insecure registry 只适合受控内网临时使用。仓库账号和镜像内容经过不受信任的链路时,HTTP 非常危险。
项目和权限
Harbor 里的对象层级:
| 对象 | 说明 |
|---|---|
| Project | 项目空间,隔离镜像和权限 |
| Repository | 镜像仓库,如 ops/demo-app |
| Artifact | 某个镜像版本或 OCI artifact |
| Tag | 镜像标签 |
| Robot Account | 给 CI/CD 使用的机器人账号 |
CI/CD 推镜像适合用 Robot Account 而非个人管理员账号。机器人账号权限更容易收窄(只给某个项目的 push 权限),泄露后也方便单独吊销,不影响其他项目。
保留和清理策略
镜像仓库很容易被旧版本撑满。常见保留策略:
| 规则 | 示例 |
|---|---|
| 保留最近 N 个 | 每个仓库保留最近 20 个 release 标签 |
| 按前缀过滤 | 保留 prod-*,清理 dev-* |
| 保留不可变版本 | 正式发布版本不覆盖、不删除 |
| 按时间清理 | CI 临时标签自动过期 |
Harbor 删除 tag 后还要执行垃圾回收(GC)才会真正释放存储空间。清理策略先在测试项目验证,多环境共用仓库时,误删镜像会直接导致回滚失败。
镜像标签的不可变性
正式发布镜像不适合反复覆盖同一个标签。app:prod 每次都覆盖,运行节点上拉到的到底是哪个构建很难追溯。
更稳的标签方式:
text
registry.example.com/ops/demo-app:1.4.2
registry.example.com/ops/demo-app:20260522-1530-a1b2c3d部署系统可以额外维护"当前生产使用哪个版本"的映射,但镜像标签本身要可追溯。出现故障时知道当前容器用的是哪个构建,比"应该是最新版本"可靠得多。
常见排查
| 现象 | 检查方向 |
|---|---|
docker login 失败 | 用户名密码、机器人账号权限、证书 |
docker push denied | 项目权限、仓库是否设为只读 |
| 拉镜像超时 | 网络、DNS、代理、仓库服务状态 |
| 证书错误 | CA 是否放到 /etc/docker/certs.d/ |
| 磁盘满 | Harbor data 目录、垃圾回收是否执行、旧 tag 是否清理 |
排查仓库问题时先分清是客户端认证失败、TLS 失败、网络不通、还是仓库后端存储满。错误信息通常已经指向了方向,不要一上来就重启整套 Harbor。