189 lines
8.6 KiB
Plaintext
189 lines
8.6 KiB
Plaintext
[[secrets-propertysource]]
|
|
= Secrets PropertySource
|
|
|
|
Kubernetes has the notion of https://kubernetes.io/docs/concepts/configuration/secret/[Secrets] for storing
|
|
sensitive data such as passwords, OAuth tokens, and so on. This project provides integration with `Secrets` to make secrets
|
|
accessible by Spring Boot applications. You can explicitly enable or disable This feature by setting the `spring.cloud.kubernetes.secrets.enabled` property.
|
|
|
|
When enabled, the `Fabric8SecretsPropertySource` looks up Kubernetes for `Secrets` from the following sources:
|
|
|
|
. Reading recursively from secrets mounts
|
|
. Named after the application (as defined by `spring.application.name`)
|
|
. Matching some labels
|
|
|
|
*Note:*
|
|
|
|
By default, consuming Secrets through the API (points 2 and 3 above) *is not enabled* for security reasons. The permission 'list' on secrets allows clients to inspect secrets values in the specified namespace.
|
|
Further, we recommend that containers share secrets through mounted volumes.
|
|
|
|
If you enable consuming Secrets through the API, we recommend that you limit access to Secrets by using an authorization policy, such as RBAC.
|
|
For more information about risks and best practices when consuming Secrets through the API refer to https://kubernetes.io/docs/concepts/configuration/secret/#best-practices[this doc].
|
|
|
|
If the secrets are found, their data is made available to the application.
|
|
|
|
Assume that we have a spring boot application named `demo` that uses properties to read its database
|
|
configuration. We can create a Kubernetes secret by using the following command:
|
|
|
|
[source]
|
|
----
|
|
kubectl create secret generic db-secret --from-literal=username=user --from-literal=password=p455w0rd
|
|
----
|
|
|
|
The preceding command would create the following secret (which you can see by using `kubectl get secrets db-secret -o yaml`):
|
|
|
|
[source,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
|
|
----
|
|
|
|
Note that the data contains Base64-encoded versions of the literal provided by the `create` command.
|
|
|
|
Your application can then use this secret -- for example, by exporting the secret's value as environment variables:
|
|
|
|
[source,yaml]
|
|
----
|
|
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
|
|
----
|
|
|
|
You can select the Secrets to consume in a number of ways:
|
|
|
|
. By listing the directories where secrets are mapped:
|
|
+
|
|
[source,bash]
|
|
----
|
|
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql
|
|
----
|
|
+
|
|
If you have all the secrets mapped to a common root, you can set them like:
|
|
+
|
|
[source,bash]
|
|
----
|
|
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
|
|
----
|
|
|
|
. By setting a named secret:
|
|
+
|
|
[source,bash]
|
|
----
|
|
-Dspring.cloud.kubernetes.secrets.name=db-secret
|
|
----
|
|
|
|
. By defining a list of labels:
|
|
+
|
|
[source,bash]
|
|
----
|
|
-Dspring.cloud.kubernetes.secrets.labels.broker=activemq
|
|
-Dspring.cloud.kubernetes.secrets.labels.db=postgresql
|
|
----
|
|
|
|
As the case with `ConfigMap`, more advanced configuration is also possible where you can use multiple `Secret`
|
|
instances. The `spring.cloud.kubernetes.secrets.sources` list makes this possible.
|
|
For example, you could define the following `Secret` instances:
|
|
|
|
[source,yaml]
|
|
----
|
|
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
|
|
----
|
|
|
|
In the preceding example, if `spring.cloud.kubernetes.secrets.namespace` had not been set,
|
|
the `Secret` named `s1` would be looked up in the namespace that the application runs.
|
|
See xref:property-source-config/namespace-resolution.adoc[namespace-resolution] to get a better understanding of how the namespace
|
|
of the application is resolved.
|
|
|
|
xref:property-source-config/configmap-propertysource.adoc#config-map-fail-fast[Similar to the `ConfigMaps`]; if you want your application to fail to start
|
|
when it is unable to load `Secrets` property sources, you can set `spring.cloud.kubernetes.secrets.fail-fast=true`.
|
|
|
|
It is also possible to enable retry for `Secret` property sources xref:property-source-config/configmap-propertysource.adoc#config-map-retry[like the `ConfigMaps`].
|
|
As with the `ConfigMap` property sources, first you need to set `spring.cloud.kubernetes.secrets.fail-fast=true`.
|
|
Then you need to add `spring-retry` and `spring-boot-starter-aop` to your classpath.
|
|
Retry behavior of the `Secret` property sources can be configured by setting the `spring.cloud.kubernetes.secrets.retry.*`
|
|
properties.
|
|
|
|
NOTE: If you already have `spring-retry` and `spring-boot-starter-aop` on the classpath for some reason
|
|
and want to enable fail-fast, but do not want retry to be enabled; you can disable retry for `Secrets` `PropertySources`
|
|
by setting `spring.cloud.kubernetes.secrets.retry.enabled=false`.
|
|
|
|
Since data coming from Secrets is usually treated as sensitive, endpoints of the actuator `/env` and `/configprops` can be made to sanitize data, so that it is not displayed in plain text. In order to do that, you need to set:
|
|
|
|
[source]
|
|
----
|
|
spring.cloud.kubernetes.sanitize.secrets=true
|
|
----
|
|
|
|
This setting is supported since `3.0.6` and upwards.
|
|
|
|
.Properties:
|
|
[options="header,footer"]
|
|
|===
|
|
| Name | Type | Default | Description
|
|
| `spring.cloud.kubernetes.secrets.enabled` | `Boolean` | `true` | Enable Secrets `PropertySource`
|
|
| `spring.cloud.kubernetes.secrets.name` | `String` | `${spring.application.name}` | Sets the name of the secret to look up
|
|
| `spring.cloud.kubernetes.secrets.namespace` | `String` | Client namespace | Sets the Kubernetes namespace where to look up
|
|
| `spring.cloud.kubernetes.secrets.labels` | `Map` | `null` | Sets the labels used to lookup secrets
|
|
| `spring.cloud.kubernetes.secrets.paths` | `List` | `null` | Sets the paths where secrets are mounted (example 1)
|
|
| `spring.cloud.kubernetes.secrets.enableApi` | `Boolean` | `false` | Enables or disables consuming secrets through APIs (examples 2 and 3)
|
|
| `spring.cloud.kubernetes.secrets.fail-fast` | `Boolean` | `false` | Enable or disable failing the application start-up when an error occurred while loading a `Secret`
|
|
| `spring.cloud.kubernetes.secrets.retry.enabled` | `Boolean` | `true` | Enable or disable secrets retry.
|
|
| `spring.cloud.kubernetes.secrets.retry.initial-interval` | `Long` | `1000` | Initial retry interval in milliseconds.
|
|
| `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.
|
|
|===
|
|
|
|
Notes:
|
|
|
|
* The `spring.cloud.kubernetes.secrets.labels` property behaves as defined by
|
|
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding#map-based-binding[Map-based binding].
|
|
* The `spring.cloud.kubernetes.secrets.paths` property behaves as defined by
|
|
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding#collection-based-binding[Collection-based binding].
|
|
* Access to secrets through the API may be restricted for security reasons. The preferred way is to mount secrets to the Pod.
|
|
|
|
You can find an example of an application that uses secrets (though it has not been updated to use the new `spring-cloud-kubernetes` project) at
|
|
https://github.com/fabric8-quickstarts/spring-boot-camel-config[spring-boot-camel-config]
|
|
|