试图让Spring/Consul/Vault一起工作 [英] Trying to get Spring/Consul/Vault to work together

查看:123
本文介绍了试图让Spring/Consul/Vault一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试做一些我认为很简单的事情.我想使用领事进行配置,并使用保险柜以获取机密.

I'm trying to do something I think is simple. I want to use Consul for configuration, and Vault for secrets.

我正在寻找的是一个像这样的简单应用程序,它使我可以从Consul获取配置和服务,并从Vault中获取机密.

在我的示例中,Consul和Vault已连接,并且我可以在Consul服务和键值存储中看到Vault.

In my example, Consul and Vault are connected, and I can see Vault in the Consul services and key-value store.

在Postman中,我可以直接查询Vault,并在{{vault_url}}/v1/secret/interservice-bus/data-categorizer

In Postman, I can query Vault directly and see my data at {{vault_url}}/v1/secret/interservice-bus/data-categorizer

现在我在测试应用中看不到Consul或保险柜的值.

Right now I cannot see Consul or Vault values in the test app.

我的application.yml很简单

My application.yml is simple

spring:
  profiles:
    active: dev
  main:
    banner-mode: "CONSOLE"
  application:
    name: test-consul

logging:
  level:
    org: INFO

bootstrap.yml是我执行大部分配置的地方.有些重复了,因为Spring抱怨缺少不同的部分.我不确定为什么.

The bootstrap.yml is where I'm doing most of my configuration. Some of it is repeated, because Spring complains if different parts are missing. I'm not sure why.

spring:
    profiles: 
        active: vault, dev
    cloud:
        consul:
            host: 127.0.0.1
            port: 8500
            config:
                enabled: true  
            discovery:
                prefer-ip-address: true
        config:
            discovery:
                enabled: true
                service-id: vault 
            server:
                vault:
                    host: localhost
                    port: 8200
                    scheme: http
                    authentication: TOKEN
                    token: 00000000-0000-0000-0000-000000000000
        vault:            
            host: localhost
            port: 8200
            scheme: http
            connection-timeout: 5000
            read-timeout: 15000
            authentication: TOKEN
            config:
                order: -10
            token: 00000000-0000-0000-0000-000000000000
            discovery:
                enabled: true
                service-id: vault

令牌在上方被遮盖,但与库的根令牌匹配.

The token is obscured above, but does match the root token for the vault.

这是我的POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>edu.dkist</groupId>
    <artifactId>test-consul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>test-consul</name>
    <description>Small test to see if consul can work with vault</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR4</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-all</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-consul-dependencies</artifactId>
                <version>1.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

这是我要运行的简单应用程序

And here's the simple app I'm trying to run

package com.example.demo;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@RefreshScope
@SpringBootApplication
@EnableDiscoveryClient
public class DemoApplication {
    @Autowired
    org.springframework.cloud.client.discovery.DiscoveryClient discoveryClient;

    @Value("${test}")
    private String testString;


    @Value("${interservice-bus.data-categorizer.username}") 
    private String user;

    @Value("${interservice-bus.data-categorizer.password}")
    private String password;


    @PostConstruct
    public void setRabbitMQLocation() {
            if (discoveryClient == null) {
            System.out.println("******************************ERROR: Discovery Client is null******************************");
            return;
        }
            System.out.println("****************************** Discovery Client is ACTIVE ******************************");

        org.springframework.cloud.client.ServiceInstance serviceInstance =
                discoveryClient.getInstances("interservice-bus")
                        .stream()
                        .findFirst()
                        .orElseThrow(() -> new RuntimeException("ERROR: " + "interservice-bus" + " not found"));
        System.out.println("****************************** ISB is " + serviceInstance.getHost() + ":" + serviceInstance.getPort() + " ******************************");
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

没有找到测试".我试图从保险柜中提取用户名和密码,并从领事那里进行测试.

It's not finding "test". I am trying to pull the username and password from Vault, and test from Consul.

我要

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-06-20 16:30:33.580 ERROR 92722 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.demoApplication': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'test' in value "${test}"

我正在寻找的是一个简单的应用程序,它使我可以从Consul获取配置和服务,并从Vault中获取机密.

从网上搜索并查看示例后,我不清楚我是否还需要获取Vault依赖项,或者是否需要从Consul获取所有信息(因此不需要Vault依赖项).

From searching on the net and looking at examples, it's not clear to me if I need to pull in the Vault dependencies as well or if I'm getting everything from Consul (and thus don't need the Vault dependencies).

推荐答案

要从Vault获取配置,您需要将Spring Cloud Vault添加到pom.

To get configuration from Vault you need to add Spring Cloud Vault to your pom.

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>

使用Spring Cloud Dalston.SR4(在pom中使用),您将收到Spring Cloud Vault 1.0.2.因此请注意,此版本的资料少于较新的资料(例如,您不能使用发现功能).如果要使用它,请考虑至少使用Spring Cloud Vault 1.1.1.RELEASE随附的Edgware.SR4.您可以随时在此处查看版本信息: https://github.com/spring-projects/spring-cloud/wiki#release-notes .无论如何,它仍然可以工作,但是您需要对其进行配置. 您的bootstrap.yml应该看起来像这样.

With Spring Cloud Dalston.SR4 (which you used in your pom) you will receive Spring Cloud Vault 1.0.2. So be aware that this version has less stuff than newer one (e.g. you cannot use discovery feature). If you want to use it, consider using at least Edgware.SR4 which comes with Spring Cloud Vault 1.1.1.RELEASE. You can always check version information here: https://github.com/spring-projects/spring-cloud/wiki#release-notes. Anyway, it still will work, but you need to configure it. Your bootstrap.yml should look like this.

spring:
  application:
    name: test-consul
  profiles:
    active: dev
  vault:
    fail-fast: true
    host: localhost
    port: 8200
    scheme: http
    authentication: TOKEN
    config:
      order: -10 # not sure that you need this, didn't investigate
    token: <your_token>

Spring Cloud Vault会使用Vault HTTP API根据您的应用程序名称和配置文件在Vault中搜索配置.因此,您需要根据下一个模式存储信息. (请参阅 Spring Cloud Vault 1.0.2 的文档)

Spring Cloud Vault will search configuration in Vault based on your application name and profile using Vault HTTP API. So you need to store information according to next patterns. (See documentation for Spring Cloud Vault 1.0.2)

/secret/{application}/{profile}
/secret/{application}
/secret/{default-context}/{profile}
/secret/{default-context}

示例:

vault write secret/test-consul/dev username=test_user

在这种情况下,在应用程序启动期间,Spring Cloud Vault将从secret/test-consul/dev获取属性并从中创建属性源.要获得此测试属性的值,您应该仅使用键.示例:

In this case during application start Spring Cloud Vault will get properties from secret/test-consul/dev and create Property Source from them. To get value of this test property you should use only key. Example:

@Value("${username}")
private String user;  // will be resolved to "test_user"

从Consul KV存储中获取属性是相似的. bootstrap.yml文件为:

Getting properties from Consul KV storage is similar. bootstrap.yml file is:

spring:
  profiles:
    active: dev
  application:
    name: test-consul
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        enabled: true

Spring Cloud Consul将使用下一个模式(所有模式)来使用HTTP API从Consul获取键值.请参阅有关Spring Cloud Consul 1.2.1的文档(它随Dalston.SR4一起提供):

Spring Cloud Consul will use next patterns (all of them) for getting key-values from Consul using HTTP API. See documentation for Spring Cloud Consul 1.2.1 (it comes with Dalston.SR4):

config/testApp,dev/
config/testApp/
config/application,dev/
config/application/

因此,您需要相应地保存数据.我是通过Consul GUI通过在KV Storage中创建文件夹来实现的,使用控制台它看起来应该与此类似:

So you need to save data accordingly. I did it from Consul GUI by creating folders in KV Storage, using console it should look similarly to this:

consul kv put config/test-consul/test testvalue

通过使用HTTP API获取数据,Spring Cloud Consul将从存储在其中的属性创建属性源,您将可以使用

By getting data using HTTP API Spring Cloud Consul will create a property source from properties stored there and you will be able to get this using

@Value("${test}")
private String testString; // will be resolved to "testvalue"

您可以组合两种配置并同时使用Spring Cloud Consul和Vault.在此演示中,我完全没有使用application.yml.

You can combine 2 configurations and use Spring Cloud Consul and Vault simultaneously. I did't use application.yml at all for this demo.

希望这篇长篇文章对您有所帮助:)

Hope this long post will help you :)

这篇关于试图让Spring/Consul/Vault一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆