KServe KernelCache 工件签名安全配置指南:V1beta1KernelCacheArtifactSecurityConfig 深度解析
KServe KernelCache 工件签名安全配置指南:V1beta1KernelCacheArtifactSecurityConfig 深度解析
导读:本文围绕 KServe KernelCache(内核缓存)子系统中用于"已完成捕获工件(artifact)签名"的安全配置模型
V1beta1KernelCacheArtifactSecurityConfig展开,讲清楚它的三个核心字段(mode、failurePolicy、cert)及其嵌套的证书配置(signingProfileRef、subjectRegexp、trustBundle、trustBundleKey)如何从inferenceservice-configConfigMap 加载、如何被 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"
}
}
}
加载流程的关键步骤:
- 从
isvcConfigMap.Data["kernelcache"]中读取 JSON 字符串并json.Unmarshal到KernelCacheConfig。 - 对未设置字段逐一回填默认值(
mode缺省为cert;cert的三个关键字段缺省时分别回填上述默认常量;failurePolicy缺省为reject)。 - 调用
ArtifactSecurity.ToSecurityConfig()转换为底层安全包契约——其中mode == "" || mode == "none"会被转换为disabled(configmap.go)。 - 调用
securityConfig.Default()与Validate()进行校验:mode必须是disabled或cert,failurePolicy必须是reject或warn。 - 额外的硬性约束(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 对象)。
八、配置实战与排查要点
- 修改配置:编辑
inferenceservice-configConfigMap(默认位于 kserve 命名空间),更新kernelcache.artifactSecurity子块后触发控制器重载;若配置非法,NewKernelCacheConfig会返回明确错误,例如invalid kernelcache.artifactSecurity: unknown security mode或kernelcache.artifactSecurity.failurePolicy must be reject。 - 签名材料准备:
cert模式要求存在可用的签名 Secret(默认键布局tls.key/tls.crt/ca.crt)与信任 bundle(Secret 优先于同名 ConfigMap,默认键ca.crt)。 - 身份约束:务必设置
subjectRegexp并确保签名叶子证书的 SAN 能匹配该正则(默认spiffe://kserve/kernelcache-signer),否则验签方会拒绝签名者身份。 - 关闭安全:如需临时关闭签名/验签,可将
mode设为"none"(等价于disabled),此时既不签名也不验证、永不阻塞。 - 相关资源观测:部署后通过
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 的模型与测试,整条链路在仓库中形成了完整闭环——这也是排查与扩展该安全机制时最值得精读的三段代码。