Secrets PropertySource
Kubernetes 提供了 Secrets 的概念,用于存储敏感数据,如密码、OAuth 令牌等。该项目提供了与 Secrets
的集成,使得 Spring Boot 应用程序可以访问这些机密信息。你可以通过设置 spring.cloud.kubernetes.secrets.enabled
属性来显式地启用或禁用此功能。
启用后,Fabric8SecretsPropertySource
会从以下来源查找 Kubernetes 的 Secrets
:
-
从 secrets 挂载中递归读取
-
以应用程序命名(由
spring.application.name
定义) -
匹配某些标签
注意:
默认情况下,出于安全考虑,未启用通过 API 使用 Secrets(上述第 2 和第 3 点)。对 Secrets 的 'list' 权限允许客户端检查指定命名空间中的 Secrets 值。此外,我们建议容器通过挂载卷共享 Secrets。
如果你启用了通过 API 消费 Secrets 的功能,我们建议你使用授权策略(如 RBAC)来限制对 Secrets 的访问。有关通过 API 消费 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 编码版本。
然后,您的应用程序可以使用这个密钥——例如,通过将密钥的值导出为环境变量:
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:
-
通过列出映射机密的目录:
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql
如果你所有的机密都映射到一个共同的根目录,你可以这样设置:
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
-
通过设置一个命名的机密:
-Dspring.cloud.kubernetes.secrets.name=db-secret
-
通过定义一组标签:
-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
没有被设置,那么名为 s1
的 Secret
将会在应用程序运行的命名空间中进行查找。请参阅 namespace-resolution 以更好地理解应用程序的命名空间是如何解析的。
类似于 ConfigMaps;如果你希望应用程序在无法加载 Secrets
属性源时启动失败,可以设置 spring.cloud.kubernetes.secrets.fail-fast=true
。
同样可以为 Secret
属性源启用重试机制,就像 ConfigMaps 一样。与 ConfigMap
属性源类似,首先需要设置 spring.cloud.kubernetes.secrets.fail-fast=true
。然后,你需要在类路径中添加 spring-retry
和 spring-boot-starter-aop
。Secret
属性源的重试行为可以通过设置 spring.cloud.kubernetes.secrets.retry.*
属性来进行配置。
如果由于某些原因,你的 classpath 中已经包含了 spring-retry
和 spring-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 | 设置用于查找 Secret 的标签 |
spring.cloud.kubernetes.secrets.paths | List | null | 设置 Secret 挂载的路径(示例 1) |
spring.cloud.kubernetes.secrets.enableApi | Boolean | false | 启用或禁用通过 API 消费 Secret(示例 2 和 3) |
spring.cloud.kubernetes.secrets.fail-fast | Boolean | false | 启用或禁用当加载 Secret 时发生错误时,应用程序启动失败 |
spring.cloud.kubernetes.secrets.retry.enabled | Boolean | true | 启用或禁用 Secret 重试。 |
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.labels
属性的行为遵循 基于 Map 的绑定 的定义。 -
spring.cloud.kubernetes.secrets.paths
属性的行为遵循 基于集合的绑定 的定义。 -
出于安全原因,通过 API 访问 secrets 可能会受到限制。推荐的方式是将 secrets 挂载到 Pod 中。
你可以在 spring-boot-camel-config 找到一个使用 secrets 的应用程序示例(尽管它尚未更新为使用新的 spring-cloud-kubernetes
项目)。