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

如何在Spring中读取Kubernetes挂载的Secret?

问题:Kubernetes Secret挂载后Spring无法读取的错误排查

Kubernetes Secret挂载配置

你已通过Volume方式挂载Secret,相关配置如下:

volumeMounts:
    - name: test-key
      readOnly: true
      mountPath: /opt/key

问题现象

尝试在Spring中读取该Secret时出现占位符解析错误:

  • 在application.properties中配置:spring.datasource.private-key=${PRIVATE_KEY}
  • 报错信息:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.private-key' in value "${spring.datasource.private-key}"

尝试的代码及问题依旧

更新Spring代码后仍报相同错误:

@Value("${spring.datasource.private-key}")
private String privateKey;

@Bean
public PrivateKey getPrivateKeyFromEnvironmentVariable() throws IOException, NoSuchAlgorithmException {
    List<String> activeProfiles = Arrays.asList(environment.getActiveProfiles());

    String key;
    if(activeProfiles.contains(LOCAL_ENVIRONMENT_NAME) ) {
        key = resourceUtil.asString(LOCAL_PRIVATE_KEY_RESOURCE_PATH);
    } else if(activeProfiles.contains(TEST_ENVIRONMENT_NAME)) {
        key = generatePrivateKey();
    } else {
        //key = System.getenv(PRIVATE_KEY_ENVIRONMENT_VARIABLE_NAME);
        key = privateKey;
    }
    // 后续私钥处理逻辑...
}

错误原因及解决方案

你混淆了Kubernetes Secret的两种使用方式:Volume挂载和环境变量映射,当前的代码逻辑和挂载方式不匹配,导致读取失败。

方案一:直接读取挂载的Secret文件

既然已经用Volume将Secret挂载到/opt/key目录,Spring需要直接读取该目录下的文件内容,而非通过环境变量或配置占位符:

@Bean
public PrivateKey getPrivateKeyFromMountedFile() throws IOException, NoSuchAlgorithmException {
    List<String> activeProfiles = Arrays.asList(environment.getActiveProfiles());
    String key;

    if(activeProfiles.contains(LOCAL_ENVIRONMENT_NAME)) {
        key = resourceUtil.asString(LOCAL_PRIVATE_KEY_RESOURCE_PATH);
    } else if(activeProfiles.contains(TEST_ENVIRONMENT_NAME)) {
        key = generatePrivateKey();
    } else {
        // 读取挂载的Secret文件,文件名对应Secret中的键名
        Path keyPath = Paths.get("/opt/key/private-key");
        key = Files.readString(keyPath);
    }

    // 私钥解析逻辑...
}

注意:/opt/key下的文件名就是你创建Secret时指定的键名,比如用kubectl create secret generic test-key --from-file=private-key=/本地密钥路径创建的Secret,挂载后就会生成/opt/key/private-key文件。

方案二:将Secret映射为环境变量

如果想通过@Value或System.getenv读取,需要修改Kubernetes Pod配置,把Secret映射为环境变量,而非Volume挂载:

env:
  - name: PRIVATE_KEY
    valueFrom:
      secretKeyRef:
        name: test-key
        key: private-key # Secret对应的键名

配置完成后,容器内会生成PRIVATE_KEY环境变量,此时你原来的application.properties配置spring.datasource.private-key=${PRIVATE_KEY}或@Value("${PRIVATE_KEY}")就能正常解析。

为什么当前代码报错?

  1. 你用Volume挂载Secret,但试图通过环境变量PRIVATE_KEY赋值配置项,而该环境变量并未定义(未配置Secret到环境变量的映射),导致Spring无法解析占位符。
  2. 直接使用@Value("${spring.datasource.private-key}")时,这个配置项本身没有被赋值(无论是配置文件还是环境变量都没提供有效值),因此报错。

内容的提问来源于stack exchange,提问作者DiegoMG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:57:22