You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 -- env
    
    检查输出中是否存在CONFIG_KEY=12345789abde:
    • 如果没有这个变量:说明Deployment的配置未生效,或者ConfigMap的名称/键名有误。检查Deployment的实际运行配置:
      kubectl get deployment java-kubernetes-clusters-test -n default -o yaml
      
      确认spec.template.spec.containers[0].env部分和你编写的一致,没有被Cloud Build的sed命令意外修改。
    • 如果有这个变量:说明问题出在Spring Boot应用内部。

2. 排查Spring Boot配置问题

如果环境变量已存在但Spring无法解析:

  • 查看Pod的应用日志,确认错误类型:
    kubectl logs <你的Pod名称> -n default
    
    如果日志显示Could 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:45:36