Secrets PropertySource

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

启用后,Fabric8SecretsPropertySource 从以下来源查找 Kubernetes 的 Secrets

  1. 从 secret mount 中递归读取

  2. 以应用程序命名(如 spring.application.name 所定义)

  3. Matching some labels

注意:

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

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

如果找到 secret,则其数据将提供给应用程序。

假设我们有一个名为 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,例如,通过将 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. 通过列出映射 secret 的目录:[source, bash]

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

如果您将所有 secret 映射到一个公共根,可以像这样设置:

-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
  1. 通过设置命名 secret:[source, bash]

-Dspring.cloud.kubernetes.secrets.name=db-secret
  1. 通过定义标签列表:[source, bash]

-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-resolution 更好地了解如何解析应用程序的命名空间。

xref:property-source-config/configmap-propertysource.adoc#config-map-fail-fast[Similar to the ConfigMaps); 如果您希望应用程序在无法加载 Secrets 属性源时无法启动,您可以设置 spring.cloud.kubernetes.secrets.fail-fast=true

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

如果您已在类路径中出于某种原因拥有 spring-retryspring-boot-starter-aop,并且想要启用快速失败,但是不想启用重试;您可以通过设置 spring.cloud.kubernetes.secrets.retry.enabled=false 禁用 Secrets PropertySources 的重试。

由于源自 Secrets 的数据通常被视为敏感数据,执行器端点 /env/configprops 可以净化数据,使其不会以纯文本形式显示。要实现此目的,您需要设置:

spring.cloud.kubernetes.sanitize.secrets=true

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

Table 1. Properties:
Name Type Default Description

spring.cloud.kubernetes.secrets.enabled

Boolean

true

Enable Secrets PropertySource

spring.cloud.kubernetes.secrets.name

String

${spring.application.name}

设置查找机密的名称

spring.cloud.kubernetes.secrets.namespace

String

Client namespace

设置查找的 Kubernetes 名称空间

spring.cloud.kubernetes.secrets.labels

Map

null

设置用于查找机密的标记

spring.cloud.kubernetes.secrets.paths

List

null

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

spring.cloud.kubernetes.secrets.enableApi

Boolean

false

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

spring.cloud.kubernetes.secrets.fail-fast

Boolean

false

在加载 Secret 时发生错误后启用或禁用应用程序启动失败

spring.cloud.kubernetes.secrets.retry.enabled

Boolean

true

启用或禁用机密重试。

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

Long

1000

初始重试时间间隔(毫秒)。

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

Integer

6

Maximum number of attempts.

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

Long

2000

Maximum interval for backoff.

spring.cloud.kubernetes.secrets.retry.multiplier

Double

1.1

Multiplier for next interval.

备注:

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

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

  • 出于安全原因,可能会限制通过 API 访问机密。首选方法是将机密挂载到 Pod 中。

您可以在 spring-boot-camel-config 找到使用 Secrets(尽管尚未更新为使用新的 spring-cloud-kubernetes 项目)的应用程序示例。