- CLI
- 开发工具
- 云原生
【免费下载链接】kustomize
Customization of kubernetes YAML configurations
导读:本文以 Kustomize 官方 FAQ 为骨架,逐一拆解开发者最常遇到的三个问题——kubectl 内嵌的 kustomize 为何总是落后、如何理解与绕过
load_restrictor的文件读取安全限制、以及为什么某些字段没有被 kustomize 转换。通过结合本仓库源码,读者将掌握load-restrictor标志的用法与合法取值、configurations字段的自定义机制,以及默认字段转换配置的底层实现位置,能够在实际项目中快速定位并解决这些问题。
目录
- Q1:kubectl 里的 kustomize 为什么不是最新版?
- Q2:安全报错 "file 'foo' is not in or below 'bar'" 是什么?
- Q3:为什么有些字段没有被 kustomize 转换?
- FAQ 之外的排查工具箱
Q1:kubectl 里的 kustomize 为什么不是最新版?
问题:为什么kubectl kustomize内置的 kustomize 版本总是比独立发布的 kustomize 旧?
TLDR(官方结论):这取决于两件事的完成进度——要么把 kubectl 迁出 kubernetes/kubernetes 主仓库,要么改变它的依赖关系。官方预估 ETA 在 Kubernetes ~1.20 前后。
根因分析:Kubernetes 主仓库采用 go modules 之后,破坏了 kustomize 的更新流程。原因在于 kustomize 库依赖了 kubernetes 的 apimachinery 库,而这些库是从 kubernetes 的 staging 目录对外发布的。由于版本依赖链的耦合,kustomize 无法直接在 kubectl 内自由更新。
官方给出的两项并行工作:
- 把 kubectl 从 kubernetes/kubernetes 主仓库中迁移出来(预期 Kubernetes ~1.20);
- 让 kustomize 摆脱对 apimachinery 库的依赖(预期 Kubernetes ~1.20),相关工作跟踪见 kustomize 仓库 issue #2506。
只要上述任一工作完成,官方就会用最新版 kustomize 更新 kubectl。
对用户的实践建议:
- 若你的工作流依赖
kubectl kustomize,请明确其内置版本可能落后于独立发布的 kustomize; - 需要最新功能(如新的转换器、Bug 修复)时,优先使用独立安装的 kustomize 二进制。仓库提供了一键安装脚本,见 hack/install_kustomize.sh,同时 hack/install_kubectl.sh 中也包含配套的 kubectl 安装逻辑;
- 关注 kustomize 仓库 issue #2506 的进展,它是解除版本耦合的关键。
Q2:安全报错 "file 'foo' is not in or below 'bar'" 是什么?
问题:运行kustomize build时遇到如下报错,是什么原因?
security; file 'foo' is not in or below 'bar'背景:kustomize v2.0 开始加入了一项安全检查,禁止 kustomization 读取其自身目录根之外的文件。这一设计初衷是保护那些习惯直接从网上下载 kustomization 目录、未经检查就直接用于生产集群的人(相关讨论见 #693、#700、#995 和 #998)。
官方推荐的正确做法:
资源(包括 configmap 和 secret generator 引用的文件)仍然可以共享,最佳实践是:
- 把资源放在一个带有自己 kustomization 文件的目录中;
- 从任何需要使用它的 kustomization 中,把这个目录作为
base引用。
这种方式鼓励模块化和可迁移性(relocatability)——整个目录树可以整体移动而不破坏引用关系。
如何按版本禁用限制
v3 时代使用下划线风格的标志:
kustomize build --load_restrictor none $targetv4+ 时代改为连字符风格标志,且取值为枚举字符串:
kustomize build --load-restrictor LoadRestrictionsNone $target注意:v4+ 中
--load_restrictor none已被--load-restrictor LoadRestrictionsNone取代,旧式写法不再生效。
源码层面的安全机制
该检查由 loader 组件实现。在 api/internal/loader/loadrestrictions.go 中定义了两个限制策略函数:
RestrictionRootOnly:将路径解析为绝对路径后,用d.HasPrefix(root)校验目标目录是否位于 kustomization 根目录之下,不满足则返回格式化错误"security; file '%s' is not in or below '%s'"(这正是 FAQ 中报错的出处);RestrictionNone:不做任何校验,直接原样返回路径。
默认行为是RestrictionRootOnly,这一点在 api/internal/loader/fileloader.go#L246 中可以看到:loadRestrictor: RestrictionRootOnly。
两种限制策略的枚举定义位于 api/types/loadrestrictions.go:
// Files referenced by a kustomization file must be in // or under the directory holding the kustomization // file itself. LoadRestrictionsRootOnly // The kustomization file may specify absolute or // relative paths to patch or resources files outside // its own tree. LoadRestrictionsNone--load-restrictor标志的合法取值与默认值
标志定义在 kustomize/commands/build/flagloadrestrictor.go:
- 标志名:
--load-restrictor; - 默认值:
LoadRestrictionsRootOnly; - 合法取值:
LoadRestrictionsRootOnly、LoadRestrictionsNone(代码中兼容处理了旧的none值,见getFlagLoadRestrictorValue); - 校验逻辑:传入其他任何值都会报错
illegal flag value --load-restrictor ...,合法值列表随错误信息一起打印。
标志的帮助文本也说明了禁用限制的代价:
"if set to 'LoadRestrictionsNone', local kustomizations may load files from outside their root. This does, however, break the relocatability of the kustomization."
即:放开限制会破坏 kustomization 的可迁移性。
结论:默认且推荐保持LoadRestrictionsRootOnly;只有在你确信需要引用目录树之外的文件,并愿意承担可迁移性损失时,才使用LoadRestrictionsNone。
Q3:为什么有些字段没有被 kustomize 转换?
问题:比如namePrefix、namespace等变换器没有作用到某个字段上(典型例子见 #1319、#1322、#1347 等)。
根因(官方结论):kustomize 转换哪些字段,是由默认配置显式指定的。这份配置位于仓库的 api/internal/konfig/builtinpluginconsts/defaultconfig.go。
从源码看,GetDefaultFieldSpecs将下列内置 fieldSpecs 拼接为默认配置:
namePrefixFieldSpecs nameSuffixFieldSpecs commonLabelFieldSpecs templateLabelFieldSpecs volumeClaimTemplateLabelFieldSpecs commonAnnotationFieldSpecs namespaceFieldSpecs varReferenceFieldSpecs nameReferenceFieldSpecs imagesFieldSpecs replicasFieldSpecs也就是说,只有这些内置列表里登记过的"路径 + kind"组合才会被对应变换器处理。如果你的字段(例如某个 CRD 中的自定义字段、或某个内嵌对象中的 name 引用)不在默认列表中,就不会被转换。
通过configurations自定义转换范围
默认配置本身可以通过在kustomization.yaml中加入configurations来定制,例如:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization configurations: - kustomizeconfig.yaml其中kustomizeconfig.yaml里可以配置以下变换器的字段规则:
commonAnnotations: [] commonLabels: [] nameprefix: [] namespace: [] varreference: [] namereference: [] images: [] replicas: []configurations字段在类型定义中的位置见 api/types/kustomization.go#L169-L170:
// Configurations is a list of transformer configuration files Configurations []string `json:"configurations,omitempty" yaml:"configurations,omitempty"`namereference 配置长什么样
以namereference为例,默认配置位于 api/internal/konfig/builtinpluginconsts/namereference.go,其结构是"目标 kind + 字段路径"的列表。例如:
nameReference: - kind: ConfigMap version: v1 fieldSpecs: - path: spec/volumes/configMap/name version: v1 kind: Pod - path: spec/containers/env/valueFrom/configMapKeyRef/name version: v1 kind: Pod ...自定义配置时,仿照此结构补充你期望被namePrefix、namespace、namereference等变换器作用的路径即可。其他默认配置同理,可在 api/internal/konfig/builtinpluginconsts 目录下找到对应的*.go文件(如 images.go、replicas.go、namespace.go 等)。
把修复反馈回上游
官方鼓励:如果你认为某个字段应当被默认转换,可以通过提交 PR 修改默认配置来持久化这一变更,参考历史 PR:#1338、#1348 等。
FAQ 之外的排查工具箱
除了上述三个官方 FAQ 条目,以下仓库资源能帮你更快定位问题:
- 加载限制的单元测试:api/internal/loader/loadrestrictions_test.go 用真实与模拟文件系统覆盖了
RestrictionNone、RestrictionRootOnly的通过/拒绝路径,可作为理解行为的参考; - loader 集成测试:api/internal/loader/fileloader_test.go 中的
TestRestrictionRootOnlyInRealLoader与TestRestrictionNoneInRealLoader验证了两种限制在真实文件系统上的行为; - 转换配置示例:仓库 examples/transformerconfigs 目录提供了 crd 与 images 的自定义转换配置样例及说明文档,是编写
kustomizeconfig.yaml的直接模板; - 官方文档:更多概念可查阅 site/content/en 下的用户指南。
小结:三个 FAQ 分别对应"版本滞后(依赖解耦)、安全限制(load_restrictor)、字段转换(默认 fieldSpecs 配置)"三大主题。理解其底层源码位置与参数语义后,绝大多数同类问题都能在几分钟内定位并解决。
- CLI
- 开发工具
- 云原生
【免费下载链接】kustomize
Customization of kubernetes YAML configurations
相关推荐
Subtitle Edit 官方 FAQ 深度解读:从格式支持、语音转文字到故障排查的完整指南
Subtitle Edit 官方 FAQ 深度解读:从格式支持、语音转文字到故障排查的完整指南 Subtitle Edit 是一款免费、开源(MIT 许可证)的
音视频桌面应用Borg 备份工具官方 FAQ 全解析:用法、限制、安全与疑难排障实战指南
Borg 备份工具官方 FAQ 全解析:用法、限制、安全与疑难排障实战指南 本篇技术指南以 Borg(Deduplicating archiver with c
运维存储Kedro 官方 FAQ 深度解读:安装排查、配置进阶与数据分层约定的完整实战指南
Kedro 官方 FAQ 深度解读:安装排查、配置进阶与数据分层约定的完整实战指南 导读 :本文以 Kedro 项目官方文档 docs/getting star
数据工程工作流自动化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考