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

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=[email protected] \
    --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
私有 Registryregistry:2 镜像,几分钟搭建
生产 RegistryHarbor(功能丰富,CNCF 毕业项目)
TLS自签名或 Let’s Encrypt
镜像签名cosign + Sigstore(无密钥签名)
签名策略/etc/containers/policy.json
镜像加速Registry Mirror 配置

下一步


扩展阅读