资讯动态

Seldon Core 2 存储密钥(Storage Secrets)配置指南:基于 Rclone 安全访问 S3、GCS 与 MinIO 模型工件

发布时间:2026/10/14 2:37:11 来源:尧图企业网站定制
人工智能大模型MLOpsLLMOps模型推理服务云原生后端【免费下载链接】seldon-coreAn MLOps framework to package, deploy, monitor and manage thousands of production machine learning models项目地址https://gitcode.com/gh_mirrors/se/seldon-core点击查看免费下载本篇指南讲解 Seldon Core 2 中如何通过 Rclone 配置存储密钥Storage Secrets让 Model 安全地访问存放在 AWS S3、Google Cloud StorageGCS、MinIO 以及本地文件系统等后端上的推理工件inference artifacts。读完本文你将掌握 Rclone 远端配置的三要素remote name / type / provider parameters、Kubernetes Secret 的承载与校验规则、预加载密钥Preloaded Secrets的集中配置方式以及 Agent 组件底层加载与应用这些配置的完整链路可直接在集群中落地私有或公有对象存储的模型加载。存储密钥解决什么问题在 Seldon Core 2 中Model 通过spec.storageUri指向存放模型工件的远端位置Agent 组件负责把这些工件下载到本地模型缓存后提供给推理服务器加载。这些远端可以落在Rclone 支持的任意存储后端上——包括本地文件系统、AWS S3、Google Cloud StorageGCS等。当存储后端需要认证S3 访问密钥、GCS 服务账号凭据等时就需要把 Rclone 的配置以 Kubernetes Secret 的形式提供给 Agent这就是存储密钥storage secret。它是连接storageUri与真实对象存储之间认证信息的唯一纽带。仓库中对应的核心实现位于 scheduler/pkg/agent/rcloneRCloneClient与 scheduler/pkg/agent/k8s/secrets.goSecret 读取。开箱即用的公共 GCS 配置Seldon Core 2 默认提供一份访问公共 GCS bucket的 Rclone 配置因此可以直接引用 Seldon 官方预置的模型无需任何额外密钥。例如# samples/models/sklearn-iris-gs.yaml apiVersion: mlops.seldon.io/v1alpha1 kind: Model metadata: name: iris spec: storageUri: gs://seldon-models/scv2/samples/mlserver_1.6.0/iris-sklearn requirements: - sklearn memory: 100Ki这个默认能力由名为seldon-rclone-gs-public的 Kubernetes Secret 提供其定义位于 Helm chart 模板 k8s/helm-charts/seldon-core-v2-runtime/templates/rclone-gs-public.yaml内容如下apiVersion: v1 kind: Secret metadata: name: seldon-rclone-gs-public namespace: {{ .Release.Namespace }} type: Opaque stringData: gs: | type: google cloud storage name: gs parameters: anonymous: true注意这里parameters.anonymous: true表示以匿名方式访问公共 bucket无需任何凭据。它被作为预加载密钥preloaded secret默认注入所有 Server因此上面的 Model 不需要也不应该指定secretName。你完全可以照葫芦画瓢用同样的方式定义和使用自己的存储配置。Rclone 配置格式三个核心要素要定义一个新的存储配置需要提供三个要素要素含义说明Remote name远端名Rclone 对该存储位置的命名由你自由命名但spec.storageUri中使用的协议前缀必须与它一致Remote type远端类型Rclone 与该存储通信所使用的协议取 Rclone 支持的类型值例如 AWS S3 为s3、Dropbox 为dropboxProvider parameters提供商参数特定 type/provider 的认证与连接参数取决于远端类型与具体提供商例如s3类型下有 AWS S3、MinIO、Ceph 等多个 provider关于命名匹配从源码 scheduler/pkg/agent/rclone/rclone.go 的getRemoteName可以看出Agent 会把storageUri中:之前的部分解析为 remote name// This method assumes a simple remote URI with no config. e.g. s3://mybucket func getRemoteName(uri string) (string, error) { idx : strings.Index(uri, :) if idx -1 { return , fmt.Errorf(Failed to find : in %s for rclone name match, uri) } if idx 0 { return , fmt.Errorf(Cant get remote from URI with configuration included inline) } name : uri[0:idx] return name, nil }也就是说storageUri: s3://models/iris对应的 remote name 必须是s3storageUri: gcs://my-bucket/...对应的 remote name 必须是gcs。provider 参数完全取决于具体的远端类型与提供商请查阅 Rclone 文档中对应存储类型的说明。有两个容易踩坑的点Rclone 文档中同一参数会同时给出config 格式与env var 格式在 Seldon Core 2 中必须使用config 格式即参数名: 值的 YAML 键值对。例如 GCS 的--gcs-client-id应写作client_id。Rclone 官方config create接口文档中提到的opts选项在本项目中不受支持请不要在配置中使用。在仓库中Agent 解析配置的RcloneConfigCreate结构scheduler/pkg/agent/rclone/rclone.go将name、type、parameters三字段标记为必填并用 validator 校验type RcloneConfigCreate struct { Name string json:name yaml:name validate:required Type string json:type yaml:type validate:required Parameters map[string]string json:parameters yaml:parameters validate:required Opt map[string]string json:opt yaml:opt }parseRcloneConfig会先尝试按 JSON 解析失败再按 YAML 解析json.Unmarshal失败后回退到yaml.Unmarshal因此下面的配置写成 JSON 或 YAML 均可被接受。Kubernetes Secret 承载与两种使用方式Kubernetes Secret 用于存放 Rclone 配置即存储密钥供 Server 使用。每个 Secret 必须恰好包含一个 Rclone 配置——也就是只有一个数据键data key键名可任意键值就是上面格式的配置文本。这一恰好一个键的约束在源码 scheduler/pkg/agent/k8s/secrets.go 的GetSecretConfig中强制实现func (s *SecretHandler) GetSecretConfig(secretName string, timeout time.Duration) ([]byte, error) { ctx, cancel : context.WithTimeout(context.Background(), timeout) defer cancel() secret, err : s.clientset.CoreV1().Secrets(s.namespace).Get(ctx, secretName, metav1.GetOptions{}) if err ! nil { return nil, err } if len(secret.Data) 1 { for _, val : range secret.Data { return val, nil } } if len(secret.StringData) 1 { for _, val : range secret.StringData { return []byte(val), nil } } //TODO allow more than 1 key in secret return nil, fmt.Errorf(Secret does not have 1 key %s, secretName) }可以看到Secret 的data或stringData中键的数量必须恰好为 1否则直接报错Secret does not have 1 key。一个 Server 使用存储密钥有两种方式动态加载由 Model 在.spec.secretName中显式指定一个 SecretServer 在加载该模型时按需从 Kubernetes 拉取对应的 Rclone 配置预加载密钥Preloaded SecretsServer 启动前一次性加载若干 Secret供同一 SeldonRuntime 下管理的所有模型复用。两种方式可以混用——部分 Model 用预加载密钥、部分 Model 用动态加载密钥互不冲突。Secret 的名称、数据键名称都由你自由决定唯一的要求是只有一个数据键且其值是前面描述的 Rclone 配置格式。预加载密钥Preloaded Secrets与其让每个 Model 都显式指定 secret不如让 Server 预先加载一批存储密钥供众多 Model 复用。使用预加载密钥时Model 定义中.spec.secretName应留空但.spec.storageUri的协议前缀仍须与某个已预加载 Secret 中的 remote name 匹配。需要预加载的 Secret 集中登记在一个名为seldon-agent的 ConfigMap 中这个 ConfigMap 作用于同一个 SeldonRuntime 管理的所有 Server。默认情况下它只包含seldon-rclone-gs-public对应 scheduler/k8s/config/agent.yaml 中的默认配置。扩展它只需往config_secrets列表里追加自己的 Secret 名# samples/auth/agent.yaml apiVersion: v1 kind: ConfigMap metadata: name: seldon-agent data: agent.json: |- { rclone : { config_secrets: [seldon-rclone-gs-public,minio-secret] }, }修改这个配置最直接的方式是更新 SeldonRuntime有两条路径路径一通过seldon-core-v2-runtimeHelm chart 配置对应的 values 字段是config.agentConfig.rclone.configSecretsconfig: agentConfig: rclone: configSecrets: - my-s3 - custom-gcs - minio-in-cluster路径二直接配置 SeldonRuntime 对象通过.spec.config.agentConfig.rclone.config_secrets追加 SecretapiVersion: mlops.seldon.io/v1alpha1 kind: SeldonRuntime metadata: name: seldon spec: seldonConfig: default config: agentConfig: rclone: config_secrets: - my-s3 - custom-gcs - minio-in-cluster ...这两种写法与源码中的类型定义一一对应。SeldonConfig CRD 中AgentConfiguration.Rclone同时暴露了config_secrets预加载 Secret 名列表与config原始 Rclone 配置文本列表两个字段见 operator/apis/mlops/v1alpha1/seldonconfig_types.go。Agent 侧的同名配置结构体定义在 scheduler/pkg/agent/config/config.gotype AgentConfiguration struct { Rclone *RcloneConfiguration json:rclone,omitempty yaml:rclone,omitempty Kafka *KafkaConfiguration json:kafka,omitempty yaml:kafka,omitempty } type RcloneConfiguration struct { ConfigSecrets []string json:config_secrets,omitempty yaml:config_secrets,omitempty Config []string json:config,omitempty yaml:config,omitempty }实战示例一S3 MinIO假设 MinIO 已安装在minio-system命名空间对应的存储密钥可以这样定义# samples/auth/minio-secret.yaml apiVersion: v1 kind: Secret metadata: name: minio-secret namespace: seldon-mesh type: Opaque stringData: s3: | type: s3 name: s3 parameters: provider: minio env_auth: false access_key_id: minioadmin secret_access_key: minioadmin endpoint: http://minio.minio-system:9000要点拆解Secret 名为minio-secret位于seldon-mesh命名空间数据键名为s3可任意命名值是 Rclone 的 config 格式配置type: s3表示远端类型为 S3 协议provider: minio指定提供商为 MinIOenv_auth: false关闭环境变量认证改用下面显式给出的access_key_id/secret_access_keyendpoint指向集群内 MinIO 服务的地址。之后在 Model 中通过.spec.secretName引用该 Secret动态加载方式# samples/models/sklearn-iris-minio.yaml apiVersion: mlops.seldon.io/v1alpha1 kind: Model metadata: name: iris spec: storageUri: s3://models/iris secretName: minio-secret requirements: - sklearn注意storageUri的前缀s3必须与 Secret 配置中的name: s3一致Agent 会对此做严格校验详见下文原理部分。实战示例二Google Cloud Storage 服务账号认证GCS 支持使用服务账号service account进行认证。先用 gcloud CLI 为服务账号生成凭据文件gcloud iam service-accounts keys create \ gcloud-application-credentials.json \ --iam-account [SERVICE-ACCOUNT--NAME][PROJECT-ID].iam.gserviceaccount.com然后把gcloud-application-credentials.json的完整内容即其中的 JSON 对象文本嵌入 SecretapiVersion: v1 kind: Secret metadata: name: gcs-bucket type: Opaque stringData: gcs: | type: gcs name: gcs parameters: service_account_credentials: gcloud-application-credentials.json配置要点type: gcs表示远端类型为 Google Cloud Storagename: gcs是 remote nameModel 的storageUri前缀必须为gcsservice_account_credentials是 Rclone 的 GCS provider 属性需要填入服务账号凭据 JSON 的完整内容而非文件路径。随后在 Model 中引用apiVersion: mlops.seldon.io/v1alpha1 kind: Model metadata: name: mymodel spec: storageUri: gcs://my-bucket/my-path/my-pytorch-model secretName: gcs-bucket requirements: - pytorch这样模型加载时 Agent 就会以该服务账号身份访问gcs://my-bucket/my-path/my-pytorch-model。源码级原理Agent 如何加载与应用存储密钥理解了配置方法后深入 Agent 源码可以看清整个链路。配置来源Secret 与原始配置双通道Agent 启动后通过RCloneClient.StartConfigListener加载初始配置并监听配置更新scheduler/pkg/agent/rclone/rclone_config.go。loadRcloneConfiguration会依次执行三件事loadRcloneSecretsConfiguration遍历config.Rclone.ConfigSecrets中的每个 Secret 名调用secretsHandler.GetSecretConfig从 Kubernetes 拉取配置文本再调用r.Config(config)注册到 RcloneloadRcloneRawConfiguration遍历config.Rclone.Config中内联的原始 Rclone 配置文本同样是 JSON/YAML 格式逐个注册deleteUnusedRcloneConfiguration对比当前 Rclone 中已存在的 remotes 与本次新增的 remotes 列表把不在新列表中的远端删除保证配置收敛到预期状态。r.Config内部scheduler/pkg/agent/rclone/rclone.go会先解析并校验配置然后查询该 remote 是否已存在存在则调用 Rclone 的/config/update更新不存在则调用/config/create新建。整个过程通过 Rclone 的 HTTP rc 接口完成涉及的关键端点包括/config/create、/config/update注册或更新远端配置/config/get、/config/listremotes查询远端是否存在、列出全部远端/config/delete删除不再使用的远端/sync/copy把模型工件从远端同步到本地缓存/rc/noop就绪探针Agent 的配置处理器会 watch 挂载的agent.yaml配置文件ConfigMapseldon-agent的挂载配置变更时通过 channel 通知RCloneClient重新加载见 scheduler/pkg/agent/config/config.go 中的NewAgentConfigHandler与StartConfigListener。动态加载链路从 secretName 到 Rclone remote当 Model 指定.spec.secretName时这条链路如下Model CRD 的InferenceArtifactSpec定义了storageUri必填与secretName可选字段operator/apis/mlops/v1alpha1/model_types.go控制器通过Model.AsSchedulerModel()把spec.secretName转换为 scheduler proto 的StorageConfig_StorageSecretName写入模型元数据Agent 处理模型加载请求时getArtifactConfigscheduler/pkg/agent/agent_svc_manager.go根据 StorageConfig 分派若是StorageSecretName则用模型所在命名空间构造SecretsHandler调用GetSecretConfig拉取配置文本若是StorageRcloneConfig则直接使用内联的 Rclone 配置配置文本连同模型信息传给ModelRepository.DownloadModelVersion最终由RCloneClient.Copy完成下载。getArtifactConfig的源码片段印证了这一逻辑switch x : model.GetModelSpec().GetStorageConfig().GetConfig().(type) { case *sched_pb.StorageConfig_StorageRcloneConfig: return []byte(x.StorageRcloneConfig), nil case *sched_pb.StorageConfig_StorageSecretName: ... config, err : am.secretsHandler.GetSecretConfig(x.StorageSecretName, util.K8sTimeoutDefault) ... return config, nil }名称匹配与连接字符串构造无论动态加载还是预加载下载模型时Copy都会调用createUriWithConfigscheduler/pkg/agent/rclone/rclone.go它做两件事严格校验名称匹配从storageUri解析出的 remote name 必须与配置中的config.Name相等否则报错name from URI (%s) does not match secret (%s); are you using the right storage config?。这就是为什么s3://...必须对应名为s3的配置构造连接字符串把配置展开成 Rclone 的连接字符串:type,paramvalue,...值中若含:或,会做引号包裹与转义处理然后替换 URI 前缀后作为srcFs传给/sync/copy。下载的目标目录以modelName srcUri的哈希命名缓存在 Agent 本地路径下dst : fmt.Sprintf(%s/%d, r.localPath, hash)因此同一个模型的多副本可共享同一份工件下载。配置变更与容错copyWithConfigResync体现了容错设计如果/sync/copy首次调用失败可能是 Rclone 服务重启导致配置丢失Agent 会重新加载当前配置再重试一次同步最大化减少瞬态故障对模型加载的影响。测试与验证仓库为上述逻辑提供了充分的单元测试可作为理解与验证的依据scheduler/pkg/agent/rclone/rclone_config_test.go用 httpmock 模拟 Rclone rc 接口覆盖远端 create / update / delete 场景以及badConfig缺少必填字段时校验失败的场景scheduler/pkg/agent/k8s/secrets_test.go验证GetSecretConfig对 Secret 键数量的约束operator/apis/mlops/v1alpha1/model_types_test.go验证secretName到 scheduler protoStorageConfig_StorageSecretName的转换operator/apis/mlops/v1alpha1/seldonconfig_types_test.go验证agentConfig的默认值合并逻辑。部署到集群后可以用kubectl get configmap seldon-agent -n namespace -o yaml确认预加载列表并用 Agent 日志关键词retrieving Rclone secret、creating new Rclone remote、After update current set of remotes观察配置加载过程快速定位问题。小结存储密钥的本质是Rclone 配置的 Kubernetes Secret 载体每个 Secret 恰好一个配置一个数据键配置三要素是 remote name、remote type 与 provider parametersstorageUri前缀必须与 remote name 严格一致两种使用方式Model 级动态加载.spec.secretName与 Server 级预加载seldon-agentConfigMap /agentConfig.rclone.configSecrets可混合使用默认的seldon-rclone-gs-public提供了公共 GCS bucket 的开箱支持Agent 通过 Rclone HTTP rc 接口完成远端的创建、更新、删除与工件同步并对配置变更做热更新与容错重试。相关示例文件均可直接在仓库中找到并复用配置类示例见 samples/auth模型类示例见 samples/models/sklearn-iris-gs.yaml 与 samples/models/sklearn-iris-minio.yaml更多 Kafka 与 TLS 相关的存储/密钥配置可参考 k8s/samples 目录。赞分享人工智能大模型MLOpsLLMOps模型推理服务云原生后端【免费下载链接】seldon-coreAn MLOps framework to package, deploy, monitor and manage thousands of production machine learning models项目地址https://gitcode.com/gh_mirrors/se/seldon-core点击查看免费下载相关推荐Grafana Tempo 使用 Amazon S3 与 S3 兼容对象存储MinIO / SeaweedFS / rclone配置指南Grafana Tempo 使用 Amazon S3 与 S3 兼容对象存储MinIO / SeaweedFS / rclone配置指南 导读 本文基于后端可观测性链路追踪Triton Inference Server模型仓库访问密钥存储安全密钥管理工具Triton Inference Server模型仓库访问密钥存储安全密钥管理工具 在AI模型部署流程中安全管理云存储服务的访问密钥一直是工程师面临的重要挑模型推理服务AI 应用后端FiftyOne Enterprise Secrets 实战指南插件密钥的安全存储、声明与运行时访问FiftyOne Enterprise Secrets 实战指南插件密钥的安全存储、声明与运行时访问 FiftyOne Enterprise 从 1.4.0人工智能计算机视觉数据集数据可视化数据标注模型评测上一篇终极罗技鼠标宏教程5分钟实现绝地求生零后坐力压枪下一篇输入一段文字3分钟拿到数字人口播视频Pixelle-Video 实操手册创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑