尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Kustomize 结构化数据内嵌 JSON/YAML 的定向替换与合并提案(22-03)深度解析

发布时间:2026/9/23 19:50:24

资讯中心
01
ARTICLE

Kustomize 结构化数据内嵌 JSON/YAML 的定向替换与合并提案(22-03)深度解析

Kustomize 结构化数据内嵌 JSON/YAML 的定向替换与合并提案(22-03)深度解析
CLI开发工具云原生【免费下载链接】kustomizeCustomization of kubernetes YAML configurations项目地址https://gitcode.com/gh_mirrors/ku/kustomize点击查看免费下载本文档基于仓库 proposals/22-03-value-in-the-structured-data.md 展开并结合 api/filters/replacement/replacement.go、api/types/replacement.go、api/types/generatorargs.go 等源码佐证。Kustomize 的传统定位是只做结构化编辑它能够精确地改写 YAML 资源中任意字段却无法触碰字符串字面量string literal内部的内容——例如 ConfigMap 的data.config.json中内嵌的一段 JSON或prometheus.yml里的一段 YAML 配置。本提案编号 22-03状态 implementable提出两项关键能力通过扩展replacements的fieldPath/fieldPaths语义直接定位并改写字符串内部的 JSON/YAML 子结构以及为configMapGenerator/secretGenerator新增mergeValues参数让behavior: merge时按 key 对结构化字符串做递归合并。读完本文你将理解这两个特性背后的设计动机、接口约定、四个完整用户故事以及仓库中对应的源码实现路径。一、背景为什么字符串里的结构是 Kustomize 的盲区Kustomize 能够对 Kubernetes YAML 资源施加结构化编辑structured edits但当某个字段的值本身是一个多行长字符串或长单行字符串如 JSON、YAML 等其他结构化格式数据时从 Kustomize 的视角看这只是一段任意的非结构化字符串。考虑下面这个 ConfigMapapiVersion: v1 kind: ConfigMap metadata: name: target-configmap data: config.json: |- {config: { id: 42, hostname: REPLACE_TARGET_HOSTNAME }}想直接通过replacements把REPLACE_TARGET_HOSTNAME换成集群专属域名传统方式做不到——data.config.json在 Kustomize 眼里只是一个标量字符串无法继续下钻。用户只能整体替换整个 JSON 文件这在一个 base 要覆盖多集群dev/prod时非常痛苦。这一诉求由来已久提案中列出了一系列历史 issue#680、#3787、#4517并且明确指出该功能在大量场景下可以成为已弃用的 vars 的替代方案。二、设计原则在不违背仅结构化编辑核心原则的前提下扩展提案的价值判断非常克制。它强调允许用户标识出包含 JSON/YAML 数据的字符串字面量让 Kustomize 对其中包含的数据做结构化编辑——这样既满足了内嵌数据改写的需求又没有破坏 Kustomize 只支持结构化编辑的核心原则。为此提案明确了三个 Non-goals明确不做的事不提供非结构化编辑unstructured edits这与 Kustomize 拒绝参数化eschews parameterization的立场一致不提供通过patches字段去定位/合并字符串内部值的能力——即该能力仅属于replacements与生成器合并不向 patch 机制扩散不提供对内嵌数据自定义字段合并策略的能力合并行为遵循固定语义。Goals 则只有一个提供一种方式去更新 Kubernetes 对象内以 JSON/YAML 格式存在的结构化数据中的值。三、特性一用replacements改写内嵌结构化数据的值3.1 接口设计扩展fieldPath/fieldPaths的语义提案建议扩展replacements中source.fieldPath与targets.fieldPaths的取值能力。其核心思路是当source.fieldPath与targets.fieldPaths在命中某个 YAML 中的字符串字面量之后仍然带有额外的路径段时Kustomize 将把该字符串解析为结构化数据并用这些额外路径段继续向下钻取。也就是说路径被分成两段前段在 YAML 资源里定位到那个装着结构体的字符串字段后段在这个字符串内部继续定位具体值。3.2 关键语法用\.转义键名中的点由于字段路径默认以.作为分隔符当字符串字面量字段的键名本身含有.例如config.json时必须使用\.转义## replacement replacements: - source: kind: ConfigMap name: source-configmap fieldPath: data.HOSTNAME targets: - select: kind: ConfigMap name: target-configmap fieldPaths: - data.config\.json.config.hostname # config\.json 之后的路径指向结构化数据中的一处这里data.config\.json定位到data[config.json]这个字符串随后的config.hostname则在该字符串解析出的 JSON 结构内部继续下钻。从源码看路径切分由kyaml_utils.SmarterPathSplitter完成见 api/filters/replacement/replacement.go它负责正确处理\.转义。而fieldPath/fieldPaths字段本身的类型定义位于 api/types/replacement.goSourceSelector.FieldPath为单个字符串TargetSelector.FieldPaths为字符串数组TargetSelector还支持select/reject选择器与optionsFieldOptions支持delimiter、index、create等细化解释。3.3 底层实现setValueInStructuredData的完整流程仓库中 api/filters/replacement/replacement.go 的setValueInStructuredData函数完整实现了这一机制其流程可以概括为切分路径用SmarterPathSplitter按.切分识别\.转义寻找标量边界从路径第 1 段开始递增尝试用yaml.Lookup逐段定位找到能解析为结构化数据的标量节点为止——一旦某段命中的节点是ScalarNode且其后还有剩余路径段就尝试yaml.Unmarshal解析其值解析成功即把该段作为字符串字段路径剩余段作为结构化数据路径解析内嵌数据将该标量字符串反序列化为yaml.RNode结构树下钻并写入通过PathMatcher沿structuredDataPath下钻配合FieldOptions.Createcreate: true时允许创建缺失字段找到目标节点调用setFieldValue写入新值标量仅复制 Value 以保留类型自动转换能力回写并保持格式serializeStructuredData根据原始字符串的首字符判断格式——以{或[开头按 JSON 序列化否则回退为 YAML 序列化从而尽量保留原有 JSON/YAML 风格与紧凑/美化格式见 replacement.go。该过滤器由内置 transformer 插件ReplacementTransformerPlugin驱动api/internal/builtins/ReplacementTransformer.go最终通过resmap的ApplyFilter对全部资源生效。这也印证了提案的沿用既有 replacements 接口、不引入新 Kind/CLI 标志的保守设计。四、特性二configMapGenerator/secretGenerator的mergeValues结构化合并4.1 接口设计GeneratorArgs新增mergeValues提案为configMapGenerator和secretGenerator共用的 GeneratorArgs 增加一个参数mergeValues用于在behavior为merge时对同为结构化格式的两个字符串字面量执行递归合并。mergeValues是一个列表每个元素包含两个参数参数含义key用于选中要合并的字符串字面量的键名即 ConfigMap/Secret 数据项的 keyformat指定该字符串字面量的格式必须为YAML或JSON该合并操作属于覆盖 base ConfigMap 值Overriding Base ConfigMap Values能力的一部分在合并两个 ConfigMap/Secret 时对具有相同 key的字符串字面量执行结构化合并。从类型定义上看GeneratorArgs中的Behavior字段取值必须是create/replace/merge三者之一本特性要求behavior: merge才能生效api/types/generatorargs.go。4.2 配置示例configMapGenerator: - name: demo-settings behavior: merge # 本功能要求 behavior: merge。 mergeValues: - key: config.json # 要合并的目标 key。 format: json # 结构化数据格式必须是 YAML/JSON。 literals: - config.json: |- { config: { hostname: REPLACE_TARGET_HOSTNAME, value: { foo: bar } } }合并语义与 Kustomize 一贯的递归合并一致同名字段深度合并不同名字段互补保留详见下文 Story 2 的输入输出对照。五、四个用户故事从需求到完整输入输出Story 1替换 ConfigMap 中 JSON 字符串内的值场景多集群管理中dev/prod 集群需要不同的config.json内容。传统做法只能整体替换整个 JSON 文件本特性允许仅覆盖差异点。源与目标资源## source apiVersion: v1 kind: ConfigMap metadata: name: source-configmap data: HOSTNAME: www.example.com --- apiVersion: v1 kind: ConfigMap metadata: name: target-configmap data: config.json: |- {config: { id: 42, hostname: REPLACE_TARGET_HOSTNAME }}replacement 配置## replacement replacements: - source: kind: ConfigMap name: source-configmap fieldPath: data.HOSTNAME targets: - select: kind: ConfigMap name: target-configmap fieldPaths: - data.config\.json.config.hostname期望结果## expected apiVersion: v1 kind: ConfigMap metadata: name: source-configmap data: HOSTNAME: www.example.com --- apiVersion: v1 kind: ConfigMap metadata: name: target-configmap data: config.json: {config:{hostname:www.example.com,id:42}}注意结果中config.json被序列化为紧凑 JSON键顺序也发生了重排这正是serializeStructuredData按 JSON 格式回写的行为。Story 2用configMapGenerator合并两份 JSON 配置场景许多应用以 JSON 文件承载配置运行在 Kubernetes 上时通过 ConfigMap 挂载。若configMapGenerator能对data中的 JSON 做合并JSON 文件的维护将变得简单。base 侧base/kustomization.yamlconfigMapGenerator: - name: demo literals: - config.json: |- { config: { loglevel: debug, parameter: { foo: bar } } }overlay 侧overlay/kustomization.yamlresources: - ../base configMapGenerator: - name: demo behavior: merge mergeValues: - key: config.json # 要合并的目标 key。 format: json # 结构化数据格式必须是 YAML/JSON。 literals: - config.json: |- { config: { hostname: www.example.com, parameter: { baz: qux } } }合并结果parameter下foo与baz并存loglevel与hostname互补apiVersion: v1 data: config.json: |- { config: { loglevel: debug, hostname: www.example.com, parameter: { foo: bar, baz: qux } } } kind: ConfigMap metadata: name: demo-xxxxxxxxxx # 名称后缀哈希Story 3替换 ConfigMap 中 YAML 字符串内的值场景Prometheus、AlertManager 等云原生应用使用 YAML 格式的配置文件且需要覆盖的值通常位于嵌套 YAML 结构中。若能在 YAML 内部做覆盖就无需复制整个 YAML 文件。源与目标资源## source apiVersion: v1 kind: ConfigMap metadata: name: environment-config data: env: dev --- apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config data: prometheus.yml: |- global: external_labels: prometheus_env: TARGET_ENVIROMENT scrape_configs: - job_name: prometheus static_configs: - targets: [localhost:9090]replacement 配置## replacement replacements: - source: kind: ConfigMap name: environment-config fieldPath: data.env targets: - select: kind: ConfigMap name: prometheus-config fieldPaths: - data.prometheus\.yml.global.external_labels.prometheus_env期望结果## expected apiVersion: v1 kind: ConfigMap metadata: name: environment-config data: env: dev --- apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config data: prometheus.yml: |- global: external_labels: prometheus_env: dev scrape_configs: - job_name: prometheus static_configs: - targets: [localhost:9090]注意这里data.prometheus\.yml后面的global.external_labels.prometheus_env是在 YAML 结构内部下钻由于原始值以 YAML 块标量|-形式存在且首字符不是{/[回写时走 YAML 序列化路径块式格式得以保留。Story 4替换 Annotations 中 JSON 字符串内的值场景部分集群上的应用需要在 Kubernetes 资源的Annotations中写入 JSON 格式配置例如云厂商 Ingress/BackendConfig 注解、AWS Load Balancer Controller 的注解等此时也需要覆盖其中的值。源与目标资源## source apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: debug-backend-config spec: securityPolicy: name: debug-security-policy --- apiVersion: v1 kind: Service metadata: name: appA-svc annotations: cloud-provider/backend-config: {ports: {appA:gke-default-backend-config}} spec: ports: - name: appA port: 1234 protocol: TCP targetPort: 8080replacement 配置## replacement replacements: - source: kind: BackendConfig name: debug-backend-config fieldPath: metadata.name targets: - select: kind: Service name: appA-svc fieldPaths: - metadata.annotations.cloud-provider/backend-config.ports.appA期望结果## expected apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: debug-backend-config spec: securityPolicy: name: debug-security-policy --- apiVersion: v1 kind: Service metadata: name: appA-svc annotations: cloud-provider/backend-config: {ports: {appA:debug-backend-config}} spec: ports: - name: appA port: 1234 protocol: TCP targetPort: 8080这一故事把结构内下钻扩展到了 annotations 场景cloud-provider/backend-config键名中的/无需转义.才是分隔符其后的ports.appA在 JSON 内下钻。这正是提案中从 BackendConfig 的metadata.name取值、写入 Service 注解 JSON 中ports.appA字段的经典用法对应了 GKE Ingress 按端口绑定独立 BackendConfig、以及 AWS Load Balancer Controllerlisten-ports注解等真实需求。六、风险与后续规划提案模板中保留了 Risks、Dependencies、Scalability 等章节当前正文未填充细节符合仓库中 mini enhancement proposal 的轻量流程见 proposals/README.md 中对 Option 2 的描述。值得注意的约束包括依赖控制Kustomize 严格管控 Go 依赖以保证能合入kubectl不能直接依赖 kubectl 或 apimachinery 代码——因此本特性在实现上优先复用kyaml自身的 YAML 解析与PathMatcher能力而不是引入新的解析库格式保持回写时需识别 JSON/YAML 两种格式并尽量保留原始风格这是实现中最容易产生行为差异的部分已由serializeStructuredData处理进阶路径若该特性后续进入kubectl kustomize按 KEP 流程需要经历 Alpha可能以开关门控→ Beta与kubectl kustomize完全对齐→ GA一般等待至少两个 kubectl 发布周期的阶段。七、总结本提案用最小的接口改动扩展fieldPath/fieldPaths语义 GeneratorArgs新增mergeValues解决了 Kustomize 长期无法触碰字符串内结构的痛点且严格守住了仅结构化编辑的核心原则。四个用户故事覆盖了 JSON/YAML 内嵌数据在 ConfigMap data、Prometheus 配置、云厂商 annotations 等典型场景的定向覆盖与递归合并仓库源码api/filters/replacement/replacement.go、api/types/replacement.go、api/types/generatorargs.go也已给出可实现的完整路径。对于在多集群、多环境场景下维护内嵌配置的用户而言这套能力意味着不必再整文件替换、只改差异点。如需继续深入可参考仓库内的相关实现与测试replacementtransformer_test.go、ReplacementTransformer_test.go以及另一份相关提案 21-11-transformer-annotations.md。赞分享CLI开发工具云原生【免费下载链接】kustomizeCustomization of kubernetes YAML configurations项目地址https://gitcode.com/gh_mirrors/ku/kustomize点击查看免费下载相关推荐性能对比分析ANE Transformers vs 传统Transformer在苹果设备上的差异性能对比分析ANE Transformers vs 传统Transformer在苹果设备上的差异 ANE Transformers是针对苹果神经引擎ApplKarmada 中 sigs.k8s.io/yaml 深度解析YAML 与 Go 结构体互转的 JSON 桥接实现Karmada 中 sigs.k8s.io/yaml 深度解析YAML 与 Go 结构体互转的 JSON 桥接实现 本文以 Karmada 仓库中 vendo云原生多集群集群管理微服务Sudachi 模拟器上手指南从源码编译到运行 Switch 游戏的完整流程Sudachi 模拟器上手指南从源码编译到运行 Switch 游戏的完整流程 Sudachi 是一款用 C 编写的 Nintendo Switch 开源模桌面应用移动开发虚拟化上一篇2025最新版adblock-nocoin-list评测拦截率提升30%的秘密下一篇FakeTraveler技术解析Android位置模拟框架的设计与实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。