用 base 与 overlay 做出环境差异
目标
从一个 base 生成 dev、prod 两个环境,并能将这些 overlay 连接为 ArgoCD Application 的源。
为什么重要
按环境复制 YAML 管理,必然会逐渐分叉;分叉后无人知道哪边才正确,“dev 明明可以”也由此开始。overlay 让公共部分只写一次,仅把差异保留为文件,从结构上阻止分叉。本实验尤其要观察 configMapGenerator 的哈希后缀:配置内容变化时 ConfigMap 名称改变,引用它的 Pod 模板也改变,从而自动触发 rollout。没有哈希时,只更新 ConfigMap,Pod 却继续使用旧配置,这是最难排查的事故之一。最后还会了解 ArgoCD 处理 Helm 的方式:ArgoCD 不执行 helm install,而是在 repo-server 中用 helm template 渲染后 apply。因此集群中运行 helm list 看不到内容,回滚依靠 git 提交而不是 Helm revision。
步骤
- base 指令文件为
/root/gitops/kustomize/base/kustomization.yaml。把/opt/lab/fixtures/gitops/seed/deployment.yaml和service.yaml复制到/root/gitops/kustomize/base/,在同一目录创建kustomization.yaml。写入apiVersion: kustomize.config.k8s.io/v1beta1、kind: Kustomization,并在resources中列出两个文件名。base 的spec.replicas设为2(设为 1 将失败)。 - 用
kustomize build /root/gitops/kustomize/base > /root/gitops/kustomize/out/base.yaml保存结果。结果必须包含kind: Deployment和kind: Service,不得包含kind: Kustomization。 - 在 base 的
kustomization.yaml中加入namePrefix: labhub-,并添加公共标签app.kubernetes.io/part-of: labhub-platform(labels:下的- pairs:形式或commonLabels:均可)。重新构建并更新out/base.yaml后,Deployment 名称应为labhub-web,Service 的metadata.labels也应包含该标签。 - 创建
/root/gitops/kustomize/overlays/dev/kustomization.yaml。resources第一项为../../base,namespace为gitops-dev,nameSuffix为-dev。使用kustomize build /root/gitops/kustomize/overlays/dev > /root/gitops/kustomize/out/dev.yaml保存。 - 在 dev overlay 中放置战略合并补丁文件(如
patch-deployment.yaml),并在kustomization.yaml的patches中写入路径。补丁须把 Deployment 的spec.replicas降为1,并为容器web添加环境变量LOG_LEVEL=debug。补丁的metadata.name使用base 中的原始名称web。base 的 replicas 仍须为2。重新构建并更新out/dev.yaml。 - 在 dev overlay 的
kustomization.yaml中使用configMapGenerator创建名为app-config的 ConfigMap(如在literals中写LOG_FORMAT=json)。再在第 5 步补丁中让容器web通过envFrom的configMapRef.name: app-config引用它。重新构建后,ConfigMap 名称末尾应有内容哈希,Deployment 引用名也应更新为带哈希的名称。在/root/gitops/kustomize/out/hash-note.txt中用中文说明哈希后缀使配置变更触发 Pod rollout。 - 在
argocd命名空间创建kind: Application、metadata.name: platform-helm。在spec.source.helm.valueFiles中加入values-prod.yaml;在spec.source.helm.parameters中加入名称image.tag和一个值(如1.27.3);spec.source.targetRevision使用非HEAD的固定值(如v1.4.0)。 - 创建
/root/gitops/kustomize/overlays/prod/overlay:resources为../../base,namespace为gitops-prod,用补丁把spec.replicas设为3或更大,并通过images把镜像标签改成与 dev 不同的值(如name: nginx、newTag: 1.27.3)。将构建结果保存到/root/gitops/kustomize/out/prod.yaml。随后在argocd命名空间创建kind: Application、metadata.name: web-dev;spec.source.path必须包含overlays/dev,spec.source.kustomize.images至少包含一个镜像覆盖项。
参考
- 创建第 7、8 步 Application 前须先注册 ArgoCD CRD。与前一个实验一样,从
/opt/crds/的离线包中查找并应用(grep -l applications.argoproj.io /opt/crds/*.yaml)。 kustomize build将结果写到标准输出。重定向前先创建输出目录(/root/gitops/kustomize/out/)。- 即使添加了名称前缀,补丁仍用base 中的原始名称查找目标。若提示找不到目标,也可不用
patches,改用旧式patchesStrategicMerge。 - 常见错误 1:为了让 dev replicas 为 1 而修改 base,这会让 prod 也变成 1。base 是公因子,环境专属值属于 overlay。
- 常见错误 2:修改 overlay 后不重新构建。评分读取
out/*.yaml,每次修改配置都必须重新保存相应构建结果。
配置 kustomize base
base 指令文件为 /root/gitops/kustomize/base/kustomization.yaml。把 /opt/lab/fixtures/gitops/seed/deployment.yaml 和 service.yaml 复制到 /root/gitops/kustomize/base/,在同一目录创建 kustomization.yaml。写入 apiVersion: kustomize.config.k8s.io/v1beta1、kind: Kustomization,并在 resources 中列出两个文件名。base 的 spec.replicas 设为 2(设为 1 将失败)。
kustomization.yaml 是指令文件而非清单。resources 中列出的名称必须真实存在于同一目录。
保存 base 构建结果
用 kustomize build /root/gitops/kustomize/base > /root/gitops/kustomize/out/base.yaml 保存结果。结果必须包含 kind: Deployment 和 kind: Service,不得包含 kind: Kustomization。
把 kustomize build 디렉터리 的标准输出写入文件。结果中不应混入指令文件本身,因为它不是产物。
添加名称前缀与公共标签
在 base 的 kustomization.yaml 中加入 namePrefix: labhub-,并添加公共标签 app.kubernetes.io/part-of: labhub-platform(labels: 下的 - pairs: 形式或 commonLabels: 均可)。重新构建并更新 out/base.yaml 后,Deployment 名称应为 labhub-web,Service 的 metadata.labels 也应包含该标签。
名称变换和标签都在 base kustomization 中声明。可使用新版 labels 的 pairs 或旧版 commonLabels。修改后必须重新构建,结果文件才会变化。
创建 dev overlay
创建 /root/gitops/kustomize/overlays/dev/kustomization.yaml。resources 第一项为 ../../base,namespace 为 gitops-dev,nameSuffix 为 -dev。使用 kustomize build /root/gitops/kustomize/overlays/dev > /root/gitops/kustomize/out/dev.yaml 保存。
overlay 通过相对路径把 base 放入 resources。命名空间和名称后缀由 overlay 决定,构建结果单独保存为 dev 文件。
用补丁覆盖 base
在 dev overlay 中放置战略合并补丁文件(如 patch-deployment.yaml),并在 kustomization.yaml 的 patches 中写入路径。补丁须把 Deployment 的 spec.replicas 降为 1,并为容器 web 添加环境变量 LOG_LEVEL=debug。补丁的 metadata.name 使用base 中的原始名称 web。base 的 replicas 仍须为 2。重新构建并更新 out/dev.yaml。
不要修改 base。补丁文件使用 base 中的原始名称,且容器名称必须正确才能合并。
连接配置生成器与哈希后缀
在 dev overlay 的 kustomization.yaml 中使用 configMapGenerator 创建名为 app-config 的 ConfigMap(如在 literals 中写 LOG_FORMAT=json)。再在第 5 步补丁中让容器 web 通过 envFrom 的 configMapRef.name: app-config 引用它。重新构建后,ConfigMap 名称末尾应有内容哈希,Deployment 引用名也应更新为带哈希的名称。在 /root/gitops/kustomize/out/hash-note.txt 中用中文说明哈希后缀使配置变更触发 Pod rollout。
生成器创建的名称末尾带内容哈希。工作负载引用该 ConfigMap 时,引用名也会同步更新——理解它为何有用是本步骤的核心。
编写使用 Helm 源的 Application
在 argocd 命名空间创建 kind: Application、metadata.name: platform-helm。在 spec.source.helm.valueFiles 中加入 values-prod.yaml;在 spec.source.helm.parameters 中加入名称 image.tag 和一个值(如 1.27.3);spec.source.targetRevision 使用非 HEAD 的固定值(如 v1.4.0)。
环境值文件与每次部署变化的单独参数位于不同位置。若 revision 指向分支最新值,同一声明在不同时刻会部署不同内容。
创建基于 overlay 的 Application 与 prod 构建
创建 /root/gitops/kustomize/overlays/prod/ overlay:resources 为 ../../base,namespace 为 gitops-prod,用补丁把 spec.replicas 设为 3 或更大,并通过 images 把镜像标签改成与 dev 不同的值(如 name: nginx、newTag: 1.27.3)。将构建结果保存到 /root/gitops/kustomize/out/prod.yaml。随后在 argocd 命名空间创建 kind: Application、metadata.name: web-dev;spec.source.path 必须包含 overlays/dev,spec.source.kustomize.images 至少包含一个镜像覆盖项。
prod overlay 使用与 dev 相同的 base,但命名空间、副本数和镜像标签必须不同。Application 中也有专门替换镜像标签的位置。