#镜像仓库验证策略
本指南演示如何配置 Kyverno 来控制 Kubernetes 集群中可使用的容器镜像仓库。它实现了仓库访问控制策略,确保只部署来自批准和可信仓库的镜像。
#目录
什么是镜像仓库验证?快速开始1. 阻止除公司仓库外的所有仓库2. 测试策略常见场景场景 1:允许多个可信仓库场景 2:不同环境不同规则场景 3:阻止特定风险仓库场景 4:团队专属仓库访问高级模式有效使用通配符最佳实践从警告模式开始排除系统命名空间常见问题#什么是镜像仓库验证?
仓库验证提供了对镜像来源的集中控制。它能够:
- 控制镜像来源:仅允许来自可信仓库的镜像
- 阻止风险仓库:防止使用未知或被攻破的仓库
- 强制合规:满足关于镜像来源的安全要求
- 针对不同环境制定不同规则:生产环境严格,开发环境宽松
- 跟踪使用情况:监控使用了哪些仓库
#快速开始
#1. 阻止除公司仓库外的所有仓库
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: company-registry-only
spec:
validationFailureAction: Enforce # 阻止非批准镜像
background: false
rules:
- name: check-registry
match:
any:
- resources:
kinds:
- Pod
validate:
message: "仅允许公司仓库:registry.company.com"
pattern:
spec:
containers:
- image: "registry.company.com/*"#2. 测试策略
# 应用策略
kubectl apply -f registry-policy.yaml
# 这条命令应失败(nginx 来自 Docker Hub)
kubectl run test --image=nginx:latest
# 这条命令应成功(如果镜像存在于仓库中)
kubectl run test --image=registry.company.com/nginx:latest#常见场景
#场景 1:允许多个可信仓库
组织通常使用多个仓库:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: multiple-trusted-registries
spec:
validationFailureAction: Enforce
background: false
rules:
- name: check-approved-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "镜像必须来自批准的仓库:公司仓库、GCR 或官方 Docker 镜像"
anyPattern:
- spec:
containers:
- image: "registry.company.com/*" # 公司仓库
- spec:
containers:
- image: "gcr.io/project-name/*" # Google Container Registry
- spec:
containers:
- image: "docker.io/library/*" # 仅官方 Docker 镜像
- spec:
containers:
- image: "quay.io/organization/*" # Red Hat Quay#场景 2:不同环境不同规则
生产环境应严格,开发环境可更灵活:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: environment-based-registry-rules
spec:
validationFailureAction: Enforce
background: false
rules:
# 生产环境:仅允许认证镜像
- name: production-strict-registries
match:
any:
- resources:
kinds:
- Pod
namespaces:
- production
- prod-*
validate:
message: "生产环境仅允许认证的公司镜像"
pattern:
spec:
containers:
- image: "registry.company.com/certified/*"
# 开发环境:允许更多仓库
- name: development-flexible-registries
match:
any:
- resources:
kinds:
- Pod
namespaces:
- development
- dev-*
- staging
- test-*
validate:
message: "开发环境允许使用公司仓库、GCR 或官方 Docker 镜像"
anyPattern:
- spec:
containers:
- image: "registry.company.com/*"
- spec:
containers:
- image: "gcr.io/dev-project/*"
- spec:
containers:
- image: "docker.io/library/*"
- spec:
containers:
- image: "docker.io/organization/*"#场景 3:阻止特定风险仓库
阻止特定仓库,同时允许其他仓库:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: block-risky-registries
spec:
validationFailureAction: Enforce
background: false
rules:
# 方法一:使用拒绝列表
- name: block-untrusted-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "不允许使用 untrusted-registry.com 的镜像"
deny:
conditions:
- key: "{{ request.object.spec.containers[?contains(image, 'untrusted-registry.com')] | length(@) }}"
operator: GreaterThan
value: 0
# 方法二:Docker Hub 仅允许官方镜像
- name: allow-only-official-dockerhub
match:
any:
- resources:
kinds:
- Pod
validate:
message: "仅允许官方 Docker Hub 镜像(docker.io/library/*)"
deny:
conditions:
- key: "{{ request.object.spec.containers[?starts_with(image, 'docker.io/') && !starts_with(image, 'docker.io/library/')] | length(@) }}"
operator: GreaterThan
value: 0#场景 4:团队专属仓库访问
不同团队可访问不同仓库:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: team-specific-registries
spec:
validationFailureAction: Enforce
background: false
rules:
# 前端团队可使用 Node.js 镜像
- name: frontend-team-registries
match:
any:
- resources:
kinds:
- Pod
namespaces:
- frontend-*
validate:
message: "前端团队可使用公司仓库和官方 Node.js 镜像"
anyPattern:
- spec:
containers:
- image: "registry.company.com/*"
- spec:
containers:
- image: "docker.io/library/node:*"
- spec:
containers:
- image: "docker.io/library/nginx:*"
# 数据团队可使用 ML/AI 镜像仓库
- name: data-team-registries
match:
any:
- resources:
kinds:
- Pod
namespaces:
- data-*
- ml-*
validate:
message: "数据团队可使用公司仓库和 ML/AI 镜像"
anyPattern:
- spec:
containers:
- image: "registry.company.com/*"
- spec:
containers:
- image: "docker.io/tensorflow/*"
- spec:
containers:
- image: "docker.io/pytorch/*"
- spec:
containers:
- image: "nvcr.io/nvidia/*"#高级模式
#有效使用通配符
# 匹配模式:
- image: "registry.company.com/*" # 来自该仓库的任意镜像
- image: "registry.company.com/team-a/*" # 仅 team-a 的镜像
- image: "*/database:*" # 任意仓库的数据库镜像
- image: "gcr.io/project-*/app:*" # GCR 中 project-* 下的任意 app 镜像#最佳实践
#从警告模式开始
spec:
validationFailureAction: Audit # 先使用审计模式,不阻止#排除系统命名空间
rules:
- name: check-registries
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- kube-public#常见问题
-
镜像格式错误:
- ❌
registry.company.com:5000/app(缺少协议) - ✅
registry.company.com/app:latest
- ❌
-
通配符误用:
- ❌
registry.company.com*(缺少斜杠) - ✅
registry.company.com/*
- ❌
-
Docker Hub 格式:
- ❌
nginx(隐式 docker.io) - ✅
docker.io/library/nginx
- ❌