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 |
| 私有 Registry | registry:2 镜像,几分钟搭建 |
| 生产 Registry | Harbor(功能丰富,CNCF 毕业项目) |
| TLS | 自签名或 Let’s Encrypt |
| 镜像签名 | cosign + Sigstore(无密钥签名) |
| 签名策略 | /etc/containers/policy.json |
| 镜像加速 | Registry Mirror 配置 |
下一步
- 👉 第 13 章:Docker 迁移 — 从 Docker 平滑迁移到 Podman