Docker私有仓库

一、Docker Registry概述

1.1 Registry简介

1.1.1 什么是Docker Registry

定义:

Docker Registry = Docker镜像仓库
就像: 存放集装箱的专用仓库

核心功能:
├─ 存储Docker镜像
├─ 分发镜像到客户端
├─ 版本管理
├─ 访问控制
└─ 镜像同步

Registry类型:
├─ Docker Hub: 公共仓库
├─ Docker Registry: 私有仓库
├─ Harbor: 企业级仓库
└─ 其他: Quay, Nexus等

东巴文理解:

镜像仓库对比:
┌──────────────────┬──────────────┬──────────────┐
│     特性         │  公共仓库     │   私有仓库    │
├──────────────────┼──────────────┼──────────────┤
│  访问权限        │ 公开         │ 私有         │
│  网络速度        │ 较慢         │ 快速         │
│  安全性          │ 一般         │ 高           │
│  成本            │ 免费         │ 自建成本     │
│  适用场景        │ 开源项目      │ 企业内部     │
└──────────────────┴──────────────┴──────────────┘

为什么需要私有仓库:
├─ 网络速度: 内网访问更快
├─ 安全性: 镜像不外泄
├─ 成本: 节省带宽成本
├─ 合规: 满足合规要求
└─ 自定义: 灵活配置

1.1.2 Registry架构

架构图:

┌─────────────────────────────────────────┐
│         Docker Registry架构              │
├─────────────────────────────────────────┤
│                                         │
│  ┌─────────────────────────────────┐   │
│  │   Docker Client                 │   │
│  │   (docker push/pull)            │   │
│  └──────────────┬──────────────────┘   │
│                 │                       │
│                 ↓                       │
│  ┌─────────────────────────────────┐   │
│  │   Registry API                  │   │
│  │   (HTTP/HTTPS)                  │   │
│  └──────────────┬──────────────────┘   │
│                 │                       │
│                 ↓                       │
│  ┌─────────────────────────────────┐   │
│  │   Storage Backend               │   │
│  │   ├─ Filesystem (本地)          │   │
│  │   ├─ S3 (AWS)                   │   │
│  │   ├─ Azure Blob                 │   │
│  │   └─ GCS (Google)               │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

1.2 Registry版本

1.2.1 版本对比

版本说明:

Registry V1:
├─ 已废弃
├─ 性能较差
└─ 不推荐使用

Registry V2:
├─ 当前版本
├─ 性能优秀
├─ 安全性高
├─ 支持多种存储后端
└─ 推荐使用

特性对比:
┌──────────────────┬──────────────┬──────────────┐
│     特性         │   V1         │     V2       │
├──────────────────┼──────────────┼──────────────┤
│  性能            │ 一般         │ 优秀         │
│  安全性          │ 低           │ 高           │
│  存储后端        │ 单一         │ 多种         │
│  并发性能        │ 差           │ 好           │
│  镜像格式        │ 图层         │ 清单         │
└──────────────────┴──────────────┴──────────────┘

二、搭建Registry

2.1 快速搭建

2.1.1 基本搭建

启动Registry容器:

# 启动Registry容器
docker run -d \
  --name registry \
  -p 5000:5000 \
  -v /data/registry:/var/lib/registry \
  --restart=always \
  registry:2

# 查看容器状态
docker ps | grep registry

# 输出
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                    NAMES
a1b2c3d4e5f6   registry:2   "/entrypoint.sh /etc…"   5 seconds ago   Up 4 seconds   0.0.0.0:5000->5000/tcp   registry

验证Registry:

# 查看Registry状态
curl http://localhost:5000/v2/

# 输出
{}

# 查看仓库列表
curl http://localhost:5000/v2/_catalog

# 输出
{"repositories":[]}

2.1.2 使用Registry

推送镜像:

# 拉取测试镜像
docker pull nginx:latest

# 标记镜像
docker tag nginx:latest localhost:5000/mynginx:latest

# 推送镜像
docker push localhost:5000/mynginx:latest

# 输出
The push refers to repository [localhost:5000/mynginx]
a1b2c3d4e5f6: Pushed
latest: digest: sha256:123456... size: 1362

拉取镜像:

# 删除本地镜像
docker rmi nginx:latest
docker rmi localhost:5000/mynginx:latest

# 从私有仓库拉取
docker pull localhost:5000/mynginx:latest

# 查看镜像
docker images | grep mynginx

# 输出
localhost:5000/mynginx   latest    a1b2c3d4e5f6   2 weeks ago    142MB

2.2 Docker Compose部署

2.2.1 Compose配置

docker-compose.yml:

version: '3.8'

services:
  registry:
    image: registry:2
    container_name: registry
    restart: always
    ports:
      - "5000:5000"
    environment:
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
    volumes:
      - registry_data:/var/lib/registry
      - ./config:/etc/docker/registry
      - ./auth:/auth
    networks:
      - registry-net

volumes:
  registry_data:

networks:
  registry-net:

启动服务:

# 启动Registry
docker compose up -d

# 查看日志
docker compose logs -f registry

# 查看服务状态
docker compose ps

2.3 配置文件详解

2.3.1 Registry配置

config.yml:

version: 0.1
log:
  level: info
  formatter: text
  fields:
    service: registry
    environment: production

storage:
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
  cache:
    blobdescriptor: inmemory
  maintenance:
    uploadpurging:
      enabled: true
      age: 168h
      interval: 24h
      dryrun: false

http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
  tls:
    certificate: /etc/docker/registry/ssl/registry.crt
    key: /etc/docker/registry/ssl/registry.key

auth:
  htpasswd:
    realm: Registry Realm
    path: /auth/htpasswd

notifications:
  endpoints:
    - name: listener
      url: http://localhost:5003/callback
      headers:
        Authorization: [Bearer <token>]
      timeout: 500ms
      threshold: 5
      backoff: 1s

配置说明:

配置项说明:
├─ log: 日志配置
│   ├─ level: 日志级别
│   ├─ formatter: 日志格式
│   └─ fields: 日志字段
│
├─ storage: 存储配置
│   ├─ filesystem: 本地文件系统
│   ├─ delete: 删除功能
│   ├─ cache: 缓存配置
│   └─ maintenance: 维护配置
│
├─ http: HTTP配置
│   ├─ addr: 监听地址
│   ├─ headers: HTTP头
│   └─ tls: TLS配置
│
├─ auth: 认证配置
│   └─ htpasswd: 密码文件认证
│
└─ notifications: 通知配置
    └─ endpoints: 通知端点

三、安全配置

3.1 TLS/SSL配置

3.1.1 生成证书

生成自签名证书:

# 创建证书目录
mkdir -p /data/registry/ssl

# 生成私钥
openssl genrsa -out /data/registry/ssl/registry.key 2048

# 生成证书
openssl req -new -x509 \
  -key /data/registry/ssl/registry.key \
  -out /data/registry/ssl/registry.crt \
  -days 365 \
  -subj /CN=registry.example.com

# 查看证书
openssl x509 -in /data/registry/ssl/registry.crt -text -noout

使用CA证书:

# 创建CA私钥
openssl genrsa -out ca.key 2048

# 创建CA证书
openssl req -new -x509 -days 365 -key ca.key -out ca.crt

# 创建服务器私钥
openssl genrsa -out registry.key 2048

# 创建证书签名请求
openssl req -new -key registry.key -out registry.csr

# 使用CA签名证书
openssl x509 -req -days 365 \
  -in registry.csr \
  -CA ca.crt -CAkey ca.key \
  -CAcreateserial \
  -out registry.crt

3.1.2 配置HTTPS

Registry配置:

# config.yml
http:
  addr: :5000
  tls:
    certificate: /etc/docker/registry/ssl/registry.crt
    key: /etc/docker/registry/ssl/registry.key

Docker Compose配置:

version: '3.8'

services:
  registry:
    image: registry:2
    ports:
      - "5000:5000"
    volumes:
      - registry_data:/var/lib/registry
      - ./ssl:/etc/docker/registry/ssl
      - ./config:/etc/docker/registry
    environment:
      REGISTRY_HTTP_TLS_CERTIFICATE: /etc/docker/registry/ssl/registry.crt
      REGISTRY_HTTP_TLS_KEY: /etc/docker/registry/ssl/registry.key

volumes:
  registry_data:

客户端配置:

# 信任自签名证书
# 方法1: 复制证书到Docker目录
mkdir -p /etc/docker/certs.d/registry.example.com:5000
cp registry.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt

# 方法2: 添加到系统信任列表
cp registry.crt /usr/local/share/ca-certificates/registry.crt
update-ca-certificates

# 重启Docker
systemctl restart docker

# 测试HTTPS
curl -k https://registry.example.com:5000/v2/

3.2 认证配置

3.2.1 基本认证

创建密码文件:

# 安装htpasswd工具
apt-get install apache2-utils  # Ubuntu/Debian
yum install httpd-tools        # CentOS/RHEL

# 创建密码文件
htpasswd -c /data/registry/auth/htpasswd admin

# 输入密码
New password: 
Re-type new password: 
Adding password for user admin

# 添加更多用户
htpasswd /data/registry/auth/htpasswd user1

Registry配置:

# config.yml
auth:
  htpasswd:
    realm: Registry Realm
    path: /auth/htpasswd

Docker Compose配置:

version: '3.8'

services:
  registry:
    image: registry:2
    ports:
      - "5000:5000"
    volumes:
      - registry_data:/var/lib/registry
      - ./auth:/auth
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd

volumes:
  registry_data:

使用认证:

# 登录Registry
docker login registry.example.com:5000

# 输入用户名和密码
Username: admin
Password: 
Login Succeeded

# 推送镜像
docker push registry.example.com:5000/mynginx:latest

# 拉取镜像
docker pull registry.example.com:5000/mynginx:latest

# 登出
docker logout registry.example.com:5000

3.2.2 Token认证

Token认证配置:

# config.yml
auth:
  token:
    realm: https://auth.example.com/auth
    service: registry.example.com
    issuer: Auth Service
    rootcertbundle: /etc/docker/registry/ssl/auth.crt

说明:

Token认证流程:
├─ 客户端请求Registry
├─ Registry返回401,要求认证
├─ 客户端向认证服务请求Token
├─ 认证服务验证身份,返回Token
├─ 客户端携带Token访问Registry
└─ Registry验证Token,允许访问

优势:
✅ 集中认证管理
✅ 支持多种认证方式
✅ 细粒度权限控制
✅ 支持单点登录

四、镜像管理

4.1 镜像操作

4.1.1 查看镜像

查看仓库列表:

# 查看所有仓库
curl -u admin:password http://localhost:5000/v2/_catalog

# 输出
{"repositories":["mynginx","myapp","mysql"]}

# 查看镜像标签
curl -u admin:password http://localhost:5000/v2/mynginx/tags/list

# 输出
{"name":"mynginx","tags":["latest","v1.0","v1.1"]}

查看镜像详情:

# 查看镜像manifest
curl -u admin:password \
  -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  http://localhost:5000/v2/mynginx/manifests/latest

# 输出
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 7023,
      "digest": "sha256:b5b2b2b..."
   },
   "layers": [...]
}

4.1.2 删除镜像

启用删除功能:

# config.yml
storage:
  delete:
    enabled: true

删除镜像:

# 1. 获取镜像digest
DIGEST=$(curl -u admin:password \
  -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  -I http://localhost:5000/v2/mynginx/manifests/latest \
  2>&1 | grep Docker-Content-Digest | awk '{print $2}')

# 2. 删除镜像
curl -u admin:password -X DELETE \
  http://localhost:5000/v2/mynginx/manifests/$DIGEST

# 3. 运行垃圾回收
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml

# 输出
mynginx
mynginx: marking manifest sha256:123456...
mynginx: marking blob sha256:abcdef...
...

4.2 镜像同步

4.2.1 镜像迁移

从Docker Hub迁移:

# 拉取镜像
docker pull nginx:latest

# 标记镜像
docker tag nginx:latest registry.example.com:5000/nginx:latest

# 推送到私有仓库
docker push registry.example.com:5000/nginx:latest

批量迁移脚本:

#!/bin/bash
# migrate-images.sh

# 镜像列表
images=(
  "nginx:latest"
  "mysql:5.7"
  "redis:alpine"
  "python:3.9"
)

# 私有仓库地址
REGISTRY="registry.example.com:5000"

# 迁移镜像
for image in "${images[@]}"; do
  echo "Migrating $image..."
  
  # 拉取镜像
  docker pull $image
  
  # 标记镜像
  docker tag $image $REGISTRY/$image
  
  # 推送镜像
  docker push $REGISTRY/$image
  
  echo "Migrated $image successfully"
done

echo "Migration completed!"

4.2.2 仓库间同步

使用docker-retag:

# 安装docker-retag
go get github.com/jessfraz/docker-retag

# 同步镜像
docker-retag \
  -s source-registry.com:5000 \
  -d dest-registry.com:5000 \
  -i "nginx,mysql,redis"

使用skopeo:

# 安装skopeo
apt-get install skopeo  # Ubuntu/Debian
yum install skopeo      # CentOS/RHEL

# 同步镜像
skopeo copy \
  docker://source-registry.com:5000/nginx:latest \
  docker://dest-registry.com:5000/nginx:latest

# 批量同步
skopeo sync \
  --src docker \
  --dest docker \
  source-registry.com:5000 \
  dest-registry.com:5000

五、高级配置

5.1 存储后端配置

5.1.1 本地文件系统

配置示例:

# config.yml
storage:
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
  cache:
    blobdescriptor: inmemory

5.1.2 AWS S3

S3配置:

# config.yml
storage:
  s3:
    accesskey: AWS_ACCESS_KEY
    secretkey: AWS_SECRET_KEY
    region: us-west-1
    bucket: my-registry-bucket
    encrypt: true
    secure: true
    v4auth: true
    chunksize: 5242880
    rootdirectory: /registry

环境变量配置:

version: '3.8'

services:
  registry:
    image: registry:2
    environment:
      REGISTRY_STORAGE: s3
      REGISTRY_STORAGE_S3_ACCESSKEY: AWS_ACCESS_KEY
      REGISTRY_STORAGE_S3_SECRETKEY: AWS_SECRET_KEY
      REGISTRY_STORAGE_S3_REGION: us-west-1
      REGISTRY_STORAGE_S3_BUCKET: my-registry-bucket

5.1.3 Azure Blob Storage

Azure配置:

# config.yml
storage:
  azure:
    accountname: myaccount
    accountkey: mykey
    container: mycontainer
    realm: core.windows.net

5.2 通知配置

5.2.1 Webhook通知

配置示例:

# config.yml
notifications:
  endpoints:
    - name: webhook-listener
      disabled: false
      url: https://webhook.example.com/callback
      headers:
        Authorization: [Bearer mytoken]
      timeout: 500ms
      threshold: 5
      backoff: 1s
      ignoredmediatypes:
        - application/octet-stream

Webhook事件:

事件类型:
├─ push: 镜像推送
├─ pull: 镜像拉取
├─ mount: 镜像挂载
├─ delete: 镜像删除
└─ tag: 标签操作

事件数据:
{
  "id": "asdflkj...",
  "timestamp": "2024-01-01T00:00:00Z",
  "action": "push",
  "target": {
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "size": 7023,
    "digest": "sha256:b5b2b2b...",
    "length": 7023,
    "repository": "mynginx",
    "tag": "latest"
  },
  "request": {
    "id": "asdfasdf...",
    "addr": "192.168.1.100:12345",
    "host": "registry.example.com:5000",
    "method": "PUT",
    "useragent": "docker/20.10.0"
  },
  "actor": {
    "name": "admin"
  }
}

六、Harbor企业级仓库

6.1 Harbor简介

6.1.1 Harbor特点

Harbor优势:

Harbor = 企业级Docker Registry
就像: 功能齐全的专业仓储中心

核心特性:
├─ 基于角色的访问控制(RBAC)
├─ 镜像漏洞扫描
├─ 镜像签名验证
├─ 镜像复制
├─ 图形化管理界面
├─ 审计日志
├─ 垃圾回收
└─ Helm Chart支持

与Registry对比:
┌──────────────────┬──────────────┬──────────────┐
│     特性         │  Registry    │   Harbor     │
├──────────────────┼──────────────┼──────────────┤
│  Web界面         │ 无           │ 有           │
│  认证方式        │ 简单         │ 多种         │
│  权限管理        │ 基础         │ RBAC         │
│  镜像扫描        │ 无           │ 有           │
│  镜像复制        │ 无           │ 有           │
│  审计日志        │ 无           │ 有           │
└──────────────────┴──────────────┴──────────────┘

6.2 Harbor安装

6.2.1 下载安装

下载Harbor:

# 下载Harbor离线安装包
wget https://github.com/goharbor/harbor/releases/download/v2.5.0/harbor-offline-installer-v2.5.0.tgz

# 解压
tar xzf harbor-offline-installer-v2.5.0.tgz

# 进入目录
cd harbor

配置Harbor:

# 复制配置文件
cp harbor.yml.tmpl harbor.yml

# 编辑配置文件
vim harbor.yml

# 主要配置
hostname: harbor.example.com
http:
  port: 80
https:
  port: 443
  certificate: /data/ssl/harbor.crt
  private_key: /data/ssl/harbor.key
harbor_admin_password: Harbor12345
database:
  password: root123
data_volume: /data/harbor

安装Harbor:

# 安装
./install.sh

# 输出
[Step 0]: checking if docker is installed ...
[Step 1]: checking docker-compose is installed ...
[Step 2]: loading Harbor images ...
[Step 3]: preparing environment ...
[Step 4]: preparing harbor configs ...
[Step 5]: starting Harbor ...
✔ ----Harbor has been installed and started successfully.----

6.2.2 访问Harbor

访问Web界面:

URL: https://harbor.example.com
用户名: admin
密码: Harbor12345

功能:
├─ 项目管理
├─ 镜像管理
├─ 用户管理
├─ 日志审计
├─ 系统设置
└─ 垃圾回收

Docker客户端配置:

# 添加Harbor到Docker信任列表
mkdir -p /etc/docker/certs.d/harbor.example.com
cp harbor.crt /etc/docker/certs.d/harbor.example.com/ca.crt

# 重启Docker
systemctl restart docker

# 登录Harbor
docker login harbor.example.com

# 推送镜像
docker tag nginx:latest harbor.example.com/library/nginx:latest
docker push harbor.example.com/library/nginx:latest

# 拉取镜像
docker pull harbor.example.com/library/nginx:latest

七、本章小结

7.1 核心概念总结

7.1.1 Registry核心

Registry类型:
├─ Docker Hub: 公共仓库
├─ Docker Registry: 私有仓库
├─ Harbor: 企业级仓库
└─ 其他: Quay, Nexus

Registry配置:
├─ 存储配置: filesystem, s3, azure
├─ 安全配置: TLS, 认证
├─ 通知配置: webhook
└─ 维护配置: 垃圾回收

镜像操作:
├─ 推送: docker push
├─ 拉取: docker pull
├─ 查看: curl API
└─ 删除: DELETE + GC

7.1.2 安全配置

TLS/SSL配置:
├─ 生成证书: openssl
├─ 配置HTTPS: config.yml
└─ 客户端信任: ca.crt

认证配置:
├─ 基本认证: htpasswd
├─ Token认证: auth server
└─ Harbor: RBAC

访问控制:
├─ 用户管理
├─ 权限控制
├─ 项目隔离
└─ 审计日志

7.2 最佳实践

7.2.1 生产环境建议

安全配置:
✅ 启用HTTPS
✅ 配置认证
✅ 定期更新证书
✅ 启用审计日志

性能优化:
✅ 使用高性能存储
✅ 配置缓存
✅ 定期垃圾回收
✅ 监控资源使用

运维管理:
✅ 定期备份
✅ 监控告警
✅ 文档化流程
✅ 灾难恢复方案

7.2.2 Harbor使用建议

项目管理:
✅ 按团队创建项目
✅ 设置访问权限
✅ 配置镜像扫描
✅ 启用镜像签名

镜像管理:
✅ 规范镜像命名
✅ 定期清理无用镜像
✅ 配置镜像复制
✅ 启用漏洞扫描

用户管理:
✅ 使用RBAC
✅ 定期审计用户
✅ 配置LDAP/AD
✅ 启用双因素认证

7.3 下一章预告

下一章: Docker安全

将学习:

  • 🔐 容器安全基础
  • 🛡️ 镜像安全
  • 🔒 网络安全
  • 🚨 安全最佳实践

📝 练习题

基础题

  1. 搭建Registry: 使用Docker命令快速搭建一个Registry,推送和拉取一个nginx镜像。

  2. 基本认证: 为Registry配置基本认证,创建用户并测试登录。

  3. HTTPS配置: 为Registry配置HTTPS,生成自签名证书并配置客户端信任。

进阶题

  1. Docker Compose部署: 使用Docker Compose部署一个完整的Registry,包含认证、HTTPS和持久化存储。

  2. 镜像管理: 编写脚本批量迁移Docker Hub的镜像到私有仓库。

  3. Harbor安装: 安装Harbor企业级仓库,配置项目、用户和权限。

实践题

  1. 完整Registry方案: 设计一个生产环境的Registry方案,要求:

    • 高可用部署
    • HTTPS安全访问
    • 用户认证和权限管理
    • 镜像扫描
    • 审计日志
    • 备份恢复
    • 监控告警
  2. 多仓库同步: 设计一个多仓库镜像同步方案,实现:

    • 主从仓库架构
    • 自动同步策略
    • 故障切换
    • 数据一致性保证