Helm模板循环合并值时出现脏数据问题求助
解决Helm循环中extraContainers值残留问题
问题根源
执行helm template时,extra-container2意外继承了extra-container1的资源配置和FOO=BAR环境变量,而非使用.Values.app的默认值。这是因为循环中使用的mustMergeOverwrite是原地修改第一个参数的破坏性合并函数,第一次迭代会修改原始的.Values.app对象,后续迭代复用被污染的对象导致值残留。
解决方案
每次合并配置前,先创建.Values.app的深拷贝,基于干净的副本进行合并操作,避免修改原始默认配置对象。
修改后的deployment.yaml循环代码
containers: {{- include "app.container" (merge .Values.app $) | nindent 8 }} {{- range $k, $v := .Values.extraContainers }} {{- $nameDict := dict "name" $k -}} {{- $cleanBase := deepCopy $.Values.app -}} {{- include "app.container" (mustMergeOverwrite $cleanBase $nameDict $v) | nindent 8 }} {{- end }}
替代方案(兼容低版本Helm)
如果你的Helm版本低于3.5(不支持deepCopy),可以使用merge函数替代mustMergeOverwrite——merge会返回新的合并对象,不会修改原始参数。注意参数顺序:自定义配置在前,默认配置在后,确保自定义配置优先级更高。
containers: {{- include "app.container" (merge .Values.app $) | nindent 8 }} {{- range $k, $v := .Values.extraContainers }} {{- $nameDict := dict "name" $k -}} {{- include "app.container" (merge $v $nameDict $.Values.app) | nindent 8 }} {{- end }}
原理说明
mustMergeOverwrite:直接修改第一个传入的对象,将后续对象的配置覆盖进去,会污染原始的默认配置。deepCopy:创建原始对象的完全独立副本,每次循环都基于干净的默认配置进行合并,彻底避免值残留。merge:返回新的合并结果对象,不修改任何传入的参数,同样能避免原始配置被污染。
内容的提问来源于stack exchange,提问作者gurpsone
相关产品推荐
相关产品推荐

