使用 Kyverno 验证 Kubernetes 容器镜像:实用指南
如果您在 Kubernetes 上运行工作负载,镜像安全至关重要。容器会从公共或私有镜像仓库中拉取数据,如果这些来源未经验证,就可能引发漏洞,甚至供应链攻击。
Kyverno 应运而生——它是一个 Kubernetes 原生策略引擎,可让您根据自己定义的策略验证、修改和生成配置。本文将向您展示如何使用 Kyverno 验证容器镜像源并强制执行安全措施。
我讲在这篇文章中介绍下面的内容:
- Kyverno 如何工作的
- 如何在 Kubernetes 中强制执行可信镜像仓库
- 如何验证镜像签名和标签
- Kyverno 镜像验证策略示例
- 如何将其集成到安全的 CI/CD 工作流中
Kyverno 如何工作的
Kubernetes 准入控制
Kyverno 在 Kubernetes 集群中作为动态准入控制器运行。Kyverno 从 Kubernetes API 服务器接收用于验证和修改的准入 webhook HTTP 回调,并应用匹配的策略,返回执行准入策略或拒绝请求的结果。
Kyverno 策略可以使用资源类型、名称、标签选择器等多种方式匹配资源。
修改策略可以编写为覆盖层(类似于 Kustomize)或 RFC 6902 JSON 补丁。验证策略也使用覆盖层样式的语法,支持模式匹配和条件(if-then-else)处理。
策略执行情况通过 Kubernetes 事件捕获。对于已允许或在引入 Kyverno 策略之前存在的请求,Kyverno 会在集群中创建策略报告,其中包含与策略匹配的资源的运行列表、其状态等信息。
下图展示了 Kyverno 的高级逻辑架构。
Kyverno 架构
Webhook 是处理来自 Kubernetes API 服务器的 AdmissionReview 请求并将其发送到引擎进行处理的服务器。Webhook 控制器会动态配置 Webhook,该控制器会监视已安装的策略并修改 Webhook,使其仅请求与这些策略匹配的资源。证书更新器负责监视和更新 Webhook 所需的证书(存储为 Kubernetes Secrets)。后台控制器通过协调中间资源 UpdateRequests 来处理所有策略的生成和变更。报告控制器负责从其中间资源(准入报告和后台扫描报告)创建和协调策略报告。
Kyverno 还支持高可用性。Kyverno 的高可用性安装是指所选控制器配置为使用多个副本运行。根据控制器的不同,额外的副本也可能有助于提高 Kyverno 的可扩展性。有关各种 Kyverno 控制器、其组件以及如何处理可用性的更多详细信息,请参阅高可用性页面。
为什么应该验证容器镜像
容器通常从 Docker Hub、Quay 或 GitHub Container Registry 等镜像源中拉取数据。但并非所有来源都值得信赖。
攻击者可以:
- 注入恶意层
- 劫持废弃的公共镜像
- 推送模拟容器
解决方案?定义允许的内容,并在镜像运行之前强制执行。
使用 Kyverno 验证镜像注册表来源
假设您只想允许来自 myregistry.example.com 的镜像。
以下 Kyverno 策略即可实现此目的:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:name: verify-image-source
spec:validationFailureAction: enforcerules:- name: require-approved-registriesmatch:resources:kinds:- Podvalidate:message: "Only approved registries are allowed"pattern:spec:containers:- image: "myregistry.example.com/*"
此策略会扫描 Pod 规范中每个容器的 image 字段。如果容器与允许的注册表不匹配,则会在准入时被阻止。
验证特定镜像标签或摘要
想要仅允许带有 :latest 或固定摘要的镜像?这里有另一条 Kyverno 规则:
validate:message: "Use specific tags or digests only"pattern:spec:containers:- image: "*:*"
如果您想要可重复性,甚至可以将此规则与逻辑结合使用,以阻止 :latest。
将以下策略添加到您的集群。它包含一条验证规则,要求所有 Pod 都具有团队标签。Kyverno 支持不同的规则类型来验证、变更、生成、清理和校验镜像配置。字段“failureAction”设置为“Enforce”,以阻止不合规的 Pod。使用默认值“Audit”,将报告违规行为,但不会阻止请求。
kubectl create -f- << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:name: require-labels
spec:rules:- name: check-teammatch:any:- resources:kinds:- Podvalidate:failureAction: Enforcemessage: "label 'team' is required"pattern:metadata:labels:team: "?*"
EOF
尝试创建一个不带所需标签的部署。
kubectl create deploy nginx --image=nginx
您应该会看到一个错误。
error: failed to create deployment: admission webhook "validate.kyverno.svc-fail" denied the request: resource Deployment/default/nginx was blocked due to the following policies:require-labels:autogen-check-team: 'validation error: label ''team'' isrequired. Rule autogen-check-team failed at path /spec/template/metadata/labels/team/'
高级:验证镜像签名
在 Kyverno 1.7+ 版本中,您可以使用 Cosign 支持的图像签名验证。示例:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:name: verify-image-signature
spec:validationFailureAction: enforcerules:- name: require-signed-imagesverifyImages:- image: "ghcr.io/my-org/*"key: "https://my-keys/key.pub"attestations:- name: dev-attestationpredicateType: "https://example.com/dev"
这确保只有来自可信来源的签名镜像才能被允许进入集群。
测试 Kyverno 镜像策略
1. 应用策略:
kubectl apply -f policy.yaml
2. 使用 Pod 清单进行测试:
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:containers:- name: testimage: docker.io/library/nginx:latest
3. 如果策略阻止,您将看到验证错误。
与 CI/CD 流水线集成
- 在预览环境中强制执行 Kyverno 策略
- 使用 Conftest 或 Kyverno CLI 等工具在部署前测试策略
- 集成到 GitLab、GitHub Actions 或 Argo CD 流水线
总结
Kyverno 是一款专为 Kubernetes 设计的云原生策略引擎,支持平台工程师自动化安全、合规和最佳实践。它通过验证、变更、生成和清理 Kubernetes 资源来实现策略的执行。Kyverno 策略以 YAML 编写,无需学习新语言即可访问。
Kyverno 充当动态准入控制器,接收来自 Kubernetes API 服务器的 Webhook 回调来执行策略。它支持策略报告、软件供应链安全的镜像验证,以及使用 Git 和 Kustomize 等常用工具进行策略管理。此外,Kyverno 还可以在 Kubernetes 集群之外使用,以实现更广泛的策略执行。