GKE中通过ConfigMap向Spring Boot传递参数失败求助
我正在配置应用以在Google Cloud Kubernetes集群(GKE)中运行,希望通过ConfigMap将参数传递给Spring Boot应用的application.properties文件,采用环境变量的方式传递值。
我已在default命名空间创建了如下ConfigMap:
apiVersion: v1 kind: ConfigMap metadata: name: app-config data: config-key: 12345789abde
执行命令:
kubectl create -f app-config.yaml -n default
输出:configmap/app-config created,检查后确认ConfigMap已成功创建,键值对正常。
我使用cloudbuild.yaml部署Spring Boot应用(不使用ConfigMap时部署正常),其内容如下:
substitutions: _CLOUDSDK_COMPUTE_ZONE: us-central1-c # default value _CLOUDSDK_CONTAINER_CLUSTER: kubernetes-cluster-test # default value steps: - id: 'Build docker image' name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/${_TECH_RADAR_PROJECT_ID}/${_TECH_CONTAINER_IMAGE}:$SHORT_SHA', '.'] - id: 'Push image to Container Registry' name: 'gcr.io/cloud-builders/docker' args: ['push', 'gcr.io/${_TECH_RADAR_PROJECT_ID}/${_TECH_CONTAINER_IMAGE}:$SHORT_SHA'] - id: 'Set image in yamls' name: 'ubuntu' args: ['bash','-c','sed -i "s,${_TECH_CONTAINER_IMAGE},gcr.io/${_TECH_RADAR_PROJECT_ID}/${_TECH_CONTAINER_IMAGE}:$SHORT_SHA," deployment.yaml'] - id: 'Create or update cluster based on last docker image' name: 'gcr.io/cloud-builders/kubectl' args: ['apply', '-f', 'deployment.yaml'] env: - 'CLOUDSDK_COMPUTE_ZONE=${_CLOUDSDK_COMPUTE_ZONE}' - 'CLOUDSDK_CONTAINER_CLUSTER=${_CLOUDSDK_CONTAINER_CLUSTER}' - id: 'Expose service to outside world via load balancer' name: 'gcr.io/cloud-builders/kubectl' args: [ 'apply', '-f', 'service-load-balancer.yaml' ] env: - 'CLOUDSDK_COMPUTE_ZONE=${_CLOUDSDK_COMPUTE_ZONE}' - 'CLOUDSDK_CONTAINER_CLUSTER=${_CLOUDSDK_CONTAINER_CLUSTER}' options: logging: CLOUD_LOGGING_ONLY
引用ConfigMap的deployment.yaml内容如下(容器同样位于default命名空间):
apiVersion: "apps/v1" kind: "Deployment" metadata: name: "java-kubernetes-clusters-test" namespace: "default" labels: app: "java-kubernetes-clusters-test" spec: replicas: 3 selector: matchLabels: app: "java-kubernetes-clusters-test" template: metadata: labels: app: "java-kubernetes-clusters-test" spec: containers: - name: "app" image: "kubernetes-cluster-test-image" env: - name: CONFIG_KEY valueFrom: configMapKeyRef: name: app-config key: config-key
部署到Google Cloud时,Spring Boot无法读取占位符,出现错误。
我在application.properties中引用名为CONFIG_KEY的环境变量:
com.example.dockerkubernetes.property.value=${CONFIG_KEY}
并在Spring Boot控制器中使用:
@RestController @RequiredArgsConstructor public class MyController { @Value("${com.example.dockerkubernetes.property.value}") private String testValue; public String getConfigMapTestKey() { return this.testValue; } }
请问问题出在哪里?是否是权限缺失导致的?
首先明确:GKE默认的default服务账号拥有读取同命名空间ConfigMap的权限,权限问题概率极低。以下是逐步排查点和修复方案:
1. 验证环境变量是否正确注入到Pod中
先确认Kubernetes是否成功将ConfigMap的值注入为环境变量:
- 列出default命名空间的Pod:
kubectl get pods -n default - 进入任意一个Pod查看环境变量:
检查输出中是否存在kubectl exec -it <你的Pod名称> -n default -- envCONFIG_KEY=12345789abde:- 如果没有这个变量:说明Deployment的配置未生效,或者ConfigMap的名称/键名有误。检查Deployment的实际运行配置:
确认kubectl get deployment java-kubernetes-clusters-test -n default -o yamlspec.template.spec.containers[0].env部分和你编写的一致,没有被Cloud Build的sed命令意外修改。 - 如果有这个变量:说明问题出在Spring Boot应用内部。
- 如果没有这个变量:说明Deployment的配置未生效,或者ConfigMap的名称/键名有误。检查Deployment的实际运行配置:
2. 排查Spring Boot配置问题
如果环境变量已存在但Spring无法解析:
- 查看Pod的应用日志,确认错误类型:
如果日志显示kubectl logs <你的Pod名称> -n defaultCould not resolve placeholder 'CONFIG_KEY',可能是应用启动时环境变量加载异常,或者你自定义了Spring的PropertySources配置、禁用了环境变量读取。 - 确认Spring Boot默认行为:Spring Boot会自动读取环境变量作为配置源,
application.properties中的${CONFIG_KEY}会直接映射到同名环境变量,无需额外配置。 - 检查控制器代码:你的
getConfigMapTestKey()方法没有添加请求映射注解(如@GetMapping),导致无法通过HTTP请求访问。修改代码:@RestController @RequiredArgsConstructor public class MyController { @Value("${com.example.dockerkubernetes.property.value}") private String testValue; @GetMapping("/config-test") public String getConfigMapTestKey() { return this.testValue; } }
3. 排查Cloud Build的镜像替换逻辑
你的Cloud Build步骤中使用sed命令替换镜像名,可能会误替换Deployment中其他包含${_TECH_CONTAINER_IMAGE}字符串的内容。建议改用更安全的方式:
- 使用
kustomize管理Deployment,通过images字段替换镜像名,避免sed的误操作。 - 或者在sed命令中使用更精确的匹配,只替换
image:后面的内容:sed -i "s,image: ${_TECH_CONTAINER_IMAGE},image: gcr.io/${_TECH_RADAR_PROJECT_ID}/${_TECH_CONTAINER_IMAGE}:$SHORT_SHA," deployment.yaml
4. 触发Pod滚动更新
如果Deployment配置正确但Pod还是旧的,可以手动触发滚动更新:
kubectl rollout restart deployment java-kubernetes-clusters-test -n default
确保所有Pod都基于最新的配置启动。
内容的提问来源于stack exchange,提问作者Krzysztof Michalski

