KServe KernelCache 工件签名安全配置指南:V1beta1KernelCacheArtifactSecurityConfig 深度解析

原创2026-10-11 11:30:48200 阅读
文章标签:模型推理服务云原生后端微服务MLOps人工智能

KServe KernelCache 工件签名安全配置指南:V1beta1KernelCacheArtifactSecurityConfig 深度解析

导读:本文围绕 KServe KernelCache(内核缓存)子系统中用于"已完成捕获工件(artifact)签名"的安全配置模型 V1beta1KernelCacheArtifactSecurityConfig 展开,讲清楚它的三个核心字段(mode、failurePolicy、cert)及其嵌套的证书配置(signingProfileRef、subjectRegexp、trustBundle、trustBundleKey)如何从 inferenceservice-config ConfigMap 加载、如何被 Go 控制器解析并下发默认值、最终如何驱动底层的 cosign 签名与验证流程。读完本文,你将掌握 KernelCache 工件安全在配置层、SDK 层与控制器实现层的完整对应关系,能够独立配置和排查 artifactSecurity 相关的问题。

KServe 的 KernelCache 特性允许把模型推理容器的内核(如 vLLM 加载的模型权重产物)预编译并缓存为 OCI 镜像,从而大幅缩短工作负载就绪时间。而 KernelCacheArtifactSecurityConfig 正是这套链路中负责"安全封口"的配置模型:捕获完成后的工件需要被签名,准备/挂载前的工件需要被验签。以下内容以仓库中的 API 参考文档 为骨架,结合配置样例与源码实现逐层展开。

一、定位:artifactSecurity 在配置体系中的位置

KernelCacheArtifactSecurityConfig 不是孤立存在的。它作为 KernelCacheConfig 的一个嵌套字段,承载于 inferenceservice-config ConfigMap 的 kernelcache 条目中。官方 Python SDK 生成的文档对它的定位是一句话:

"KernelCacheArtifactSecurityConfig configures signing of completed artifacts."(配置已完成工件的签名)

在 V1beta1KernelCacheConfig 文档 中可以看到,KernelCacheConfig 还包含 enabled、defaultMountType、defaultNodeGroup、jobNamespace、mcvImage、prefetchImage、registry、jobTTLSecondsAfterFinished、mcvCaptureReadinessTimeoutSeconds、reconcileIntervalSeconds 等字段,而 artifact_security(artifactSecurity)正是其中负责签名的子块。Go 侧对应的结构体定义在 pkg/apis/serving/v1beta1/configmap.go:

// KernelCacheArtifactSecurityConfig configures signing of completed artifacts.
type KernelCacheArtifactSecurityConfig struct {
	Mode          string                        `json:"mode,omitempty"`
	FailurePolicy string                        `json:"failurePolicy,omitempty"`
	Cert          KernelCacheArtifactCertConfig `json:"cert,omitempty"`
}

配置入口是 ConfigMap 的 kernelcache 键。仓库中 config/configmap/inferenceservice.yaml 给出了完整的示例配置块,其中 artifactSecurity 的官方示例为:

"artifactSecurity": {
  "mode": "cert",
  "failurePolicy": "reject",
  "cert": {
    "signingProfileRef": "kernelcache-signer",
    "trustBundle": "kserve/kernelcache-root-ca",
    "subjectRegexp": "spiffe://kserve/kernelcache-signer"
  }
}

注释明确说明了它的职责:artifactSecurity controls signing after capture and verification before preparation(捕获之后签名、准备之前验签)。

二、属性总览:V1beta1KernelCacheArtifactSecurityConfig 字段表

依据 API 参考文档 中的 Properties 表格,该模型共有三个字段,均为可选(optional):

属性名(Python SDK 命名) JSON 键 类型 说明
cert cert V1beta1KernelCacheArtifactCertConfig 证书签名相关的子配置(证书签名 profile 设置)
failure_policy failurePolicy str 验签失败时的处置策略
mode mode str 安全机制模式,应用于验证与签名两侧

SDK 模型文件中 v1beta1_kernel_cache_artifact_security_config.py 的 openapi_types 与 attribute_map 精确对应上述映射:

openapi_types = {
    'cert': 'V1beta1KernelCacheArtifactCertConfig',
    'failure_policy': 'str',
    'mode': 'str'
}

attribute_map = {
    'cert': 'cert',
    'failure_policy': 'failurePolicy',
    'mode': 'mode'
}

也就是说,Python SDK 中写作 failure_policy 的属性,序列化为 JSON 时使用驼峰键 failurePolicy,与 ConfigMap 中的写法完全一致。

三、字段详解与取值范围

3.1 mode:安全机制模式

mode 决定 KernelCache 工件使用哪种验证/签名机制。从 pkg/kernelcache/types/config.go 与 pkg/kernelcache/types/cert.go 的源码可以看到模式枚举:

const (
	// ModeDisabled performs no verification or signing.
	ModeDisabled Mode = "disabled"
)

// ModeCert verifies a signature made with a cert-manager issued key by checking
// the X.509 chain against a CA bundle plus a signer identity.
const ModeCert Mode = "cert"
  • cert:默认模式。使用 cert-manager 签发的密钥对工件镜像进行 cosign 签名,验签时校验 X.509 证书链(CA bundle)+ 签名者身份(SAN)。
  • disabled:不做任何签名与验证。配置映射中传入 "none" 也会被等价转换为 disabled(见下文 ToSecurityConfig)。
  • 未知模式会在配置校验时直接报错:unknown security mode(config.go)。

3.2 failurePolicy:验签失败时的处置策略

failurePolicy 决定"验证未通过"这一结果如何被消费。源码中定义了两个取值(config.go):

const (
	// FailurePolicyReject blocks use of an image that fails verification.
	FailurePolicyReject FailurePolicy = "reject"

	// FailurePolicyWarn allows use after logging a warning. Intended for
	// migration or development, not production.
	FailurePolicyWarn FailurePolicy = "warn"
)
  • reject:拒绝使用未通过验证的镜像(默认值,生产环境推荐)。
  • warn:允许使用,但记录警告日志,仅供迁移或开发场景使用。
  • 值得注意的是:当前 KServe 控制器在加载配置时强制要求 failurePolicy 必须为 reject(见下文默认值小节),也就是说 warn 枚举存在于底层安全包中,但通过 ConfigMap 直接配置时会被控制器拒绝,这是从源码中得出的明确约束。

3.3 cert:证书签名配置

cert 是嵌套的 V1beta1KernelCacheArtifactCertConfig 对象,官方描述为 "KernelCacheArtifactCertConfig contains certificate signing profile settings"(包含证书签名 profile 设置)。其四个属性如下:

属性名 JSON 键 类型 说明
signing_profile_ref signingProfileRef str 引用的签名 profile 名称(operator 管理)
subject_regexp subjectRegexp str 用于匹配被接受签名者身份(叶子证书 SAN)的正则表达式
trust_bundle trustBundle str 存放 CA 证书的 Secret 或 ConfigMap 引用(namespace/name)
trust_bundle_key trustBundleKey str trust bundle 中存放 CA PEM 的数据键名

对应的 Go 结构体在 pkg/kernelcache/types/cert.go,其字段注释进一步明确了语义:

  • TrustBundle:引用持有 CA 证书的 Secret 或 ConfigMap(形如 namespace/name)。同名 Secret 与 ConfigMap 可同时存在,Secret 优先;bundle 中可以拼接多个 PEM 证书(如根 CA + 中间 CA,或多个 CA 用于轮换),全部作为信任锚点。
  • TrustBundleKey:CA PEM 所在数据键,默认为 ca.crt;如果 bundle 使用了其他键名(如 cabundle.pem、ca-int.crt)则需要显式设置。
  • SubjectRegexp:匹配被接受的签名者身份(叶子证书的 SAN)。验签必需,否则任何能链接到该 CA 的证书都会被接受,失去身份约束。
  • 此外 Go 结构体还包含 SDK 模型未暴露的 SigningSecret(signingSecret)与 SigningKeyKey/SigningCertKey/SigningChainKey(signingKeyKey/signingCertKey/signingChainKey),分别用于签名侧指定签名材料 Secret 与覆盖默认数据键(tls.key/tls.crt/ca.crt)。

四、默认值与配置加载逻辑(源码级)

artifactSecurity 的一大特点是:即使 ConfigMap 中完全没有写这段配置,控制器也会注入一套默认值。逻辑集中在 pkg/apis/serving/v1beta1/configmap.go 的 NewKernelCacheConfig 中:

DefaultKernelCacheArtifactSecurityMode            = "cert"
DefaultKernelCacheArtifactSigningProfileRef       = "kernelcache-signer"
DefaultKernelCacheArtifactTrustBundle             = "kserve/kernelcache-root-ca"
DefaultKernelCacheArtifactSubjectRegexp           = "spiffe://kserve/kernelcache-signer"

即默认配置为:

{
  "artifactSecurity": {
    "mode": "cert",
    "failurePolicy": "reject",
    "cert": {
      "signingProfileRef": "kernelcache-signer",
      "trustBundle": "kserve/kernelcache-root-ca",
      "subjectRegexp": "spiffe://kserve/kernelcache-signer"
    }
  }
}

加载流程的关键步骤:

  1. 从 isvcConfigMap.Data["kernelcache"] 中读取 JSON 字符串并 json.Unmarshal 到 KernelCacheConfig。
  2. 对未设置字段逐一回填默认值(mode 缺省为 cert;cert 的三个关键字段缺省时分别回填上述默认常量;failurePolicy 缺省为 reject)。
  3. 调用 ArtifactSecurity.ToSecurityConfig() 转换为底层安全包契约——其中 mode == "" || mode == "none" 会被转换为 disabled(configmap.go)。
  4. 调用 securityConfig.Default() 与 Validate() 进行校验:mode 必须是 disabled 或 cert,failurePolicy 必须是 reject 或 warn。
  5. 额外的硬性约束(configmap.go):
    • failurePolicy 必须为 reject(非 reject 直接返回错误);
    • cert 模式下 signingProfileRef 不能为空。

SecurityConfig.Default()(types/config.go)同样体现"安全默认"哲学:未设置 mode 默认 disabled(未配置即不验证,而不是直接失败);未设置 failurePolicy 默认 reject。

五、底层实现:cert 模式下的签名与验签

mode: cert 是当前唯一真正执行签名/验签的模式。它不依赖透明日志(Transparency Log)与 SCT,纯粹通过 cosign 的 X.509 证书链校验完成,实现在 pkg/kernelcache/security 包中。

5.1 签名侧:certSigner

cert_sign.go 的 newCertSigner 从签名 Secret 加载材料并做严格校验:

  • 数据键默认按 kubernetes.io/tls 布局 + cert-manager 链键:tls.key(私钥)、tls.crt(叶子证书)、ca.crt(CA 链),可通过 SigningKeyKey/SigningCertKey/SigningChainKey 覆盖;
  • 校验私钥与叶子证书公钥匹配(不匹配直接失败,避免签名后验签时出现难以排查的 "does not verify");
  • 校验叶子证书有效期;
  • 用 x509.ExtKeyUsageCodeSigning 校验叶子证书能链接到提供的 CA 链;
  • 签名时先 remote.Head 解析出镜像 digest,对 digest(而非可变的 tag)签名,将签名绑定到精确内容,然后通过 ociremote.WriteSignatures 写回镜像仓库。

5.2 验证侧:certVerifier

cert_verify.go 的 newCertVerifier:

  • 要求 trustBundle 与 subjectRegexp 均非空(SecurityConfig.Validate 只校验正则语法,必填性由构造器强制);
  • 从 Secret(优先)或 ConfigMap 加载 CA PEM 构建 x509.CertPool;
  • 将 subjectRegexp 锚定为全匹配 ^(?:...)$,以闭合 cosign 默认的"非锚定子串匹配"行为;
  • 验签时 cosign.CheckOpts 设置 IgnoreTlog: true、IgnoreSCT: true、Identities 携带锚定后的 SAN 正则,调用 cosign.VerifyImageSignatures 完成校验。

5.3 失败策略的消费:VerifyResult.ShouldBlock

验证结果与处置策略的解耦在 types/verify.go:

func (r VerifyResult) ShouldBlock(policy FailurePolicy) bool {
	if r.Mode == ModeDisabled || r.Verified {
		return false
	}
	return policy == FailurePolicyReject
}

规则清晰:disabled 模式永不阻塞(有意跳过验证,不算失败);验证通过永不阻塞;验证失败仅在 reject 策略下阻塞。而 VerifyResult.Digest 在镜像可解析时总会填充——即使在 warn 策略下失败,调用方仍可据此固定不可变引用。

六、Python SDK 的使用方式

KServe Python SDK 为这个模型提供了完整定义与测试。模型类位于 python/kserve/kserve/models/v1beta1_kernel_cache_artifact_security_config.py,支持标准的 to_dict()、to_str()、__repr__ 等序列化接口。

测试文件 展示了同时携带全部可选字段的构造方式:

V1beta1KernelCacheArtifactSecurityConfig(
    cert = kserve.models.v1beta1_kernel_cache_artifact_cert_config.V1beta1KernelCacheArtifactCertConfig(
        signing_profile_ref = '0',
        subject_regexp = '0',
        trust_bundle = '0',
        trust_bundle_key = '0',
    ),
    failure_policy = '0',
    mode = '0'
)

对应嵌套模型 V1beta1KernelCacheArtifactCertConfig 与 SDK 文档 V1beta1KernelCacheArtifactCertConfig.md 保持一致。SDK 侧对这些字段不做枚举强校验(均为可选字符串),真正的取值约束由控制器侧(Go)的 Validate() 与 NewKernelCacheConfig 强制执行。

七、端到端观察:签名与验签状态

配置生效后,可通过自定义资源状态直观确认签名/验签结果。docs/samples/kernelcache/README.md 给出了实际观测样例:

  • 捕获工件签名状态(kubectl get kcc -oyaml):
signing:
  message: artifact signing completed
  mode: cert
  reason: SigningSucceeded
  signed: true
  signedAt: "2026-10-08T00:04:50Z"
  state: Succeeded
  • 准备前验签状态(kubectl get kc -oyaml):
verification:
  message: artifact verification completed
  mode: cert
  reason: VerificationSucceeded
  state: Succeeded
  verified: true
  verifiedAt: "2026-10-08T00:04:50Z"

两处状态中的 mode: cert 正是 artifactSecurity.mode 的透传体现。相关状态字段定义在 pkg/apis/serving/v1alpha1/kernel_cache_common_types.go(KernelCacheSigningSpec,其中 profileRef 引用 operator 管理的签名 profile,私钥与凭据不存入 API 对象)。

八、配置实战与排查要点

  1. 修改配置:编辑 inferenceservice-config ConfigMap(默认位于 kserve 命名空间),更新 kernelcache.artifactSecurity 子块后触发控制器重载;若配置非法,NewKernelCacheConfig 会返回明确错误,例如 invalid kernelcache.artifactSecurity: unknown security mode 或 kernelcache.artifactSecurity.failurePolicy must be reject。
  2. 签名材料准备:cert 模式要求存在可用的签名 Secret(默认键布局 tls.key/tls.crt/ca.crt)与信任 bundle(Secret 优先于同名 ConfigMap,默认键 ca.crt)。
  3. 身份约束:务必设置 subjectRegexp 并确保签名叶子证书的 SAN 能匹配该正则(默认 spiffe://kserve/kernelcache-signer),否则验签方会拒绝签名者身份。
  4. 关闭安全:如需临时关闭签名/验签,可将 mode 设为 "none"(等价于 disabled),此时既不签名也不验证、永不阻塞。
  5. 相关资源观测:部署后通过 kubectl get kcc,kc,kcn 查看捕获、缓存与节点状态,通过 kubectl get kcng,kcn -n kserve 查看节点组与节点级状态。

小结

V1beta1KernelCacheArtifactSecurityConfig 是 KServe KernelCache 工件安全链路的配置枢纽:mode 选定机制(cert/disabled)、failurePolicy 决定失败时的阻塞策略(当前控制器强制 reject)、cert 通过 signingProfileRef、subjectRegexp、trustBundle、trustBundleKey 完成 X.509 签名与验证所需的全部材料引用。从 ConfigMap 解析(configmap.go)到类型校验(types/config.go)再到 cosign 实现(security/cert_sign.go、security/cert_verify.go),再到 Python SDK 的模型与测试,整条链路在仓库中形成了完整闭环——这也是排查与扩展该安全机制时最值得精读的三段代码。

登录后查看全文
kserve