设计师周姐开了一家室内设计工作室。她画了一套“标准两居室”图纸:客厅、卧室、厨房、卫生间,每张图都画得一清二楚。开发商找她合作:同一个户型要卖给两个楼盘,东边楼盘厨房台面换大理石,西边楼盘门把手换成金色。周姐不想重画整本图纸,也不想在图纸上写满手写批注——她只在电脑里维护一份“改动说明”,出图时把原图与改动说明叠在一起,自动生成最终版图集。这套思路,正是 Kubernetes 配置工具 Kustomize 的核心理念:一套通用的基础资源,加上按环境叠层的差异记录,合成真正生效的最终配置。本文带你建立这套“图层思维”,学会管理多环境的集群配置。

岗位关联

学 Kustomize 是云原生工程师的基础能力。它让你告别复制粘贴 YAML 的噩梦,用声明式图层管理多环境配置,也是 ArgoCD 等 GitOps 工具链的核心一环,掌握它等于拿到了现代配置交付的入场券。

目录
  1. 可视化演示
  2. Kustomize 引入
  3. Base 基础层
  4. Overlay 覆盖层
  5. Patches 定制
  6. Transformers 变换
  7. Helm 对比
  8. GitOps 工作流
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示Kustomize的Base/Overlay分层覆盖架构、Patches补丁机制与Helm对比,直观理解K8s声明式配置管理的核心原理。

本节配有交互动效(进入视口后自动加载,约 3KB)。

Base与Overlay分层覆盖模式 Base目录存放通用资源定义,所有环境共享的基础配置 每个环境(dev/staging/prod)有独立overlay目录覆盖差异配置 最终配置 = Base + Overlay(dev/staging/prod) 声明式无模板引擎

Kustomize 引入

周姐的工作台上贴着三张便利贴:一张是“户型图集”,一张是“楼盘改动说明”,还有一张是“出图流程”。她不会一张张手绘图纸,而是把原图扫描进电脑,在改动说明里记差异,最后按下按钮,电脑自动合成新版图纸。Kustomize 做的事情,就是 Kubernetes 世界里的这台“合成打印机”。

在 K8s 集群中,每个服务都要写一堆 YAML 描述文件。开发环境、测试环境、生产环境的差异又让这些文件翻倍:单是 nginx 部署,你可能就要维护三份几乎相同的 deployment 文件。Kustomize 通过一个特殊的目录结构来解决这个问题,入口是每个目录中的 kustomization.yaml。

kustomization.yaml 是声明式配置的核心:它用“声明”代替“脚本指令”,明确列出要用哪些资源、要加哪些补丁。Kustomize 没有模板引擎——不会用 {{变量}} 语法做渲染,而是直接组合 YAML。你可以在 kustomization.yaml 中声明 resources、patches、transformers 等字段,然后用 kubectl apply -k 或 kustomize build 得到最终结果。

所以,只要把“图集”和“改动说明”整理好,周姐的“出图流水线”就永远稳定:同一套输入,永远生成同一套输出。这正是 Kustomize 被 GitOps 偏爱的原因——可预测、可审计、可重复。

Rfinal=Build(D)\displaystyle R_{\text{final}} = \text{Build}(D)
这句话的意思是:给定包含 kustomization.yaml 的目录 D,Kustomize 会执行一整套构建工序,输出可直接交付的最终配置 R_final。
  1. 输入目录 D目录中包含 kustomization.yaml 与各种 YAML 资源文件,这是构建的最小工作单元。
    D={kustomization.yaml,deployment.yaml,… }D = \{ \text{kustomization.yaml}, \text{deployment.yaml}, \dots \}
  2. 构建动作 BuildKustomize 按 kustomization.yaml 的声明加载 base 资源并应用 overlay 定制项,就像打印机把图集和改动说明叠印在一起。
    Build(D)=compose(load(D))\text{Build}(D) = \text{compose}(\text{load}(D))
  3. 最终配置 R_final构建输出是完整、可直接 apply 的资源清单,相当于交付给施工队的最终图纸。
    Rfinal→applyClusterR_{\text{final}} \xrightarrow{\text{apply}} \text{Cluster}

Base 基础层

标准两居室户型图集是周姐的看家底本。无论哪个楼盘项目,她都先拿出这本图集:客厅和卧室的尺寸、厨房与卫生间的位置、水电管线的走向——一切都已定稿。图集本身不关心楼盘在哪个城市,也不关心买家预算,它就是“标准答案”。

在 Kustomize 中,base 目录就是这套“标准户型图集”。它是一组与环境无关的 K8s 资源文件,比如 Deployment、Service、ConfigMap。base 中定义了服务的通用镜像、端口、挂载点等,这些内容在 dev、staging、prod 之间保持一致。

base 目录也需要有自己的 kustomization.yaml,在其中用 resources 字段列出所有资源文件。这里的资源集合应尽量避免环境差异——不要出现特定环境的域名、实例数量或专属标签。这类差异应当放到 overlay 层去处理,让 base 保持“干净通用”。

一套底图,十个楼盘都能用。base 的质量直接决定后续所有 overlay 的体验:底图越干净,改动说明就越简单。

B={r1,r2,…,rn}\displaystyle \mathcal{B} = \{ r_1, r_2, \ldots, r_n \}
这条式子是说:base 的本质是一个资源集合,r_i 就是集合中的单个 YAML 对象。
  1. 资源集合 B用花括号表示集合,base 是多个资源组合而成的整体。
    B={…}\mathcal{B} = \{ \ldots \}
  2. 单个资源 r_i其中每个 r_i 都是完整的 K8s 清单文件,例如 Deployment、Service,是“户型图集”中的一页图纸。
    ri∈Br_i \in \mathcal{B}
  3. 环境无关性约束base 中不出现环境专属配置,从而保证它能被所有 overlay 共用。
    ∄ env-specific∈B\nexists \, \text{env-specific} \in \mathcal{B}

Overlay 覆盖层

开发商拿来周姐的底图,提出了新要求:“东边楼盘厨房台面换大理石,西边楼盘门把手换金色”。周姐不会去复印店把整本图纸重画,而是在电脑里建一个“楼盘专属改动层”,每次出图时把底图和改动层叠在一起。

overlay 目录是 base 上叠加的“差异层”。它有自己的 kustomization.yaml,里面用 resources 引用 base 目录的位置,再用 patches 或 transformers 描述要改什么。构建时,Kustomize 会先读取 base 的资源,再依次应用 overlay 上的定制内容。

多环境实践通常把 overlay 按环境组织:overlays/dev、overlays/prod。每个 overlay 都引用同一个 base,环境之间只差差异本身。overlay 还可以继续叠加,构建时按声明顺序进行资源合并。

底图不用动,overlay 画多少就改多少。周姐只需要给每个小区单独准备一张“透明贴纸”,贴纸撕掉,底图还是那张干净的底图。

Rfinal=Render(B,O)\displaystyle R_{\text{final}} = \text{Render}(\mathcal{B}, \mathcal{O})
Render 就是把 base 和 overlay 叠加的过程。overlay 里没写的东西保持 base 原样;写了的东西压过 base 生效。
  1. 基础资源集合 B这是上节定义过的 base 资源集合,相当于“底图”。
    B\mathcal{B}
  2. 覆盖层信息 O代表 overlay 目录中声明的资源与补丁列表,相当于“改动通知单”。
    O={resources,patches,transformers}\mathcal{O} = \{ \text{resources}, \text{patches}, \text{transformers} \}
  3. 渲染合并动作Kustomize 将 B 与 O 按规则合并——标量覆盖、字段保留、列表匹配,最终输出合成后的配置。
    Render(B,O)→Rfinal\text{Render}(\mathcal{B}, \mathcal{O}) \to R_{\text{final}}

Patches 定制

如果开发商说“东边楼盘所有 132 户型的主卧飘窗要加宽 30 厘米”,周姐不需要去重画那页图纸——她只需要在改动说明里记录:定位到主卧飘窗,宽度 +0.3 米。这就是一个“补丁”:只改局部,不碰整体。

Kustomize 的 patches 字段就是干这个的。它提供了一种精确修改资源的方式,不用在 overlay 里重写整个 YAML 文件,而是通过 target 选择目标资源,再用补丁内容指定修改细节。

Patches 的常用类型有两种。第一种是 strategic merge patch:patch 中给出部分字段,Kustomize 按路径与 base 资源合并;字段标量被覆盖、新字段被添加、列表按 name 合并。第二种是 JSON patch:以 JSON 操作指令数组(如 add/replace/remove)精确定位路径,适合那些 strategic merge 无法表达的情形。kustomization.yaml 中可以使用 patches 字段配合 target 进行定位。

补丁是一种优雅的“微创手术”——不重建,只缝合。

P={(t1,d1),(t2,d2),…,(tm,dm)}\displaystyle P = \{ (t_1, d_1), (t_2, d_2), \dots, (t_m, d_m) \}
这表示补丁集合是由多个“目标—内容”对构成的:每个补丁先描述打在哪里(t),再描述改什么(d)。
  1. 目标选择 t_jtarget 通过 group/kind/name 等标识来选择要修改的资源。
    tj=(gj,kj,nj)t_j = (g_j, k_j, n_j)
  2. 补丁内容 d_j包含增量修改内容,只描述变化部分,不描述完整资源。
    dj={op,path,value}d_j = \{ \text{op}, \text{path}, \text{value} \}
  3. 按序应用多个补丁按声明顺序执行,后一个补丁可以修改前一个的结果。
    Papplied=pm∘⋯∘p1(B⊕O)P_{\text{applied}} = p_m \circ \cdots \circ p_1(\mathcal{B} \oplus \mathcal{O})

Transformers 变换

周姐同时接了好几个楼盘的订单,每个楼盘要发的风格不同:一号楼全部统一装金色门把手,二号楼全部换灰色踢脚线。“给所有房间统一换一种东西”的需求,如果逐页标注就太蠢了。

Kustomize 的 transformers 就是这种“全局微整形”。它在构建时对所有资源统一施加变换,不需要每个文件单独写补丁。常见变换有:namePrefix 给所有资源统一加前缀,commonLabels 加上公共标签,images 更新镜像,namespace 统一设置命名空间。

transformers 的威力在于“批量”与“一致”。例如 namePrefix 在多个环境有同名资源时(如 prod 和 dev 都叫 nginx)可以避免冲突;commonLabels 让跨环境筛选资源变得容易。变换是有顺序的,组合顺序决定最终结果。

给所有门装统一拉手,不需要一张张改图纸——写一次变换规则就够了。

R′=τn∘τn−1∘⋯∘τ1(R)\displaystyle \mathcal{R}' = \tau_n \circ \tau_{n-1} \circ \dots \circ \tau_1(\mathcal{R})
这表示:依次应用 τ₁ 到 τₙ 这 n 个变换,把原始资源集合 R 变成新的集合 R'。
  1. 原始配置集 R变换前的资源集合。
    R\mathcal{R}
  2. 变换函数 τ每个 τ 代表一个 transformer,如 namePrefix、commonLabels、images 或 namespace。
    τi∈{namePrefix,commonLabels,images,namespace}\tau_i \in \{ \text{namePrefix}, \text{commonLabels}, \text{images}, \text{namespace} \}
  3. 复合运算(∘)函数组合,先执行 τ₁,再执行 τ₂……最后得到全量变换后的资源集合。
    R′=τn∘⋯∘τ1(R)\mathcal{R}' = \tau_n \circ \cdots \circ \tau_1(\mathcal{R})

Helm 对比

还有一种常见的装修方式:买一套“预制家具包”,内含图纸、零件、安装说明书,按照说明书填写一些选项(沙发颜色、桌子尺寸)就能组装出成品。这是 Helm 的方式。周姐的“底图+改动说明”则是另一条路。

Helm 用模板 + Values 渲染 Chart,Kustomize 用 base + overlay 合成配置。两者目标相同——管理多变的 K8s 配置,但理念差异很大:Helm 模板引擎可以在 YAML 里写循环和条件;Kustomize 完全拒绝模板语法,保持 YAML 的原貌。

适用场景上,Helm 适合把整个应用打包交付给陌生用户(比如开源 redis chart),安装简单、版本明确。Kustomize 适合在已有的内部配置上进行增量定制,特别是“以我的 base 为核心”的场景。复杂度取舍上,Helm 学习成本高一些,Kustomize 更直观但实现不了复杂的编排逻辑。两者还可以组合:Helm 渲染出初始 YAML,再用 Kustomize overlay 做二次覆盖。

预制家具和现场定制各有拥趸;但真正聪明的甲方,往往会先买预制家具,再请周姐上门做局部改动。

R=Templ(V,T)vs.R=Build(B,O)\displaystyle R = \text{Templ}(\mathcal{V}, \mathcal{T}) \quad \text{vs.} \quad R = \text{Build}(\mathcal{B}, \mathcal{O})
两个“公式”分别表示两种生成配置的机制:左侧是 values 注入模板,右侧是 base 加 overlay。
  1. Helm 侧 Templ(V,T)T 是模板文件集合,V 是用户传入的 Values 参数;经过模板渲染得到资源。
    Templ(V,T)=render(inject(V,T))\text{Templ}(\mathcal{V}, \mathcal{T}) = \text{render}(\text{inject}(\mathcal{V}, \mathcal{T}))
  2. Kustomize 侧 Build(B,O)B 是 base 资源集合,O 是 overlay 定制信息;经过构建合成得到资源。
    Build(B,O)=merge(B,apply(O,B))\text{Build}(\mathcal{B}, \mathcal{O}) = \text{merge}(\mathcal{B}, \text{apply}(\mathcal{O}, \mathcal{B}))
  3. 殊途同归两者最终都输出标准 YAML,可交给 kubectl apply 应用。
    output→kubectl apply\text{output} \to \text{kubectl apply}

GitOps 工作流

周姐从土建开始便和所有开发商约定:所有设计图必须存进公司文档库,版本要可追溯,禁止在施工现场改图。开工时,施工队直接从文档库拉最新图纸施工。这就是装修界的“GitOps”。

GitOps 是一种以 Git 为唯一事实来源的部署方式。Kustomize 的配置(base + overlay)整体提交到 Git,CI/CD 或 ArgoCD 在部署时从 Git 拉取目录并执行 kustomize build,然后 apply 到集群。配置文件在 Git 中经历评审、合并、审计,这让多环境之间的差异清晰可见。

ArgoCD 内置 Kustomize 支持,可直接将 Application 的 path 指向 overlay 目录。Git 中的 overlay 更新后,ArgoCD 自动或手动同步,将构建结果应用到目标集群。因为 base 和 overlay 分开维护,环境之间的唯一差异点就是 overlay,这大大降低了环境配置漂移的风险。

周姐的文档库解放了所有项目:改动有人审批,出图自动完成,施工队永远照着最新版本做——而 GitOps 就把这种安全感带给了你的集群。

Cluster←applyGit{Rfinal}\displaystyle \text{Cluster} \xleftarrow{\text{apply}} \text{Git}\left\{R_{\text{final}}\right\}
表示集群状态持续向 Git 中的最终配置收敛:Git 是“规定动作”,Cluster 是“实际动作”。
  1. Git 中的目标状态构建后的最终配置以 git commit 形式存在,代表“应该是什么样”。
    Git{Rfinal}=commit\text{Git}\{R_{\text{final}}\} = \text{commit}
  2. 同步动作 applyGitOps 工具从 Git 拉取变更并 apply 到集群,是“把图纸照进现实”。
    apply(Git{Rfinal},Cluster)\text{apply}(\text{Git}\{R_{\text{final}}\}, \text{Cluster})
  3. 状态收敛集群发生漂移后,GitOps 工具会检测偏差并自动纠正回目标状态。
    Clusteractual→Clusterdesired\text{Cluster}_{\text{actual}} \to \text{Cluster}_{\text{desired}}

AI 应用场景

多环境的模型推理服务部署

阶段:模型服务部署(MLOps)

解决的问题:某个 AI 推理服务需要部署到 dev、staging、prod 三个集群,环境间只差副本数、资源配额和镜像 tag。传统手工维护三份 YAML,改一处经常漏一处,导致环境漂移。Kustomize 用 base 定义通用部分,用三个 overlay 描述环境差异,一处修改全部生效。

具体案例:算法团队交付大模型推理服务(如 vLLM),base 定义 Deployment、Service、HPA,overlays/dev 只设 2 副本,overlays/prod 设置 10 副本并增加 GPU 配额;发布时执行 kubectl apply -k overlays/prod,配置差异一目了然。

ArgoCD 多集群同步中的 Kustomize

阶段:持续交付(GitOps)

解决的问题:多集群环境配置漂移、发布过程不可审计。把 Kustomize 的 base/overlay 源码提交进 Git,ArgoCD 监听仓库路径,overlay 更新后自动同步到目标集群。

具体案例:公司有北京、上海两个 K8s 集群,每套集群跑同一套 AI 平台组件。Git 仓库中 overlays/beijing 与 overlays/shanghai 各自定义资源限额,ArgoCD 分别监听两个路径,任何人提交修改便触发对应集群的自动同步与回滚。

第三方 Helm Chart 的二次定制

阶段:基础设施引入与治理

解决的问题:开源 Chart(如 ingress-nginx)默认配置无法直接满足内部多租户隔离要求,直接改 Chart 又难以跟随上游更新。用 Kustomize overlay 在 Chart 渲染结果上做增量定制,既保留上游兼容性,又满足内部规范。

具体案例:平台团队引入 ingress-nginx 后,用 Kustomize 给所有资源打上 team=platform 标签,并统一设置 namespace 与资源配额,生成的配置通过 GitOps 流程下发到集群。

Python 演示

python64 行
import copyimport json  def merge_dict(base, overlay):    """递归合并字典:标量值以 overlay 为准"""    result = copy.deepcopy(base)    for key, value in overlay.items():        if key not in result:            result[key] = copy.deepcopy(value)        elif isinstance(result[key], dict) and isinstance(value, dict):            result[key] = merge_dict(result[key], value)        elif isinstance(result[key], list) and isinstance(value, list):            result[key] = merge_list(result[key], value)        else:            result[key] = copy.deepcopy(value)    return result  def merge_list(base_list, overlay_list):    """列表合并:按 name 键定位已有项,找不到则追加"""    result = copy.deepcopy(base_list)    for item in overlay_list:        if isinstance(item, dict) and "name" in item:            for i, exist in enumerate(result):                if isinstance(exist, dict) and exist.get("name") == item["name"]:                    result[i] = merge_dict(exist, item)                    break            else:                result.append(copy.deepcopy(item))        else:            result.append(copy.deepcopy(item))    return result  BASE = {    "apiVersion": "apps/v1",    "kind": "Deployment",    "metadata": {"name": "nginx", "labels": {"app": "nginx"}},    "spec": {        "replicas": 3,        "template": {            "spec": {                "containers": [{"name": "nginx", "image": "nginx:1.25"}]            }        }    },} OVERLAY = {    "metadata": {"labels": {"env": "prod"}},    "spec": {        "replicas": 5,        "template": {            "spec": {                "containers": [{"name": "nginx", "image": "nginx:1.26"}]            }        }    },} if __name__ == "__main__":    result = merge_dict(BASE, OVERLAY)    print(json.dumps(result, indent=2, ensure_ascii=False))
目的:用数十行代码模拟 Kustomize 的深合并逻辑——overlay 里的新字段会补进 base,旧字段被覆盖,列表按 name 定位合并。
  1. result = copy.deepcopy(base)深拷贝 base,构建过程不修改原配置。
  2. elif isinstance(result[key], dict) and isinstance(value, dict):两个字典相遇时递归合并,这是 Kustomize 合并的基础。
  3. elif isinstance(result[key], list) and isinstance(value, list):两个列表相遇时走 merge_list,按 name 字段定位。
  4. result[i] = merge_dict(exist, item)找到同名列表项后递归合并,类似 strategic merge patch。
  5. else: result.append(copy.deepcopy(item))for-else 结构,未匹配到 name 时才追加新项。
  6. print(json.dumps(result, indent=2, ensure_ascii=False))输出合并结果,labels 被叠加、replicas 变成 5、镜像更新为 1.26。

常见误区

误区我听说 Kustomize 和 Helm 一样,可以把 YAML 做成模板,用变量渲染出不同配置。所以它应该有类似 `{{ .Values.replicas }}` 的语法。

正解Kustomize 根本没有模板语法,也不执行任何逻辑运算。它先将 base 和 overlay 的资源加载进来,再做合并与变换后输出。Kustomize 更接近“两张图叠印”,而不是“模具灌浆”。参数注入、循环、条件判断都不在 Kustomize 的范围内。

为何常见:因为两者都解决“多环境配置”问题,又都生成最终 YAML,初学者容易把渲染与合并混为一谈。

误区overlay 里写了 Deployment,就能把 base 里的 Deployment 整个覆盖掉,所以我只需要复制一份再改即可。

正解Kustomize 做的是资源合并,而不是替换。若 base 和 overlay 中有同 kind + name 的资源,构建时按“深合并”规则合成一个资源:标量取 overlay、新字段补全、列表按 name 合并。只有刻意使用 replace 类操作时才会整体覆盖。

为何常见:“overlay/覆盖”的命名让人直接联想到“替换”。

误区任何数组都能被 strategic merge 逐项合并,所以 patch 里写一小段就能改大数组。

正解strategic merge 只能对 K8s 资源中有特殊标记的列表做合并,通常要求列表项带 name 字段;否则列表会被整体替换。要更精细地控制路径,应该用 JSON patch 的 add/replace/remove 指令。

为何常见:“merge” 字样以及 K8s 中常见的 patch 场景,让用户以为它能合并一切列表。

误区既然 Kustomize 能做多环境配置,Helm 就没用了;或者反过来,用了 Helm 就不需要 Kustomize。

正解两者解决的问题不同:Helm 以 Chart 为单元打包和发布应用,Kustomize 以 base+overlay 为方法修改现有清单。常见做法是先用 Helm 渲染,再用 Kustomize 覆盖,各取所长。

为何常见:网上大量对比文章给人“竞争关系”的错觉。

误区运行一次 kustomize build,namePrefix 和 commonLabels 就会把我的 base YAML 文件改掉。

正解Kustomize 的构建过程不改动任何源文件,也不写回磁盘。它把内容全部在内存中完成变换,并将结果输出到标准输出。源仓库保持干净、可复用。

为何常见:因为 kustomize build 的输出看起来像是把改动“写进”了资源,容易误以为已经落盘。

面试题

Q1. 在 kubectl apply -k ./overlays/prod 中,-k 参数代表什么?

单选题 · easy

  • A.将 kubeconfig 作为输入
  • B.按 Kustomize 目录构建并应用← 正确答案
  • C.仅保留关键命名空间
  • D.使用 kubectl 内置加密

答案:B。-k 告诉 kubectl 用 Kustomize 构建该目录——它会读取 kustomization.yaml 并渲染出最终配置后再 apply;而 -f 直接使用原文件,不会执行 overlay 合并。

Q2. base 目录设计的核心原则是什么?

单选题 · mid

  • A.只包含环境独立的通用资源← 正确答案
  • B.必须写死所有环境差异
  • C.只能存放 ConfigMap
  • D.禁止创建自己的 kustomization.yaml

答案:A。base 是“标准户型图”,只放与环境无关的通用资源;环境差异全部交给 overlay 处理。如果把环境差异写进 base,就失去了共享复用的意义。

Q3. 以下哪个 transformer 可以为所有资源增加名称前缀?

单选题 · easy

  • A.images
  • B.namePrefix← 正确答案
  • C.namespace
  • D.commonAnnotations

答案:B。namePrefix 会统一给资源的 metadata.name 加上前缀,常用于隔离不同环境或租户的同名资源。images 只改镜像,namespace 只设置命名空间,commonAnnotations 只加注解。

Q4. strategic merge patch 与 JSON patch 的主要区别是什么?

单选题 · mid

  • A.JSON patch 以操作指令数组寻址,strategic merge 按字段深度合并← 正确答案
  • B.strategic merge 无法修改任何列表
  • C.JSON patch 不需要提供 target
  • D.两者的语法完全等价

答案:A。JSON patch 是 add/replace/remove 指令数组,需要精确路径;strategic merge 给出局部对象,Kustomize 按 merge key 与新对象做递归合并。两者语法完全不同,适合不同场景。

Q5. 下列哪些属于 Kustomize 的 transformers?

多选题 · mid

  • A.commonLabels← 正确答案
  • B.namePrefix← 正确答案
  • C.images← 正确答案
  • D.values

答案:ABC。commonLabels、namePrefix、images 都是常见的 Kustomize 变换器,它们会全局修改资源。values 是 Helm 的概念,不属于 Kustomize。

Q6. 当 base 和 overlay 定义了同一个资源时,kustomize build 的结果是什么?

单选题 · mid

  • A.保留两个资源导致冲突
  • B.深合并成为一个资源← 正确答案
  • C.仅保留 overlay 版本
  • D.报错拒绝构建

答案:B。Kustomize 会按 merge 规则将同名资源合并成一个:标量以 overlay 为准,新增字段被补全,列表按 name 匹配合并。既不是替换,也不是报错。

Q7. 关于 strategic merge 对列表的合并,以下说法正确的是?

单选题 · hard

  • A.列表总是被整体替换
  • B.带 name 字段的列表项按 name 合并,否则整体替换← 正确答案
  • C.所有列表都强制拼接
  • D.只有 map 才能被合并

答案:B。strategic merge 的列表合并依赖 merge key(通常是 name)。列表项有 name 时可以定位并合并;没有 name 时无法匹配,默认整体替换。这是 patch 新手常踩的坑。

Q8. 在 GitOps 多环境仓库中,以下哪种做法最能避免配置漂移?

单选题 · extreme

  • A.每个环境各存一份完整 YAML
  • B.所有环境共用 base,差异只写在 overlay 中← 正确答案
  • C.手动同步各环境目录
  • D.直接在集群上修改资源

答案:B。共用 base + overlay 才能让环境间差异显式化。每个环境存独立 YAML 会随着迭代产生大量复制粘贴差异;手动同步和在线修改更无法审计,违背 GitOps 的声明式原则。

Q9. 相比 Helm,Kustomize 的优势有哪些?

多选题 · easy

  • A.使用纯 YAML,无需学习模板语法← 正确答案
  • B.原生支持 kubectl apply -k← 正确答案
  • C.提供版本化 release 管理
  • D.必须配套独立服务端才能运行

答案:AB。Kustomize 没有模板语法,保持 YAML 原貌;它内嵌于 kubectl,无需额外服务。C 是 Helm 的能力,D 描述错误——Kustomize 不需要独立服务端。

Q10. 关于 ArgoCD 使用 Kustomize 管理多环境配置,以下说法正确的有?

多选题 · hard

  • A.可将 path 指向含 overlay 的目录,自动完成构建← 正确答案
  • B.可使用 kustomize.buildOptions 附加额外变换配置← 正确答案
  • C.必须提前提交构建后的 YAML 才能部署
  • D.必须单独部署 Kustomize 服务端

答案:AB。ArgoCD 内置 Kustomize,可以直接从 Git 源码构建,无需提前提交渲染结果,也无需独立部署 Kustomize 服务。buildOptions 可传入额外参数,实现更灵活的构建过程。