如何将Terraform部署的K8s集群数据传递给Kustomize应用部署?
问题:Kustomize Replacements无法从集群读取ConfigMap注入值,如何实现Terraform到ArgoCD的数据传递?
我们用Terraform构建Kubernetes集群,部署分两步:
- 通过Terraform部署基础设施(含K8s集群和EFS存储),配置存于独立仓库;
- 部署ArgoCD存储应用,配置存于另一个独立仓库。
Terraform会把EFS文件系统ID存入集群kube-system命名空间的aws-storage ConfigMap中。我想通过Kustomize的replacements功能读取这个ConfigMap,将EFS ID注入到ArgoCD存储应用的StorageClass清单里。
现有配置
存储应用目录结构
|- apps/ - storage/ - efs-sc.yaml - kustomization.yaml
efs-sc.yaml内容
# apps/storage/efs-sc.yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: efs-sc provisioner: efs.csi.aws.com parameters: provisioningMode: efs-ap fileSystemId: INJECT-FSID directoryPerms: "700"
kustomization.yaml内容
# apps/storage/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - efs-sc.yaml replacements: - source: kind: ConfigMap name: aws-storage namespace: kube-system fieldPath: data.efs-file-system-id targets: - select: kind: StorageClass name: efs-sc fieldPaths: - parameters.fileSystemId
集群中ConfigMap状态
执行kubectl get cm -n kube-system aws-storage -o yaml输出:
apiVersion: v1 data: efs-file-system-id: fs-abcdef12345678 immutable: false kind: ConfigMap metadata: creationTimestamp: "2024-02-14T11:16:47Z" name: aws-storage namespace: kube-system resourceVersion: "704" uid: 007d0b3f-e7ea-4b24-8eb3-8daa83cdc249
遇到的错误
执行kustomize build apps/storage > k.yaml测试时,报错:
Error: nothing selected by ConfigMap.[noVer].[noGrp]/aws-storage.kube-system:data.efs-file-system-id
疑问:
- 是否误解了replacements功能?它能否从运行中集群读取数据注入?还是数据必须作为清单包含在Kustomize部署中?
- 若误解了该功能,还有哪些方法可实现Terraform到ArgoCD的数据传递?
相关版本:
- Kustomize:v5.3.0
- Kubectl客户端:v1.28.3(内置Kustomize v5.0.4-0.20230601165947-6ce0bf390ce3)
- K8s服务器:v1.29.0-eks-c417bb3
解答
关于Kustomize Replacements功能的误解
是的,你确实误解了replacements的工作机制:
- Kustomize是离线工具,仅处理本地文件系统中的Kubernetes清单,不会连接到运行中的K8s集群读取资源。
- replacements功能只能从当前kustomization构建上下文里的资源(即
resources、components等字段引用的本地清单)中提取值,无法直接读取集群中的ConfigMap。
报错的核心原因是:你指定的aws-storage ConfigMap不在当前kustomize的构建资源列表里,工具无法找到这个源对象。
替代实现方案
方案1:Terraform输出值到ArgoCD应用仓库
- 在Terraform代码中添加
output块导出EFS文件系统ID:
output "efs_file_system_id" { value = aws_efs_file_system.main.id description = "EFS file system ID" }
- 使用
local_file资源将输出值写入ArgoCD应用仓库的参数文件:
resource "local_file" "efs_params" { content = "EFS_FILE_SYSTEM_ID=${aws_efs_file_system.main.id}" filename = "../argo-storage-app/params.env" # 路径指向ArgoCD应用仓库对应目录 }
- 在ArgoCD应用的kustomization.yaml中用
vars功能注入值:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - efs-sc.yaml - params-configmap.yaml # 从params.env生成的ConfigMap清单 vars: - name: EFS_FILE_SYSTEM_ID objref: kind: ConfigMap name: efs-params apiVersion: v1 fieldref: fieldpath: data.EFS_FILE_SYSTEM_ID
方案2:ArgoCD应用使用参数化模板
- 将
efs-sc.yaml改为模板文件efs-sc.tpl.yaml:
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: efs-sc provisioner: efs.csi.aws.com parameters: provisioningMode: efs-ap fileSystemId: ${EFS_FILE_SYSTEM_ID} directoryPerms: "700"
- 在ArgoCD Application CR中配置参数替换:
- 通过
parameters字段从Terraform创建的集群内ConfigMap/Secret中拉取值; - 或转为Helm Chart,通过ArgoCD的
values字段传入EFS ID参数。
- 通过
方案3:使用Kustomize外部插件(需启用)
Kustomize支持外部插件,可编写脚本调用kubectl读取集群ConfigMap值并注入:
- 启用插件:设置环境变量
KUSTOMIZE_ENABLE_PLUGINS=true; - 编写脚本获取
aws-storageConfigMap的efs-file-system-id值; - 在kustomization.yaml中引用该插件完成值注入。
注意:此方式需要运行Kustomize的环境具备集群访问权限,且ArgoCD默认禁用插件,需额外配置。
方案4:Terraform直接生成StorageClass清单
让Terraform直接生成包含正确EFS ID的StorageClass文件,推送到ArgoCD应用仓库:
resource "local_file" "storage_class" { content = yamlencode({ kind = "StorageClass" apiVersion = "storage.k8s.io/v1" metadata = { name = "efs-sc" } provisioner = "efs.csi.aws.com" parameters = { provisioningMode = "efs-ap" fileSystemId = aws_efs_file_system.main.id directoryPerms = "700" } }) filename = "../argo-storage-app/efs-sc.yaml" }
内容的提问来源于stack exchange,提问作者Steven Gillies
相关产品推荐
相关产品推荐

