Secrets PropertySource

Kubernetes 引入了 Secrets 概念,用于存储密码、OAuth 令牌等敏感数据。本项目提供了与 Secrets 的集成,使 Spring Boot 应用能够访问 Secrets。你可以通过设置 spring.cloud.kubernetes.secrets.enabled 属性来显式启用或禁用此功能。

启用后,Fabric8SecretsPropertySource 会从以下来源在 Kubernetes 中查找 Secrets

  1. 递归读取 Secrets 挂载

  2. 以应用名称命名(由 spring.application.name 定义)

  3. 匹配特定标签

注意

默认情况下,出于安全原因,通过 API 使用 Secrets(上述第 2 和第 3 点)未启用。对 secrets 拥有 'list' 权限允许客户端检查指定命名空间中的 secrets 值。此外,我们建议容器通过挂载卷的方式共享 secrets。

如果你通过 API 启用 Secrets 使用,我们建议你使用授权策略(如 RBAC)限制对 Secrets 的访问。有关通过 API 使用 Secrets 的风险和最佳实践的更多信息,请参阅此文档

如果找到 secrets,其数据将可供应用使用。

假设我们有一个名为 demo 的 Spring Boot 应用,它使用属性读取数据库配置。我们可以使用以下命令创建一个 Kubernetes secret

kubectl create secret generic db-secret --from-literal=username=user --from-literal=password=p455w0rd

上述命令将创建以下 secret(你可以使用 kubectl get secrets db-secret -o yaml 命令查看)

apiVersion: v1
data:
  password: cDQ1NXcwcmQ=
  username: dXNlcg==
kind: Secret
metadata:
  creationTimestamp: 2017-07-04T09:15:57Z
  name: db-secret
  namespace: default
  resourceVersion: "357496"
  selfLink: /api/v1/namespaces/default/secrets/db-secret
  uid: 63c89263-6099-11e7-b3da-76d6186905a8
type: Opaque

请注意,数据包含由 create 命令提供的字面值的 Base64 编码版本。

你的应用随后可以使用此 secret — 例如,将其值导出为环境变量

apiVersion: v1
kind: Deployment
metadata:
  name: ${project.artifactId}
spec:
   template:
     spec:
       containers:
         - env:
            - name: DB_USERNAME
              valueFrom:
                 secretKeyRef:
                   name: db-secret
                   key: username
            - name: DB_PASSWORD
              valueFrom:
                 secretKeyRef:
                   name: db-secret
                   key: password

你可以通过多种方式选择要使用的 Secrets

  1. 通过列出 secrets 映射的目录

    -Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql

    如果你的所有 secrets 都映射到一个公共根目录,你可以像这样设置它们

    -Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
  2. 通过设置命名 secret

    -Dspring.cloud.kubernetes.secrets.name=db-secret
  3. 通过定义标签列表

    -Dspring.cloud.kubernetes.secrets.labels.broker=activemq
    -Dspring.cloud.kubernetes.secrets.labels.db=postgresql

ConfigMap 一样,也可以进行更高级的配置,你可以使用多个 Secret 实例。spring.cloud.kubernetes.secrets.sources 列表使得这成为可能。例如,你可以定义以下 Secret 实例

spring:
  application:
    name: cloud-k8s-app
  cloud:
    kubernetes:
      secrets:
        name: default-name
        namespace: default-namespace
        sources:
         # Spring Cloud Kubernetes looks up a Secret named s1 in namespace default-namespace
         - name: s1
         # Spring Cloud Kubernetes looks up a Secret named default-name in namespace n2
         - namespace: n2
         # Spring Cloud Kubernetes looks up a Secret named s3 in namespace n3
         - namespace: n3
           name: s3

在前面的示例中,如果未设置 spring.cloud.kubernetes.secrets.namespace,则名为 s1Secret 将在应用运行的命名空间中查找。请参阅Namespace 解析以更好地理解应用命名空间的解析方式。

类似于 ConfigMaps;如果你希望应用在无法加载 Secrets property sources 时启动失败,可以设置 spring.cloud.kubernetes.secrets.fail-fast=true

也可以为 Secret property sources 启用重试,类似于 ConfigMaps。与 ConfigMap property sources 一样,首先需要设置 spring.cloud.kubernetes.secrets.fail-fast=true。然后需要将 spring-retryspring-boot-starter-aop 添加到类路径中。可以通过设置 spring.cloud.kubernetes.secrets.retry.* 属性来配置 Secret property sources 的重试行为。

如果由于某种原因你的类路径中已经有 spring-retryspring-boot-starter-aop,并且想要启用 fail-fast 但不想启用重试;你可以通过设置 spring.cloud.kubernetes.secrets.retry.enabled=false 来禁用 Secrets PropertySources 的重试。

由于来自 Secrets 的数据通常被视为敏感数据,因此可以对 actuator 的 /env/configprops 端点进行数据清理,使其不以纯文本形式显示。为此,你需要设置

spring.cloud.kubernetes.sanitize.secrets=true

此设置从 3.0.6 版本及更高版本开始支持。

表 1. 属性
名称 类型 默认值 描述

spring.cloud.kubernetes.secrets.enabled

Boolean

true

启用 Secrets PropertySource

spring.cloud.kubernetes.secrets.name

String

${spring.application.name}

设置要查找的 secret 名称

spring.cloud.kubernetes.secrets.namespace

String

客户端命名空间

设置要查找的 Kubernetes 命名空间

spring.cloud.kubernetes.secrets.labels

Map

null

设置用于查找 secrets 的标签

spring.cloud.kubernetes.secrets.paths

List

null

设置 secrets 挂载的路径(示例 1)

spring.cloud.kubernetes.secrets.enableApi

Boolean

false

启用或禁用通过 API 使用 secrets(示例 2 和 3)

spring.cloud.kubernetes.secrets.fail-fast

Boolean

false

当加载 Secret 时发生错误时,启用或禁用应用启动失败

spring.cloud.kubernetes.secrets.retry.enabled

Boolean

true

启用或禁用 secrets 重试。

spring.cloud.kubernetes.secrets.retry.initial-interval

Long

1000

初始重试间隔(毫秒)。

spring.cloud.kubernetes.secrets.retry.max-attempts

Integer

6

最大尝试次数。

spring.cloud.kubernetes.secrets.retry.max-interval

Long

2000

最大退避间隔。

spring.cloud.kubernetes.secrets.retry.multiplier

Double

1.1

下一次间隔的乘数。

注释

  • spring.cloud.kubernetes.secrets.labels 属性的行为遵循Map-based binding的定义。

  • spring.cloud.kubernetes.secrets.paths 属性的行为遵循Collection-based binding的定义。

  • 出于安全原因,通过 API 访问 secrets 可能会受到限制。推荐的方式是将 secrets 挂载到 Pod 中。

你可以在spring-boot-camel-config找到一个使用 secrets 的应用示例(尽管它尚未更新以使用新的 spring-cloud-kubernetes 项目)