本指南将引导您使用 Spring Cloud Vault 构建一个从 HashiCorp Vault 获取配置属性的应用程序。
你将构建什么
您将启动 Vault,将配置属性存储在 Vault 中,构建一个 Spring 应用程序并将其与 Vault 连接。
所需内容
-
大约15分钟
-
一个喜欢的文本编辑器或IDE
-
Java 17 或更高版本
如何完成本指南
与大多数 Spring 入门指南 一样,您可以从头开始完成每个步骤,也可以直接查看 此仓库 中的代码跳到解决方案部分。
要在本地环境中查看最终结果,您可以执行以下操作之一:
-
下载 并解压本指南的源代码仓库
-
使用 Git 克隆仓库:
git clone https://github.com/spring-guides/gs-vault-config.git
-
Fork 仓库,这样您可以通过提交 pull request 来请求对本指南的修改
从 Spring Initializr 开始
您可以使用这个预先初始化的项目,然后点击生成以下载一个ZIP文件。该项目已配置为适合本教程中的示例。
要手动初始化项目:
-
访问 https://start.spring.io。该服务会拉取应用程序所需的所有依赖项,并为您完成大部分设置工作。
-
选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Java。
-
点击 Dependencies 并选择 Vault Configuration。
-
点击 Generate。
-
下载生成的 ZIP 文件,该文件是一个根据您的选择配置好的应用程序的压缩包。
如果您的 IDE 集成了 Spring Initializr,您可以直接在 IDE 中完成这个过程。
运行 HashiCorp Vault
完成本指南需要一个 HashiCorp Vault 实例。本指南使用 Docker Compose 来运行容器化的 HashiCorp Vault。已提供一个 compose.yaml
文件:
services:
vault:
container_name: "guide-vault"
image: hashicorp/vault:latest
environment:
VAULT_DEV_ROOT_TOKEN_ID: "00000000-0000-0000-0000-000000000000"
ports:
* "8200:8200"
使用 docker compose up
命令运行 HashiCorp Vault 容器。
在 Vault 中存储配置
Vault 是一个秘钥管理系统,允许您存储敏感数据,这些数据在静态时是加密的。您需要访问 Vault 容器来存储数据。使用以下命令连接到正在运行的 Docker 容器:
docker exec -it guide-vault sh
您现在正在 HashiCorp Vault 容器内运行命令。首先,您需要设置两个环境变量,以便将 Vault CLI 指向 Vault 端点并提供身份验证令牌。
export VAULT_TOKEN="00000000-0000-0000-0000-000000000000"
export VAULT_ADDR="http://127.0.0.1:8200"
现在您可以将配置键值对存储在Vault中。在本指南中,您将存储两个键值对:
vault kv put secret/gs-vault-config example.username=demouser example.password=demopassword
vault kv put secret/gs-vault-config/cloud example.username=clouduser example.password=cloudpassword
现在您已经在 Vault 中写入了两个条目:secret/gs-vault-config
和 secret/gs-vault-config/cloud
。
Vault 容器正在运行且数据已加载,您现在可以将注意力转向 Spring 应用程序了。
定义您的配置类
为您的 Spring 应用程序创建一个简单的配置:
src/main/java/hello/MyConfiguration.java
package hello;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Mark Paluch
*/
@ConfigurationProperties("example")
public class MyConfiguration {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
配置您的应用程序
在这里,您可以使用 application.properties
配置您的应用程序。下面的代码使用了 Spring Boot 的 Config Data API,允许从 Vault 导入配置。
src/main/resources/application.properties
spring.application.name=gs-vault-config
spring.cloud.vault.token=00000000-0000-0000-0000-000000000000
spring.cloud.vault.scheme=http
spring.cloud.vault.kv.enabled=true
spring.config.import: vault://
创建一个应用程序类
在这里您创建了一个包含所有组件的 Application 类。
src/main/java/hello/Application.java
package hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(MyConfiguration.class)
public class Application implements CommandLineRunner {
private final MyConfiguration configuration;
public Application(MyConfiguration configuration) {
this.configuration = configuration;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) {
Logger logger = LoggerFactory.getLogger(Application.class);
logger.info("----------------------------------------");
logger.info("Configuration properties");
logger.info(" example.username is {}", configuration.getUsername());
logger.info(" example.password is {}", configuration.getPassword());
logger.info("----------------------------------------");
}
}
Spring Cloud Vault 使用 VaultOperations
与 Vault 进行交互。来自 Vault 的属性会被映射到 MyConfiguration
,以实现类型安全的访问。@EnableConfigurationProperties(MyConfiguration.class)
启用了配置属性映射,并注册了一个 MyConfiguration
bean。
Application
包含一个 main()
方法,该方法会自动装配一个 MyConfiguration
实例。
运行应用程序
您可以通过 IDE 运行主方法。或者,使用 ./gradlew bootRun
和 ./mvnw spring-boot:run
命令启动应用程序。
由于我们的 Application
实现了 CommandLineRunner
,run
方法会在启动时自动调用。您应该会看到以下输出:
*---------------------------------------
Configuration properties
example.username is demouser
example.password is demopassword
*---------------------------------------
现在使用 cloud
配置文件启动应用程序。您可以在 Gradle 中使用 ./gradlew bootRun --args='--spring.profiles.active=cloud'
命令,或者在 Maven 中使用 ./mvnw spring-boot:run -Dspring-boot.run.arguments="--spring.profiles.active=cloud"
命令来执行此操作。当您使用 cloud
配置文件运行应用程序时,您会看到:
*---------------------------------------
Configuration properties
example.username is clouduser
example.password is cloudpassword
*---------------------------------------
配置属性会根据激活的配置文件进行绑定。Spring Cloud Vault 会从 spring.application.name
(即 gs-vault
)构造一个 Vault 上下文路径,并附加配置文件名称(cloud
),因此启用 cloud
配置文件时,会从 secret/gs-vault-config/cloud
额外获取配置属性。
构建应用程序
本节描述运行本指南的不同方式:
-
构建并执行 JAR 文件
-
使用 Cloud Native Buildpacks 构建并执行 Docker 容器
-
构建并执行原生镜像
-
使用 Cloud Native Buildpacks 构建并执行原生镜像容器
无论您选择如何运行应用程序,输出结果都应该是相同的。
要运行应用程序,您可以将应用程序打包为可执行的 jar 文件。./mvnw clean package
命令将应用程序编译为可执行的 jar 文件。然后,您可以使用 java -jar target/gs-vault-config-0.0.1-SNAPSHOT.jar
命令来运行该 jar 文件。
或者,如果您有可用的 Docker 环境,您可以直接使用 buildpacks 从 Maven 或 Gradle 插件创建 Docker 镜像。使用 Cloud Native Buildpacks,您可以创建可在任何地方运行的 Docker 兼容镜像。Spring Boot 直接支持 Maven 和 Gradle 的 buildpack。这意味着您只需输入一个命令,就可以快速将合理的镜像放入本地运行的 Docker 守护进程中。要使用 Cloud Native Buildpacks 创建 Docker 镜像,请运行 ./mvnw spring-boot:build-image
命令。在启用 Docker 环境的情况下,您可以使用 docker run --network container:guide-vault docker.io/library/gs-vault-config:0.0.1-SNAPSHOT
命令来运行应用程序。
--network
标志告诉 Docker 将我们的指南容器附加到外部容器正在使用的现有网络。您可以在 Docker 文档 中找到更多信息。
原生镜像支持
Spring Boot 还支持编译为原生镜像,前提是您的机器上安装了 GraalVM 发行版。
然后,您可以运行 ./mvnw -Pnative native:compile
命令来生成原生镜像。构建完成后,通过执行 target/gs-vault-config
命令,您将能够以近乎瞬时的启动时间运行代码。
要使用 Maven 创建原生镜像容器,您应确保 pom.xml
文件使用了 spring-boot-starter-parent
和 org.graalvm.buildtools:native-maven-plugin
。该插件应位于 <build> <plugins>
部分中:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
您还可以使用 Buildpacks 创建原生镜像。通过运行 ./mvnw -Pnative spring-boot:build-image
命令,您可以生成一个原生镜像。构建完成后,您可以使用 docker run --network container:guide-vault docker.io/library/gs-vault-config:0.0.1-SNAPSHOT
命令启动您的应用程序。
总结
恭喜!您已经成功设置了一个 Vault 服务器,并编写了一个简单的应用程序,该程序使用 Spring Vault 将机密信息读取到配置属性中,并使用强大的加密算法对数据进行加密——这一切都无需费心实现密钥管理、加密模式和填充。