☰
Operator SDK scorecard 命令详解:基于 bundle 的 Operator 质量评分与测试实战
2026/9/29 3:32:31 网站建设 项目流程
  • 云原生
  • 后端
  • 开发工具
  • 微服务

【免费下载链接】operator-sdk

SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.

项目地址:https://gitcode.com/gh_mirrors/op/operator-sdk
点击查看免费下载

导读

operator-sdk scorecard是 Operator SDK 内置的测试执行命令,用于对一个 Operator bundle(镜像或目录)运行一系列预定义的测试,评估该 Operator 是否达到可发布到 OLM(Operator Lifecycle Manager)的质量基线。读完本文,你将掌握 scorecard 的全部命令行参数及其默认值、bundle 配置文件的编写方法、text/json/xunit 三种结果输出格式的差异,以及命令底层在 Kubernetes 集群中的 Pod 执行与资源清理机制。

命令概览与语法

scorecard 命令的核心作用是运行一组对 Operator bundle 的评分测试。它通过命令行标志(flags)配置 DSL(测试描述)、bundle 与选择器(selector),并接收一个必填位置参数:要么是一个 bundle 镜像,要么是一个包含 manifests 与 metadata 的目录。

注意:如果传入的是镜像 tag,则该镜像必须已经存在于远端镜像仓库(命令执行时会拉取该镜像);本地镜像需要先推送到远端。如果传入的是目录,则必须是符合 bundle 布局的本地目录。

operator-sdk scorecard [flags]

从源码看,该命令在 internal/cmd/operator-sdk/scorecard/cmd.go 中定义,其validate()方法要求参数个数必须为 1,否则直接报错a bundle image or directory argument is required,这是命令的硬性入参约束:

func (c *scorecardCmd) validate(args []string) error { if len(args) != 1 { return fmt.Errorf("a bundle image or directory argument is required") } return nil }

如果传入的参数在本地文件系统中不存在(os.Stat报os.ErrNotExist),命令会将其视为镜像,调用extractBundleImage()通过 registry 工具拉取并解包到本地临时目录后继续执行(cmd.go)。

命令行参数全解

scorecard 提供了 12 个本命令专属标志,下表完整列出(含默认值与含义):

标志简写默认值说明
--config-c空(自动推导)scorecard 配置文件路径,默认在 bundle 内查找
--help-h—显示 scorecard 帮助信息
--kubeconfig—空kubeconfig 路径
--list-Lfalse仅列出会被执行的测试,不真正运行
--namespace-n空(由 kubeconfig 推导)运行测试 Pod 的命名空间
--output-otext结果输出格式,合法值:text、json、xunit
--pod-security—legacy是否以受限 Pod 安全上下文运行 scorecard
--selector-l空标签选择器,决定运行哪些测试
--service-account-sdefault测试使用的 ServiceAccount
--skip-cleanup-xfalse测试完成后禁用资源清理
--storage-image-bquay.io/operator-framework/scorecard-storage@sha256:a3bfda71281393c7794cabdd39c563fb050d3020fd0b642ea164646bdd39a0e2Scorecard Pod 使用的存储镜像
--test-output-ttest-output测试输出目录
--untar-image-uquay.io/operator-framework/scorecard-untar@sha256:2e728c5e67a7f4dec0df157a322dd5671212e8ae60f69137463bd4fdfbff8747Scorecard Pod 使用的解包镜像
--wait-time-w30s等待测试完成的最长时间,示例格式:35s

从父命令继承的全局标志

scorecard 作为operator-sdk的子命令,还继承了两个全局标志:

标志说明
--plugins strings本次子命令执行所使用的插件键列表
--verbose启用详细日志输出

其中--verbose在 bundle 镜像解包时尤为有用:源码中extractBundleImage()会读取 viper 中的VerboseOpt,仅在开启 verbose 时才输出带 bundle 字段的解包日志,否则丢弃日志(cmd.go)。

典型用法示例

以下命令均以传入 bundle 目录为例:

# 使用默认配置运行 scorecard,结果输出为 text operator-sdk scorecard ./bundle # 指定配置文件与命名空间 operator-sdk scorecard ./bundle --config config/scorecard/config.yaml --namespace my-operator-ns # 仅列出当前配置与选择器会命中的测试 operator-sdk scorecard ./bundle --list # 只运行 olm 套件的测试 operator-sdk scorecard ./bundle --selector suite=olm # 输出 JSON 格式结果并指定 kubeconfig operator-sdk scorecard ./bundle --output json --kubeconfig /path/to/kubeconfig # 等待测试最多 60 秒,测试结束后不清理资源(便于排查) operator-sdk scorecard ./bundle --wait-time 60s --skip-cleanup

配置文件与测试选择机制

配置文件定位规则

scorecard 配置文件的默认查找路径遵循以下优先级(见 cmd.go):

  1. 若显式传入--config,直接使用该路径;
  2. 否则读取 bundle 元数据注解operators.operatorframework.io.test.config.v1指定的配置目录(注解的键值逻辑见 internal/annotations/scorecard/scorecard.go);
  3. 若注解不存在,回退到 bundle 内的默认位置tests/scorecard/config.yaml(常量定义于 internal/scorecard/config.go)。

配置文件通过scorecard.LoadConfig()读取并反序列化为v1alpha3.Configuration结构,其 YAML 顶层字段为kind: Configuration与apiversion: scorecard.operatorframework.io/v1alpha3。

配置示例

仓库测试数据中的一份完整配置(internal/scorecard/testdata/bundle/tests/scorecard/config.yaml)展示了基本结构:

kind: Configuration apiversion: scorecard.operatorframework.io/v1alpha3 metadata: name: config stages: - parallel: true tests: - image: quay.io/operator-framework/scorecard-test:dev entrypoint: - scorecard-test - basic-check-spec labels: suite: basic test: basic-check-spec-test - image: quay.io/operator-framework/scorecard-test:dev entrypoint: - scorecard-test - olm-bundle-validation labels: suite: olm test: olm-bundle-validation-test - image: quay.io/operator-framework/scorecard-test:dev entrypoint: - scorecard-test - olm-crds-have-validation labels: suite: olm test: olm-crds-have-validation-test - image: quay.io/operator-framework/scorecard-test:dev entrypoint: - scorecard-test - olm-crds-have-resources labels: suite: olm test: olm-crds-have-resources-test - image: quay.io/operator-framework/scorecard-test:dev entrypoint: - scorecard-test - olm-spec-descriptors labels: suite: olm test: olm-spec-descriptors-test - image: quay.io/operator-framework/scorecard-test:dev entrypoint: - scorecard-test - olm-status-descriptors labels: suite: olm test: olm-status-descriptors-test

每个测试项的关键字段:

  • image:运行该测试的镜像;
  • entrypoint:测试镜像的入口命令与子命令(如scorecard-test basic-check-spec);
  • labels:测试标签,其中suite与test是约定俗成的两个标签,供--selector过滤使用;
  • storage(可选):测试产物挂载路径,若测试需要输出文件到共享存储卷,可在该项配置storage.spec.mountPath.path,未配置时继承Configuration顶层的storage设置(对应 scorecard.go 中的setTestDefaults)。

stages支持多阶段编排,每个阶段可设置parallel: true(并行执行该阶段全部测试)或false(串行执行)。并行与串行两种执行路径分别实现在 scorecard.go 的runStageParallel(goroutine + WaitGroup)与runStageSequential中。

标签选择器过滤

--selector采用 Kubernetes 标准标签选择器语法(由k8s.io/apimachinery/pkg/labels解析),与每个测试的labels进行匹配。命中逻辑见 scorecard.go 的selectTests():选择器为空或未设置时运行全部测试;设置后仅运行标签匹配的测试。典型用法:

# 仅运行 olm 套件 operator-sdk scorecard ./bundle --selector suite=olm # 仅运行指定名称的测试 operator-sdk scorecard ./bundle --selector test=olm-crds-have-validation-test

--list:先预览再执行

--list(-L)模式不会真正在集群中创建任何资源,而是将配置中(经选择器过滤后)会被执行的测试直接列出。其实现见 internal/scorecard/formatting.go 的Scorecard.List():遍历所有 stage,对每个 stage 执行selectTests()并构造v1alpha3.Test项。该模式对调试配置、确认选择器是否生效非常实用,且无需连接 Kubernetes 集群。

执行流程:从 bundle 到测试 Pod

真正运行时,scorecard 的执行链路(cmd.go + scorecard.go)可概括为:

  1. 解析 bundle:通过registryutil.FindBundleMetadata读取 bundle 元数据;
  2. 创建 ConfigMap:PodTestRunner.Initialize将 bundle 数据打包成 ConfigMap 写入目标命名空间(scorecard.go);
  3. 按 stage 执行测试:对每个 stage 选择测试 → 填充存储默认值 → 并行或串行运行;
  4. 运行单个测试:PodTestRunner.RunTest为每个测试创建scorecard-test-xxxxPod(testpod.go),并轮询等待 Pod 中scorecard-test容器终止(1 秒间隔,wait.PollUntilContextCancel);
  5. 汇总结果:读取 Pod 日志,将 JSON 反序列化为v1alpha3.TestStatus(formatting.go);
  6. 清理:默认删除测试 Pod 与 ConfigMap;超时场景下清理会使用独立的 30 秒上下文保证完成(scorecard.go)。

测试 Pod 的内部结构

从 testpod.go 的getPodDefinition()可以看到每个测试 Pod 的组成:

  • 主容器scorecard-test:运行配置中指定的测试镜像与 entrypoint,挂载/bundle(只读)用于访问解包后的 bundle 数据,并通过 downward API 注入环境变量SCORECARD_NAMESPACE;
  • Init 容器scorecard-untar:使用--untar-image指定的镜像,把 ConfigMap 卷中的bundle.tar.gz解压到/scorecard-bundle;
  • 存储 sidecar(可选):当测试配置了storage.spec.mountPath.path时,addStorageToPod(storage.go)会追加scorecard-storageemptyDir 卷、scorecard-gathersidecar 容器,并注入环境变量SCORECARD_STORAGE,测试产物最终通过exec进入 sidecar 用tar打包拉回本地--test-output目录(按<suite>/<test>组织,见getDestPath)。

Pod 安全上下文

--pod-security参数控制是否以受限安全上下文运行测试 Pod(cmd.go + scorecard.go):

  • legacy(默认):不注入安全上下文,兼容传统命名空间与 RBAC 环境;
  • restricted:为 Pod 设置runAsNonRoot: true、seccompProfile: RuntimeDefault,并为所有容器设置allowPrivilegeEscalation: false、drop: ["ALL"],满足更严格的安全基线要求。

集群连接与命名空间推导

  • kubeconfig 解析(kubeclient.go):依次从--kubeconfig标志、KUBECONFIG环境变量、$HOME/.kube/config、集群内连接(in-cluster)获取客户端;
  • 命名空间推导(kubeclient.go):优先级为--namespace标志 → kubeconfig 中配置的 namespace →default。ServiceAccount 的最终取值也遵循“配置文件中serviceAccount字段优先于--service-account标志”的规则(cmd.go)。

结果输出与退出码

text(默认)

逐条打印每个测试项的MarshalText()结果,最易于阅读。若没有任何测试被选中,会输出0 tests selected(cmd.go)。

json

将整个v1alpha3.TestList以缩进 JSON 输出,便于 CI 脚本用jq等工具解析。每个测试项包含spec(镜像、entrypoint、标签)与status(结果列表、错误、建议)。

xunit

输出标准 XUnit XML(根节点testsuites,名称为scorecard),专为 Jenkins 等 CI 系统设计。转换逻辑见 internal/cmd/operator-sdk/scorecard/xunit/xunit.go:每个测试项生成一个<testsuite>,suite 名称取自labels.test,缺失时按序号命名为testsuite-001;每个测试结果映射为<testcase>,pass→ 成功用例、fail→<failure>、error→<error>,同时记录spec.image、spec.entrypoint、labels.cluster-phase等属性与日志(system-out)。

退出码约定

结果输出完成后,hasFailingTest()(cmd.go)会扫描所有测试结果:只要存在非pass状态的用例(fail 或 error),命令即调用os.Exit(1)结束;全部通过则正常返回 0。这一行为让 scorecard 可以无缝嵌入 CI 流水线作为质量门禁。

内置测试能力一览

默认配置中内置了 basic 与 olm 两套测试(实现见 internal/scorecard/tests/basic.go 与 internal/scorecard/tests/olm.go):

测试套件校验内容
basic-check-specbasic检查 bundle 中示例 CR 是否包含spec字段
olm-bundle-validationolm校验 bundle 格式与内容(CSV、CRD 的 schema 等)
olm-crds-have-validationolm校验 CRD 是否包含 validation(OpenAPI schema)
olm-crds-have-resourcesolm校验 CSV 中 owned CRD 是否声明了resources
olm-spec-descriptorsolm校验示例 CR 的spec字段是否都有 descriptor
olm-status-descriptorsolm校验示例 CR 的status字段是否都有 descriptor

这些测试的镜像需要按配置拉取,若使用quay.io/operator-framework/scorecard-test系列镜像,请确保集群可以访问该镜像仓库。你也可以编写自定义测试镜像并在配置中替换image与entrypoint。

常见问题与排查建议

  • 镜像必须远端可达:传入 bundle 镜像 tag 时必须确保镜像已推送且集群可拉取;离线/断网环境建议改用 bundle 目录形式。
  • 0 tests selected:配置解析正常但选择器没有命中任何测试,可用--list核对配置,并检查labels拼写。
  • 等待超时:默认 30 秒可能不足以完成拉镜像与测试,可调大--wait-time;即使超时,命令也会尽力输出已收集的部分测试结果(见 cmd.go 对context.DeadlineExceeded的处理)。
  • 排查残留资源:测试 Pod 命名带scorecard-test-前缀、标签app=scorecard-test与testrun=<configmap名>,排查时可用--skip-cleanup保留现场,或通过标签手动定位(testpod.go)。

相关命令

scorecard 是operator-sdk命令体系的一员,父命令的完整说明见 operator-sdk。

  • 云原生
  • 后端
  • 开发工具
  • 微服务

【免费下载链接】operator-sdk

SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.

项目地址:https://gitcode.com/gh_mirrors/op/operator-sdk
点击查看免费下载
上一篇:Symfony Yaml 组件实战指南:在 PHP 项目中解析与序列化 YAML 1.2 配置
下一篇:Cloudflare Wrangler 认证完全指南:wrangler login 与 API Token 实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询