container-registry-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseContainer Registry Management
容器镜像仓库管理
Overview
概述
Implement comprehensive container registry management including image scanning, vulnerability detection, retention policies, access control, and multi-region replication.
实现全面的容器镜像仓库管理,包括镜像扫描、漏洞检测、保留策略、访问控制和多区域复制。
When to Use
适用场景
- Container image storage and distribution
- Security scanning and compliance
- Image retention and cleanup
- Registry access control
- Multi-region deployments
- Image signing and verification
- Cost optimization
- 容器镜像存储与分发
- 安全扫描与合规检查
- 镜像保留与清理
- 仓库访问控制
- 多区域部署
- 镜像签名与验证
- 成本优化
Implementation Examples
实现示例
1. AWS ECR Setup and Management
1. AWS ECR 配置与管理
yaml
undefinedyaml
undefinedecr-setup.yaml
ecr-setup.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: ecr-management
namespace: operations
data:
setup-ecr.sh: |
#!/bin/bash
set -euo pipefail
REGISTRY_NAME="myapp"
REGION="us-east-1"
ACCOUNT_ID="123456789012"
echo "Setting up ECR repository..."
# Create ECR repository
aws ecr create-repository \
--repository-name "$REGISTRY_NAME" \
--region "$REGION" \
--encryption-configuration encryptionType=KMS,kmsKey=arn:aws:kms:$REGION:$ACCOUNT_ID:key/12345678-1234-1234-1234-123456789012 \
--image-tag-mutability IMMUTABLE \
--image-scanning-configuration scanOnPush=true || true
echo "Repository: $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REGISTRY_NAME"
# Set lifecycle policy
aws ecr put-lifecycle-policy \
--repository-name "$REGISTRY_NAME" \
--region "$REGION" \
--lifecycle-policy-text '{
"rules": [
{
"rulePriority": 1,
"description": "Keep last 20 images tagged with release",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["release"],
"countType": "imageCountMoreThan",
"countNumber": 20
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Remove untagged images older than 7 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 7
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 3,
"description": "Keep all development images for 30 days",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["dev"],
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 30
},
"action": {
"type": "expire"
}
}
]
}'
# Enable cross-region replication
aws ecr create-registry \
--region "$REGION" \
--replication-configuration '{
"rules": [
{
"destinations": [
{
"region": "eu-west-1",
"registryId": "'$ACCOUNT_ID'"
},
{
"region": "ap-northeast-1",
"registryId": "'$ACCOUNT_ID'"
}
],
"repositoryFilters": [
{
"filter": "'$REGISTRY_NAME'",
"filterType": "PREFIX_MATCH"
}
]
}
]
}' || true
echo "ECR setup complete"scan-images.sh: |
#!/bin/bash
set -euo pipefail
REGISTRY_NAME="myapp"
REGION="us-east-1"
echo "Scanning all images in $REGISTRY_NAME"
# Get all image IDs
IMAGE_IDS=$(aws ecr list-images \
--repository-name "$REGISTRY_NAME" \
--region "$REGION" \
--query 'imageIds[*]' \
--output json)
# Scan each image
echo "$IMAGE_IDS" | jq -r '.[] | @base64' | while read image; do
IMAGE=$(echo "$image" | base64 -d | jq -r '.imageTag')
DIGEST=$(echo "$image" | base64 -d | jq -r '.imageDigest')
echo "Scanning image: $IMAGE ($DIGEST)"
# Start scan
aws ecr start-image-scan \
--repository-name "$REGISTRY_NAME" \
--image-id imageTag="$IMAGE" \
--region "$REGION" || true
# Get scan results
sleep 5
RESULTS=$(aws ecr describe-image-scan-findings \
--repository-name "$REGISTRY_NAME" \
--image-id imageTag="$IMAGE" \
--region "$REGION")
CRITICAL=$(echo "$RESULTS" | jq '.imageScanFindings.findingSeverityCounts.CRITICAL // 0')
HIGH=$(echo "$RESULTS" | jq '.imageScanFindings.findingSeverityCounts.HIGH // 0')
if [ "$CRITICAL" -gt 0 ]; then
echo "WARNING: Image has $CRITICAL critical vulnerabilities"
fi
if [ "$HIGH" -gt 0 ]; then
echo "WARNING: Image has $HIGH high vulnerabilities"
fi
done
echo "Image scanning complete"apiVersion: v1
kind: ConfigMap
metadata:
name: ecr-management
namespace: operations
data:
setup-ecr.sh: |
#!/bin/bash
set -euo pipefail
REGISTRY_NAME="myapp"
REGION="us-east-1"
ACCOUNT_ID="123456789012"
echo "Setting up ECR repository..."
# Create ECR repository
aws ecr create-repository \
--repository-name "$REGISTRY_NAME" \
--region "$REGION" \
--encryption-configuration encryptionType=KMS,kmsKey=arn:aws:kms:$REGION:$ACCOUNT_ID:key/12345678-1234-1234-1234-123456789012 \
--image-tag-mutability IMMUTABLE \
--image-scanning-configuration scanOnPush=true || true
echo "Repository: $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REGISTRY_NAME"
# Set lifecycle policy
aws ecr put-lifecycle-policy \
--repository-name "$REGISTRY_NAME" \
--region "$REGION" \
--lifecycle-policy-text '{
"rules": [
{
"rulePriority": 1,
"description": "Keep last 20 images tagged with release",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["release"],
"countType": "imageCountMoreThan",
"countNumber": 20
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Remove untagged images older than 7 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 7
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 3,
"description": "Keep all development images for 30 days",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["dev"],
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 30
},
"action": {
"type": "expire"
}
}
]
}'
# Enable cross-region replication
aws ecr create-registry \
--region "$REGION" \
--replication-configuration '{
"rules": [
{
"destinations": [
{
"region": "eu-west-1",
"registryId": "'$ACCOUNT_ID'"
},
{
"region": "ap-northeast-1",
"registryId": "'$ACCOUNT_ID'"
}
],
"repositoryFilters": [
{
"filter": "'$REGISTRY_NAME'",
"filterType": "PREFIX_MATCH"
}
]
}
]
}' || true
echo "ECR setup complete"scan-images.sh: |
#!/bin/bash
set -euo pipefail
REGISTRY_NAME="myapp"
REGION="us-east-1"
echo "Scanning all images in $REGISTRY_NAME"
# Get all image IDs
IMAGE_IDS=$(aws ecr list-images \
--repository-name "$REGISTRY_NAME" \
--region "$REGION" \
--query 'imageIds[*]' \
--output json)
# Scan each image
echo "$IMAGE_IDS" | jq -r '.[] | @base64' | while read image; do
IMAGE=$(echo "$image" | base64 -d | jq -r '.imageTag')
DIGEST=$(echo "$image" | base64 -d | jq -r '.imageDigest')
echo "Scanning image: $IMAGE ($DIGEST)"
# Start scan
aws ecr start-image-scan \
--repository-name "$REGISTRY_NAME" \
--image-id imageTag="$IMAGE" \
--region "$REGION" || true
# Get scan results
sleep 5
RESULTS=$(aws ecr describe-image-scan-findings \
--repository-name "$REGISTRY_NAME" \
--image-id imageTag="$IMAGE" \
--region "$REGION")
CRITICAL=$(echo "$RESULTS" | jq '.imageScanFindings.findingSeverityCounts.CRITICAL // 0')
HIGH=$(echo "$RESULTS" | jq '.imageScanFindings.findingSeverityCounts.HIGH // 0')
if [ "$CRITICAL" -gt 0 ]; then
echo "WARNING: Image has $CRITICAL critical vulnerabilities"
fi
if [ "$HIGH" -gt 0 ]; then
echo "WARNING: Image has $HIGH high vulnerabilities"
fi
done
echo "Image scanning complete"Terraform ECR configuration
Terraform ECR configuration
resource "aws_ecr_repository" "myapp" {
name = "myapp"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "KMS"
kms_key = aws_kms_key.ecr.arn
}
tags = {
Name = "myapp-registry"
}
}
resource "aws_ecr_lifecycle_policy" "myapp" {
repository = aws_ecr_repository.myapp.name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Keep last 20 production images"
selection = {
tagStatus = "tagged"
tagPrefixList = ["release"]
countType = "imageCountMoreThan"
countNumber = 20
}
action = {
type = "expire"
}
},
{
rulePriority = 2
description = "Remove untagged images after 7 days"
selection = {
tagStatus = "untagged"
countType = "sinceImagePushed"
countUnit = "days"
countNumber = 7
}
action = {
type = "expire"
}
}
]
})
}
resource "aws_ecr_repository_policy" "myapp" {
repository = aws_ecr_repository.myapp.name
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/EcsTaskExecutionRole"
}
Action = [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:GetImage"
]
}
]
})
}
undefinedresource "aws_ecr_repository" "myapp" {
name = "myapp"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "KMS"
kms_key = aws_kms_key.ecr.arn
}
tags = {
Name = "myapp-registry"
}
}
resource "aws_ecr_lifecycle_policy" "myapp" {
repository = aws_ecr_repository.myapp.name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Keep last 20 production images"
selection = {
tagStatus = "tagged"
tagPrefixList = ["release"]
countType = "imageCountMoreThan"
countNumber = 20
}
action = {
type = "expire"
}
},
{
rulePriority = 2
description = "Remove untagged images after 7 days"
selection = {
tagStatus = "untagged"
countType = "sinceImagePushed"
countUnit = "days"
countNumber = 7
}
action = {
type = "expire"
}
}
]
})
}
resource "aws_ecr_repository_policy" "myapp" {
repository = aws_ecr_repository.myapp.name
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/EcsTaskExecutionRole"
}
Action = [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:GetImage"
]
}
]
})
}
undefined2. Container Image Build and Push
2. 容器镜像构建与推送
bash
#!/bin/bashbash
#!/bin/bashbuild-and-push.sh - Build and push container images
build-and-push.sh - 构建并推送容器镜像
set -euo pipefail
REGISTRY="${1:-123456789012.dkr.ecr.us-east-1.amazonaws.com}"
IMAGE_NAME="${2:-myapp}"
VERSION="${3:-latest}"
DOCKERFILE="${4:-Dockerfile}"
echo "Building and pushing container image..."
set -euo pipefail
REGISTRY="${1:-123456789012.dkr.ecr.us-east-1.amazonaws.com}"
IMAGE_NAME="${2:-myapp}"
VERSION="${3:-latest}"
DOCKERFILE="${4:-Dockerfile}"
echo "Building and pushing container image..."
Set full image path
设置完整镜像路径
FULL_IMAGE="$REGISTRY/$IMAGE_NAME:$VERSION"
FULL_IMAGE="$REGISTRY/$IMAGE_NAME:$VERSION"
Login to ECR
登录ECR
echo "Authenticating to ECR..."
aws ecr get-login-password --region us-east-1 |
docker login --username AWS --password-stdin "$REGISTRY"
docker login --username AWS --password-stdin "$REGISTRY"
echo "Authenticating to ECR..."
aws ecr get-login-password --region us-east-1 |
docker login --username AWS --password-stdin "$REGISTRY"
docker login --username AWS --password-stdin "$REGISTRY"
Build image
构建镜像
echo "Building image: $FULL_IMAGE"
docker build
-f "$DOCKERFILE"
-t "$FULL_IMAGE"
-t "$REGISTRY/$IMAGE_NAME:latest"
--build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
--build-arg VCS_REF="$(git rev-parse --short HEAD)"
--build-arg VERSION="$VERSION"
.
-f "$DOCKERFILE"
-t "$FULL_IMAGE"
-t "$REGISTRY/$IMAGE_NAME:latest"
--build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
--build-arg VCS_REF="$(git rev-parse --short HEAD)"
--build-arg VERSION="$VERSION"
.
echo "Building image: $FULL_IMAGE"
docker build
-f "$DOCKERFILE"
-t "$FULL_IMAGE"
-t "$REGISTRY/$IMAGE_NAME:latest"
--build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
--build-arg VCS_REF="$(git rev-parse --short HEAD)"
--build-arg VERSION="$VERSION"
.
-f "$DOCKERFILE"
-t "$FULL_IMAGE"
-t "$REGISTRY/$IMAGE_NAME:latest"
--build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
--build-arg VCS_REF="$(git rev-parse --short HEAD)"
--build-arg VERSION="$VERSION"
.
Scan with trivy before push
推送前使用Trivy扫描
echo "Scanning image with Trivy..."
trivy image --severity HIGH,CRITICAL "$FULL_IMAGE"
echo "Scanning image with Trivy..."
trivy image --severity HIGH,CRITICAL "$FULL_IMAGE"
Push image
推送镜像
echo "Pushing image to ECR..."
docker push "$FULL_IMAGE"
docker push "$REGISTRY/$IMAGE_NAME:latest"
echo "Pushing image to ECR..."
docker push "$FULL_IMAGE"
docker push "$REGISTRY/$IMAGE_NAME:latest"
Get image digest
获取镜像摘要
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$FULL_IMAGE" | cut -d@ -f2)
echo "Image pushed successfully"
echo "Image: $FULL_IMAGE"
echo "Digest: $DIGEST"
undefinedDIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$FULL_IMAGE" | cut -d@ -f2)
echo "Image pushed successfully"
echo "Image: $FULL_IMAGE"
echo "Digest: $DIGEST"
undefined3. Image Signing with Notary
3. 使用Notary进行镜像签名
bash
#!/bin/bashbash
#!/bin/bashsign-image.sh - Sign container images with Notary
sign-image.sh - 使用Notary签名容器镜像
set -euo pipefail
IMAGE="${1}"
NOTATION_KEY="${2:-mykey}"
echo "Signing image: $IMAGE"
set -euo pipefail
IMAGE="${1}"
NOTATION_KEY="${2:-mykey}"
echo "Signing image: $IMAGE"
Initialize Notary
初始化Notary
notary key list
notary key list
Sign image
签名镜像
notation sign
--key "$NOTATION_KEY"
--allow-missing
"$IMAGE"
--key "$NOTATION_KEY"
--allow-missing
"$IMAGE"
echo "Image signed successfully"
notation sign
--key "$NOTATION_KEY"
--allow-missing
"$IMAGE"
--key "$NOTATION_KEY"
--allow-missing
"$IMAGE"
echo "Image signed successfully"
Verify signature
验证签名
notation verify "$IMAGE"
undefinednotation verify "$IMAGE"
undefined4. Registry Access Control
4. 仓库访问控制
yaml
undefinedyaml
undefinedregistry-access-control.yaml
registry-access-control.yaml
apiVersion: v1
kind: Secret
metadata:
name: ecr-pull-secret
namespace: production
type: kubernetes.io/dockercfg
stringData:
.dockercfg: |
{
"123456789012.dkr.ecr.us-east-1.amazonaws.com": {
"auth": "base64-encoded-credentials",
"email": "service-account@mycompany.com"
}
}
apiVersion: v1
kind: ServiceAccount
metadata:
name: ecr-pull-sa
namespace: production
imagePullSecrets:
- name: ecr-pull-secret
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: production
spec:
serviceAccountName: ecr-pull-sa
containers:
- name: app
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
imagePullPolicy: Always
apiVersion: v1
kind: Secret
metadata:
name: ecr-pull-secret
namespace: production
type: kubernetes.io/dockercfg
stringData:
.dockercfg: |
{
"123456789012.dkr.ecr.us-east-1.amazonaws.com": {
"auth": "base64-encoded-credentials",
"email": "service-account@mycompany.com"
}
}
apiVersion: v1
kind: ServiceAccount
metadata:
name: ecr-pull-sa
namespace: production
imagePullSecrets:
- name: ecr-pull-secret
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: production
spec:
serviceAccountName: ecr-pull-sa
containers:
- name: app
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
imagePullPolicy: Always
IAM policy for ECR access
IAM policy for ECR access
apiVersion: iam.aws.amazon.com/v1
kind: IAMPolicy
metadata:
name: ecr-read-only
spec:
policyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:GetImage
- ecr:DescribeImages
Resource: arn:aws:ecr::123456789012:repository/myapp
- Effect: Allow
Action:
- ecr:GetAuthorizationToken
Resource: ''
undefinedapiVersion: iam.aws.amazon.com/v1
kind: IAMPolicy
metadata:
name: ecr-read-only
spec:
policyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:GetImage
- ecr:DescribeImages
Resource: arn:aws:ecr::123456789012:repository/myapp
- Effect: Allow
Action:
- ecr:GetAuthorizationToken
Resource: ''
undefined5. Registry Monitoring
5. 仓库监控
yaml
undefinedyaml
undefinedregistry-monitoring.yaml
registry-monitoring.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: registry-monitoring
namespace: monitoring
data:
dashboards.json: |
{
"dashboard": {
"title": "Container Registry",
"panels": [
{
"title": "Images by Repository",
"targets": [
{
"expr": "count by (repository) (aws_ecr_repository_images)"
}
]
},
{
"title": "Images with Vulnerabilities",
"targets": [
{
"expr": "sum(aws_ecr_image_scan_findings{severity=~"HIGH|CRITICAL"})"
}
]
},
{
"title": "Registry Storage",
"targets": [
{
"expr": "aws_ecr_repository_size_bytes"
}
]
}
]
}
}
apiVersion: v1
kind: ConfigMap
metadata:
name: registry-alerts
namespace: monitoring
data:
alerts.yaml: |
groups:
- name: registry_alerts
rules:
- alert: ImageWithCriticalVulnerabilities
expr: aws_ecr_image_scan_findings{severity="CRITICAL"} > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Image has critical vulnerabilities"
- alert: ImagePushFailure
expr: aws_ecr_push_failures_total > 0
for: 1m
labels:
severity: warning
annotations:
summary: "Image push failed"
- alert: RegistryStorageHigh
expr: aws_ecr_repository_size_bytes / 1024 / 1024 / 1024 > 100
labels:
severity: warning
annotations:
summary: "Registry storage usage is high"undefinedapiVersion: v1
kind: ConfigMap
metadata:
name: registry-monitoring
namespace: monitoring
data:
dashboards.json: |
{
"dashboard": {
"title": "Container Registry",
"panels": [
{
"title": "Images by Repository",
"targets": [
{
"expr": "count by (repository) (aws_ecr_repository_images)"
}
]
},
{
"title": "Images with Vulnerabilities",
"targets": [
{
"expr": "sum(aws_ecr_image_scan_findings{severity=~"HIGH|CRITICAL"})"
}
]
},
{
"title": "Registry Storage",
"targets": [
{
"expr": "aws_ecr_repository_size_bytes"
}
]
}
]
}
}
apiVersion: v1
kind: ConfigMap
metadata:
name: registry-alerts
namespace: monitoring
data:
alerts.yaml: |
groups:
- name: registry_alerts
rules:
- alert: ImageWithCriticalVulnerabilities
expr: aws_ecr_image_scan_findings{severity="CRITICAL"} > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Image has critical vulnerabilities"
- alert: ImagePushFailure
expr: aws_ecr_push_failures_total > 0
for: 1m
labels:
severity: warning
annotations:
summary: "Image push failed"
- alert: RegistryStorageHigh
expr: aws_ecr_repository_size_bytes / 1024 / 1024 / 1024 > 100
labels:
severity: warning
annotations:
summary: "Registry storage usage is high"undefinedBest Practices
最佳实践
✅ DO
✅ 建议
- Scan images before deployment
- Use image tag immutability
- Implement retention policies
- Control registry access with IAM
- Sign images for verification
- Replicate across regions
- Monitor registry storage
- Use private registries
- 部署前扫描镜像
- 使用镜像标签不可变性
- 实施保留策略
- 使用IAM控制仓库访问
- 签名镜像以进行验证
- 跨区域复制镜像
- 监控仓库存储
- 使用私有仓库
❌ DON'T
❌ 不建议
- Push to public registries
- Use tag in production
latest - Allow anonymous pulls
- Store secrets in images
- Keep old images indefinitely
- Push without scanning
- Use default credentials
- Share registry credentials
- 推送到公共仓库
- 生产环境使用标签
latest - 允许匿名拉取
- 在镜像中存储密钥
- 无限期保留旧镜像
- 未扫描就推送镜像
- 使用默认凭证
- 共享仓库凭证
Registry Options
仓库选项
- Docker Hub: Public registry
- AWS ECR: AWS-managed
- Google GCR: Google Cloud
- Azure ACR: Azure-managed
- Artifactory: Self-hosted
- Harbor: Open-source
- Docker Hub: 公共仓库
- AWS ECR: AWS托管
- Google GCR: 谷歌云托管
- Azure ACR: Azure托管
- Artifactory: 自托管
- Harbor: 开源仓库
Image Naming Convention
镜像命名规范
[registry]/[organization]/[repository]:[tag]
123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.2.3[registry]/[organization]/[repository]:[tag]
123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.2.3