关于 container-registry-setup
面向容器平台工程师的容器 Registry 配置与运维指南,涵盖云托管和自托管方案,并提供安全、Kubernetes 与 CI/CD 示例。
主要功能
- 01云托管与自托管 Registry 选型
- 02ECR 与 Harbor 配置示例
- 03镜像漏洞扫描与签名
- 04Kubernetes 拉取凭据配置
- 05CI/CD 推送与镜像清理
- 06缓存、优化与故障排查
适用场景
- 01为应用配置 AWS ECR 仓库
- 02部署自托管 Harbor Registry
- 03在镜像发布流程中扫描和签名
- 04配置 Kubernetes 拉取私有镜像
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dengineproblem/ agents-monorepo --skill container-registry-setup安装后在 Claude Code 中输入/container-registry-setup确认已加载。
详细介绍
容器镜像仓库设置专家
容器镜像仓库的设置与管理专家。
Registry 类型
云托管
| Registry | 提供商 | 特性 |
|---|---|---|
| ECR | AWS | IAM 集成、扫描 |
| Artifact Registry | GCP | 多格式、区域化 |
| ACR | Azure | AD 集成、地理复制 |
| Docker Hub | Docker | 公有/私有、CI/CD |
自托管
| Registry | 适用场景 | 特性 |
|---|---|---|
| Harbor | 企业级 | RBAC、扫描、复制 |
| Nexus | 多制品 | Maven、npm、Docker |
| Artifactory | 企业级 | 通用、高可用 |
| Distribution | 简单场景 | Docker 官方 Registry |
AWS ECR 设置
Terraform 配置
resource "aws_ecr_repository" "app" {
name = "my-application"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "KMS"
kms_key = aws_kms_key.ecr.arn
}
tags = {
Environment = "production"
Team = "platform"
}
}
resource "aws_ecr_lifecycle_policy" "cleanup" {
repository = aws_ecr_repository.app.name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Keep last 10 images"
selection = {
tagStatus = "tagged"
tagPrefixList = ["v"]
countType = "imageCountMoreThan"
countNumber = 10
}
action = {
type = "expire"
}
},
{
rulePriority = 2
description = "Remove untagged after 7 days"
selection = {
tagStatus = "untagged"
countType = "sinceImagePushed"
countUnit = "days"
countNumber = 7
}
action = {
type = "expire"
}
}
]
})
}
ECR 身份验证
# Login to ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
123456789.dkr.ecr.us-east-1.amazonaws.com
# Push image
docker tag myapp:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
Harbor 自托管
Docker Compose 设置
version: '3'
services:
harbor-core:
image: goharbor/harbor-core:v2.9.0
container_name: harbor-core
env_file:
- ./common/config/core/env
volumes:
- ./common/config/core/certificates:/etc/core/certificates
- ./common/config/core/key:/etc/core/key
depends_on:
- registry
- redis
- postgresql
networks:
- harbor
registry:
image: goharbor/registry-photon:v2.9.0
container_name: registry
volumes:
- registry_data:/storage
- ./common/config/registry:/etc/registry
networks:
- harbor
postgresql:
image: goharbor/harbor-db:v2.9.0
container_name: harbor-db
volumes:
- database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
networks:
- harbor
redis:
image: goharbor/redis-photon:v2.9.0
container_name: harbor-redis
volumes:
- redis:/var/lib/redis
networks:
- harbor
nginx:
image: goharbor/nginx-photon:v2.9.0
container_name: nginx
ports:
- "80:8080"
- "443:8443"
volumes:
- ./common/config/nginx:/etc/nginx
depends_on:
- harbor-core
networks:
- harbor
volumes:
registry_data:
database:
redis:
networks:
harbor:
driver: bridge
镜像安全
漏洞扫描
# Trivy scan
trivy image myapp:latest
# Grype scan
grype myapp:latest
# ECR scan results
aws ecr describe-image-scan-findings \
--repository-name myapp \
--image-id imageTag=latest
使用 Cosign 签署镜像
# Generate key pair
cosign generate-key-pair
# Sign image
cosign sign --key cosign.key myregistry/myapp:latest
# Verify signature
cosign verify --key cosign.pub myregistry/myapp:latest
内容信任(Docker)
# Enable content trust
export DOCKER_CONTENT_TRUST=1
# Sign and push
docker push myregistry/myapp:latest
# Verify on pull
docker pull myregistry/myapp:latest
Kubernetes 集成
镜像拉取密钥
apiVersion: v1
kind: Secret
metadata:
name: registry-credentials
namespace: default
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: |
eyJhdXRocyI6eyJteXJlZ2lzdHJ5LmNvbSI6eyJ1c2VybmFtZSI6InVzZXIi
LCJwYXNzd29yZCI6InBhc3MiLCJhdXRoIjoiZFhObGNqcHdZWE56In19fQ==
使用拉取密钥部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry.com/myapp:v1.0.0
imagePullPolicy: Always
imagePullSecrets:
- name: registry-credentials
ServiceAccount 配置
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp-sa
namespace: default
imagePullSecrets:
- name: registry-credentials
CI/CD 集成
GitHub Actions
name: Build and Push
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:${{ github.sha }}
myuser/myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
GitLab CI
stages:
- build
- push
variables:
IMAGE_NAME: $CI_REGISTRY_IMAGE
build:
stage: build
image: docker:24
services:
- docker:24-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .
- docker push $IMAGE_NAME:$CI_COMMIT_SHA
only:
- main
清理脚本
ECR 清理
import boto3
from datetime import datetime, timedelta
def cleanup_untagged_images(repository: str, days_old: int = 7):
"""Remove untagged images older than specified days."""
ecr = boto3.client('ecr')
response = ecr.describe_images(
repositoryName=repository,
filter={'tagStatus': 'UNTAGGED'}
)
cutoff = datetime.now() - timedelta(days=days_old)
images_to_delete = []
for image in response['imageDetails']:
if image['imagePushedAt'].replace(tzinfo=None) < cutoff:
images_to_delete.append({
'imageDigest': image['imageDigest']
})
if images_to_delete:
ecr.batch_delete_image(
repositoryName=repository,
imageIds=images_to_delete
)
print(f"Deleted {len(images_to_delete)} images")
# Usage
cleanup_untagged_images('my-app', days_old=7)
性能优化
Registry 缓存
# Docker daemon.json
{
"registry-mirrors": ["https://mirror.gcr.io"],
"insecure-registries": [],
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5
}
拉取透传缓存(Harbor)
# Harbor project config
replication:
- name: docker-hub-proxy
type: pull-through
source: https://registry-1.docker.io
filters:
- name: library/*
trigger:
type: manual
故障排查
# Test connectivity
curl -v https://myregistry.com/v2/
# Check authentication
docker login myregistry.com
# Verify TLS
openssl s_client -connect myregistry.com:443 -servername myregistry.com
# Clear credentials
docker logout myregistry.com
rm ~/.docker/config.json
# Debug pull issues
docker pull myregistry.com/myapp:latest --debug
最佳实践
- 镜像不可变性 — 使用不可变标签
- 漏洞扫描 — 必须在推送时扫描
- 生命周期策略 — 自动清理旧镜像
- 内容信任 — 为生产镜像签名
- 地理复制 — 适用于全球部署
- 访问控制 — 通过 RBAC 实施最小权限
- 监控 — 对推送和拉取失败设置警报
评论
支持 Markdown