强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Podman 完全指南 / 12 - 镜像仓库

第 12 章 — 镜像仓库

12.1 镜像仓库概览

主流镜像仓库

仓库 类型 特点
Docker Hub 公共/私有 最大公共仓库,免费有限制
GitHub Container Registry (ghcr.io) 公共/私有 GitHub 深度集成
Red Hat Quay 私有 企业级,安全扫描
Harbor 私有 CNCF 项目,功能丰富
GitLab Container Registry 私有 GitLab 深度集成
AWS ECR 私有 AWS 原生
Azure ACR 私有 Azure 原生
Google Artifact Registry 私有 GCP 原生
Nexus Repository 私有 通用制品仓库
自建 Registry 私有 完全控制

镜像命名规范

完整镜像地址格式:

registry_host[:port]/[namespace/]repository[:tag|@digest]

示例:
├── docker.io/library/alpine:3.20              ← Docker Hub 官方镜像
├── docker.io/myuser/myapp:v1.0                ← Docker Hub 用户镜像
├── ghcr.io/owner/repo:latest                  ← GitHub Container Registry
├── quay.io/myorg/myapp:v2.0                   ← Red Hat Quay
├── registry.example.com/team/app:v1.2.3       ← 私有仓库
└── registry.example.com:5000/project/app:sha-abc123 ← 带端口的私有仓库

12.2 使用公共仓库

12.2.1 Docker Hub

# 注册账号后登录
podman login docker.io
# 输入用户名和密码

# 拉取镜像
podman pull docker.io/library/alpine:3.20

# 推送到 Docker Hub
podman tag myapp:v1.0 docker.io/myusername/myapp:v1.0
podman push docker.io/myusername/myapp:v1.0

# 登出
podman logout docker.io

12.2.2 GitHub Container Registry

# 使用 GitHub Personal Access Token 登录
echo $GITHUB_TOKEN | podman login ghcr.io -u USERNAME --password-stdin

# 推送到 GHCR
podman tag myapp:v1.0 ghcr.io/myorg/myapp:v1.0
podman push ghcr.io/myorg/myapp:v1.0

12.2.3 Quay.io

# 在 quay.io 创建 Robot Account(推荐用于 CI/CD)
# 登录
podman login quay.io

# 推送
podman tag myapp:v1.0 quay.io/myorg/myapp:v1.0
podman push quay.io/myorg/myapp:v1.0

12.3 搭建私有 Registry

12.3.1 基础 Registry(快速启动)

# 最简单的私有 Registry
podman run -d \
    --name registry \
    -p 5000:5000 \
    -v registry-data:/var/lib/registry:Z \
    --restart unless-stopped \
    registry:2

# 测试推送
podman tag alpine:3.20 localhost:5000/alpine:3.20
podman push localhost:5000/alpine:3.20

# 测试拉取
podman pull localhost:5000/alpine:3.20

# 列出仓库中的镜像
curl http://localhost:5000/v2/_catalog
# {"repositories":["alpine"]}

# 列出镜像的标签
curl http://localhost:5000/v2/alpine/tags/list
# {"name":"alpine","tags":["3.20"]}

12.3.2 带 TLS 的 Registry(生产环境)

# 生成自签名证书(或使用 Let's Encrypt)
mkdir -p certs

openssl req -newkey rsa:4096 -nodes -sha256 \
    -keyout certs/domain.key \
    -x509 -days 3650 \
    -out certs/domain.crt \
    -subj "/CN=registry.example.com" \
    -addext "subjectAltName=DNS:registry.example.com,IP:192.168.1.100"

# 启动带 TLS 的 Registry
podman run -d \
    --name registry \
    -p 443:443 \
    -v registry-data:/var/lib/registry:Z \
    -v $(pwd)/certs:/certs:ro,Z \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
    --restart unless-stopped \
    registry:2

# 客户端信任证书
sudo cp certs/domain.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
# Ubuntu: sudo cp certs/domain.crt /usr/local/share/ca-certificates/
#         sudo update-ca-certificates

# 测试
podman login registry.example.com
podman tag alpine:3.20 registry.example.com/alpine:3.20
podman push registry.example.com/alpine:3.20

12.3.3 带认证的 Registry

# 创建密码文件
mkdir -p auth
podman run --rm --entrypoint htpasswd \
    httpd:2 -Bbn admin secretpassword > auth/htpasswd

# 启动带认证的 Registry
podman run -d \
    --name registry \
    -p 443:443 \
    -v registry-data:/var/lib/registry:Z \
    -v $(pwd)/certs:/certs:ro,Z \
    -v $(pwd)/auth:/auth:ro,Z \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
    -e "REGISTRY_AUTH=htpasswd" \
    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
    -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
    --restart unless-stopped \
    registry:2

# 登录
podman login registry.example.com
# Username: admin
# Password: secretpassword

12.3.4 Podman 中的 Registry 配置

# /etc/containers/registries.conf — 全局配置

# 搜索仓库
[registries.search]
registries = ['registry.example.com', 'docker.io']

# 不可信仓库
[registries.block]
registries = []

# 镜像仓库配置
[[registry]]
prefix = "registry.example.com"
location = "registry.example.com"
insecure = false  # 是否允许 HTTP(不推荐)

# 镜像加速(Docker Hub)
[[registry]]
prefix = "docker.io"
location = "docker.io"

[[registry.mirror]]
location = "mirror.gcr.io"

12.4 Harbor 企业级 Registry

Harbor 是 CNCF 毕业项目,提供企业级的镜像仓库功能。

12.4.1 使用 Podman 部署 Harbor

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

# 复制配置模板
cp harbor.yml.tmpl harbor.yml

# 编辑配置
vim harbor.yml
# harbor.yml 关键配置
hostname: harbor.example.com
http:
  port: 80
https:
  port: 443
  certificate: /data/cert/server.crt
  private_key: /data/cert/server.key
harbor_admin_password: Harbor12345  # ⚠️ 立即修改
database:
  password: root123
data_volume: /data/harbor
# 安装
sudo ./install.sh --with-trivy  # 启用漏洞扫描

# 验证
podman ps  # 查看所有 Harbor 组件容器

# 使用 Harbor
podman login harbor.example.com
podman tag myapp:v1.0 harbor.example.com/myproject/myapp:v1.0
podman push harbor.example.com/myproject/myapp:v1.0

12.5 镜像签名

12.5.1 cosign(Sigstore)

cosign 是 Sigstore 项目的镜像签名工具,支持无密钥签名(Keyless Signing)。

# 安装 cosign
# Fedora
sudo dnf install cosign
# macOS
brew install cosign
# 通用
go install github.com/sigstore/cosign/v2/cmd/cosign@latest

# 生成密钥对
cosign generate-key-pair

# 签名镜像
cosign sign --key cosign.key registry.example.com/myapp:v1.0

# 验证签名
cosign verify --key cosign.pub registry.example.com/myapp:v1.0

12.5.2 无密钥签名(Keyless Signing)

# 使用 OIDC 身份进行签名(无需管理密钥)
# 常用于 CI/CD 中的 GitHub Actions / GitLab CI

# 签名(会触发 OIDC 流程)
cosign sign registry.example.com/myapp:v1.0

# 验证
cosign verify \
    --certificate-identity=user@example.com \
    --certificate-oidc-issuer=https://accounts.google.com \
    registry.example.com/myapp:v1.0

12.5.3 Podman 镜像签名策略

// /etc/containers/policy.json
{
    "default": [
        {
            "type": "insecureAcceptAnything"
        }
    ],
    "transports": {
        "docker": {
            "registry.example.com": [
                {
                    "type": "signedBy",
                    "keyType": "GPGKeys",
                    "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-example"
                }
            ],
            "ghcr.io/myorg": [
                {
                    "type": "sigstoreSigned",
                    "keyPath": "/etc/pki/containers/cosign.pub",
                    "signedIdentity": {
                        "type": "matchRepository"
                    }
                }
            ]
        }
    }
}
# 测试签名验证
podman pull registry.example.com/signed-image:v1.0
# 如果签名不匹配,会拒绝拉取

12.6 镜像分发策略

12.6.1 Registry Mirror(镜像加速)

# /etc/containers/registries.conf.d/mirror.conf

[[registry]]
prefix = "docker.io"
location = "docker.io"

[[registry.mirror]]
location = "mirror.example.com/docker-hub"

[[registry.mirror]]
location = "gcr.mirror.example.com"

12.6.2 Blocked Registries(黑名单)

# /etc/containers/registries.conf.d/block.conf

[registries.block]
registries = ['untrusted-registry.com', 'malicious.io']

12.7 本章小结

知识点 要点
公共仓库 Docker Hub、GHCR、Quay.io
私有 Registry registry:2 镜像,几分钟搭建
生产 Registry Harbor(功能丰富,CNCF 毕业项目)
TLS 自签名或 Let’s Encrypt
镜像签名 cosign + Sigstore(无密钥签名)
签名策略 /etc/containers/policy.json
镜像加速 Registry Mirror 配置

下一步


扩展阅读