Kustomize 官方 FAQ 深度解析:kubectl 内置版本滞后、load_restrictor 安全限制与字段未被转换的排查指南
2026/9/23 14:04:03 网站建设 项目流程
  • CLI
  • 开发工具
  • 云原生

【免费下载链接】kustomize

Customization of kubernetes YAML configurations

项目地址:https://gitcode.com/gh_mirrors/ku/kustomize
点击查看免费下载

导读:本文以 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 内自由更新。

官方给出的两项并行工作:

  1. 把 kubectl 从 kubernetes/kubernetes 主仓库中迁移出来(预期 Kubernetes ~1.20);
  2. 让 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 引用的文件)仍然可以共享,最佳实践是:

  1. 把资源放在一个带有自己 kustomization 文件的目录中;
  2. 从任何需要使用它的 kustomization 中,把这个目录作为base引用。

这种方式鼓励模块化和可迁移性(relocatability)——整个目录树可以整体移动而不破坏引用关系。

如何按版本禁用限制

v3 时代使用下划线风格的标志:

kustomize build --load_restrictor none $target

v4+ 时代改为连字符风格标志,且取值为枚举字符串:

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
  • 合法取值:LoadRestrictionsRootOnlyLoadRestrictionsNone(代码中兼容处理了旧的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 转换?

问题:比如namePrefixnamespace等变换器没有作用到某个字段上(典型例子见 #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 ...

自定义配置时,仿照此结构补充你期望被namePrefixnamespacenamereference等变换器作用的路径即可。其他默认配置同理,可在 api/internal/konfig/builtinpluginconsts 目录下找到对应的*.go文件(如 images.go、replicas.go、namespace.go 等)。

把修复反馈回上游

官方鼓励:如果你认为某个字段应当被默认转换,可以通过提交 PR 修改默认配置来持久化这一变更,参考历史 PR:#1338、#1348 等。


FAQ 之外的排查工具箱

除了上述三个官方 FAQ 条目,以下仓库资源能帮你更快定位问题:

  • 加载限制的单元测试:api/internal/loader/loadrestrictions_test.go 用真实与模拟文件系统覆盖了RestrictionNoneRestrictionRootOnly的通过/拒绝路径,可作为理解行为的参考;
  • loader 集成测试:api/internal/loader/fileloader_test.go 中的TestRestrictionRootOnlyInRealLoaderTestRestrictionNoneInRealLoader验证了两种限制在真实文件系统上的行为;
  • 转换配置示例:仓库 examples/transformerconfigs 目录提供了 crd 与 images 的自定义转换配置样例及说明文档,是编写kustomizeconfig.yaml的直接模板;
  • 官方文档:更多概念可查阅 site/content/en 下的用户指南。

小结:三个 FAQ 分别对应"版本滞后(依赖解耦)、安全限制(load_restrictor)、字段转换(默认 fieldSpecs 配置)"三大主题。理解其底层源码位置与参数语义后,绝大多数同类问题都能在几分钟内定位并解决。

  • CLI
  • 开发工具
  • 云原生

【免费下载链接】kustomize

Customization of kubernetes YAML configurations

项目地址:https://gitcode.com/gh_mirrors/ku/kustomize
点击查看免费下载

相关推荐

上一篇:CloudNativePG 数据库导入完全指南:microservice 与 monolith 两种逻辑备份迁移方案
下一篇:在WSL2中运行OSX-KVM:Windows用户的终极macOS解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询