【微服务安全】使用 Spring Boot、Kafka、Vault 和 Kubernetes 保护微服务间通信——第 4 部分:构建微服务

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 【微服务安全】使用 Spring Boot、Kafka、Vault 和 Kubernetes 保护微服务间通信——第 4 部分:构建微服务
  • 第 1 部分:简介和架构
  • 第 2 部分:设置 Kubernetes 和 Kafka
  • 第 3 部分:设置保险柜
  • Part 4: 构建微服务 <--本文
  • 第 5 部分:部署和测试

创建微服务

 

  • 我们将创建 2 个微服务:Transaction 和 DepositAccount。我们将为此使用 JHipster。
  • 首先,我们需要安装 JHipster。请按照此处的教程安装 JHipster [https://www.jhipster.tech/installation/]

准备信任库(truststore)

 

  • 如果您从 Java 程序调用自签名受保护端点(例如本教程中的 Vault),则需要首先信任自签名证书
  • 通常这是通过将自签名证书注册到 JVM 的信任库中来完成的。
  • 我们将面临的问题是:当我们创建 docker 镜像并在其中运行我们的微服务时,我们不会使用我们机器的 JVM。我们将改为使用图像的 JVM。我们如何将我们的证书注册到镜像的 JVM 信任库中?
  • 当我们进入本教程的部署部分时,我们将解决这个问题。同时,让我们将 Vault 的根证书注册到信任库中。请记住证书 TMPDIR/vault.crt。我们将使用此证书。
  • 我们需要找到 JVM cacerts 在哪里。在 Mac 机器上,它位于文件夹中的某个位置:$(/usr/libexec/java_home)/lib/security.你可以参考这个关于堆栈溢出的讨论:https://stackoverflow.com/questions/11936685/how-to-obtain-the-location…
  • 运行以下命令。当提示输入密码时,请指定插入符号密码。默认情况下是 changeit

> sudo keytool -import -file "/tmp/vault.crt" -keystore "$(/usr/libexec/java_home)/lib/security/cacerts" -alias "vault certificate"

 

  • 您可能需要更改生产环境的 cacerts 密码
  • 我们现在已经将 Vault 的证书注册为可信证书。

设置 JHipster 注册表

 

  • 将 JHipster Registry https://www.jhipster.tech/jhipster-registry/ 下载为 jar 文件并放入 $PROJECTS/Registry 文件夹
  • 创建另一个文件夹:$PROJECTS/Registry/central-config。在 central-config 中,创建一个名为 application.yml 的文件并在下面插入内容。请确保将 my-secret-key-which-should-be-changed-in-production-and-be-base64-encoded 替换为您自己的生产机密:

# ===================================================================

# JHipster Sample Spring Cloud Config.

# ===================================================================


# Property used on app startup to check the config server status

configserver:

   name: JHipster Registry config server

   status: Connected to the JHipster Registry config server!


# Default JWT secret token (to be changed in production!)

jhipster:

   security:

       authentication:

           jwt:

               # It is recommended to encrypt the secret key in Base64, using the `base64-secret` property.

               # For compabitibily issues with applications generated with older JHipster releases,

               # we use the non Base64-encoded `secret` property here.

               secret: my-secret-key-which-should-be-changed-in-production-and-be-base64-encoded

               # The `base64-secret` property is recommended if you use JHipster v5.3.0+

               # (you can type `echo 'secret-key'|base64` on your command line)

               # base64-secret: bXktc2VjcmV0LWtleS13aGljaC1zaG91bGQtYmUtY2hhbmdlZC1pbi1wcm9kdWN0aW9uLWFuZC1iZS1iYXNlNjQtZW5jb2RlZAo=

 

# Enable /management/logfile endpoint for all apps

logging:

   path: /tmp

   file: ${spring.application.name}.log


  • 您已成功设置 JHipster Registry

设置 API 网关

启动命令行控制台并将其指向 $PROJECTS/GatewayKafka 文件夹。跑:

> jhipster

将提出一系列问题。回答他们如下。请注意,当被问及您还想使用哪些其他技术?不要选择 Kafka。我们将单独处理 Kafka,而不是通过 JHipster:

? Which *type* of application would you like to create? Microservice gateway

? [Beta] Do you want to make it reactive with Spring WebFlux? No

? What is the base name of your application? GatewayKafka

? As you are running in a microservice architecture, on which port would like yo

ur server to run? It should be unique to avoid port conflicts. 8080

? What is your default Java package name? com.azrul.ebanking.gatewaykafka

? Which service discovery server do you want to use? JHipster Registry (uses Eur

eka, provides Spring Cloud Config support and monitoring dashboards)

? Which *type* of authentication would you like to use? JWT authentication (stat

eless, with a token)

? Which *type* of database would you like to use? SQL (H2, MySQL, MariaDB, Postg

reSQL, Oracle, MSSQL)

? Which *production* database would you like to use? PostgreSQL

? Which *development* database would you like to use? H2 with disk-based persist

ence

? Do you want to use the Spring cache abstraction? No - Warning, when using an S

QL database, this will disable the Hibernate 2nd level cache!

? Do you want to use Hibernate 2nd level cache? No

? Would you like to use Maven or Gradle for building the backend? Maven

? Which other technologies would you like to use?

? Which *Framework* would you like to use for the client? Angular

? Would you like to use a Bootswatch theme (https://bootswatch.com/)? Default JH

ipster

? Would you like to enable internationalization support? No

? Besides JUnit and Jest, which testing frameworks would you like to use?

? Would you like to install other generators from the JHipster Marketplace? (y/N

) No

 

  • 您现在已成功设置 API 网关

设置交易微服务

启动命令行控制台并将其指向 $PROJECTS/Transaction 文件夹。跑:

> jhipster

将提出一系列问题。回答他们如下。请注意,当被问及您还想使用哪些其他技术时?不要选择卡夫卡。我们将单独处理 Kafka,而不是通过 JHipster:

? Which *type* of application would you like to create? Microservice application

? [Beta] Do you want to make it reactive with Spring WebFlux? No

? What is the base name of your application? Transaction

? As you are running in a microservice architecture, on which port would like yo

ur server to run? It should be unique to avoid port conflicts. 8081

? What is your default Java package name? com.azrul.ebanking.transaction

? Which service discovery server do you want to use? JHipster Registry (uses Eur

eka, provides Spring Cloud Config support and monitoring dashboards)

? Which *type* of authentication would you like to use? JWT authentication (stat

eless, with a token)

? Which *type* of database would you like to use? SQL (H2, MySQL, MariaDB, Postg

reSQL, Oracle, MSSQL)

? Which *production* database would you like to use? PostgreSQL

? Which *development* database would you like to use? H2 with disk-based persist

ence

? Do you want to use the Spring cache abstraction? No - Warning, when using an S

QL database, this will disable the Hibernate 2nd level cache!

? Would you like to use Maven or Gradle for building the backend? Maven

? Which other technologies would you like to use?

? Would you like to enable internationalization support? No

? Besides JUnit and Jest, which testing frameworks would you like to use?

? Would you like to install other generators from the JHipster Marketplace? No

指定对 Kafka 和 Vault 的依赖关系

 

  • 首先,让我们处理依赖关系。在文件 $PROJECTS/Transaction/pom.xml 中,在 <dependencies> </dependencies> 标记中添加以下依赖项。

 

 <dependency>

           <groupId>org.springframework.kafka</groupId>

           <artifactId>spring-kafka</artifactId>

           <version>2.4.8.RELEASE</version>

       </dependency>

       <dependency>

           <groupId>org.apache.kafka</groupId>

           <artifactId>kafka-clients</artifactId>

           <version>2.4.1</version>

       <dependency>

           <groupId>org.apache.kafka</groupId>

           <artifactId>kafka_2.13</artifactId>

           <version>2.4.1</version>

       </dependency>

        <dependency>

           <groupId>org.springframework.cloud</groupId>

           <artifactId>spring-cloud-starter-vault-config</artifactId>

           <version>2.2.5.RELEASE</version>

       </dependency>

 

  • 在同一个 pom.xml 文件下,我们还需要在 <dependencyManagement><dependencies> ... </dependencies></dependencyManagement> 下添加一个条目

 

           <dependency>

               <groupId>org.springframework.cloud</groupId>

               <artifactId>spring-cloud-dependencies</artifactId>

               <version>Hoxton.RELEASE</version>

               <type>pom</type>

               <scope>import</scope>

           </dependency>

需要 spring-cloud-starter-vault-config 和 spring-cloud-dependencies 以允许 Vault 集成

编写事务微服务

 

  • 让我们创建一种将数据从发布者传输到消费者并再次返回的方法。为此,我们在名为 com.azrul.ebanking.common.dto 的包中创建了一个“数据传输对象”(DTO)。这将是生产者和消费者的通用包。在那里,让我们按照下面的方式创建一个 Transaction 类。请注意,为了使 Transaction 类可序列化,它必须实现 Serializable 接口,必须有一个默认构造函数,toString 和 equals 方法:

网络异常,图片无法展示
|

网络异常,图片无法展示
|

  • [完整来源:https://raw.githubusercontent.com/azrulhasni/Ebanking-JHipster-Kafka-Va…]
  • Kafka配置
  • Spring 使用 spring-kafka 库对 Kafka 提供了广泛的支持。这包括序列化器和反序列化器 - 这将使消息传递类型安全。另一方面,我们不会使用这些序列化器/反序列化器,因为我们将在消息到达我们自己的 Kafka 之前对其进行加密。我们将选择一个基本的字符串序列化器/反序列化器。
  • 这是我们将用来连接到 Kafka 的 KafkaTemplate。请注意,我们使用的是一种特殊的 KafkaTemplate,称为 ReplyingKafkaTemplate。这个类将允许我们发送请求并获得响应,而无需我们自己做太多的管道
  • 我们还需要一个配置文件。在 $PROJECTS/Transaction/src/main/resources/config 文件夹下,在 application.yml 文件中添加:

kafka:

 bootstrap-servers: kafka-headless.default.svc.cluster.local:9092

 deposit-debit-request-topic: deposit-debit-request

 deposit-debit-response-topic: deposit-debit-response

 consumer:

   group.id: transaction

   auto.offset.reset: earliest

 producer:

 

  • 在 $PROJECTS/Transaction/src/main/resources/config 文件夹下,在文件 bootstrap.yml 中,在 spring.cloud 下添加以下属性。
  • 在方案中,确保我们把 https
  • 在主机中,确保我们放置自己的 Vault Kubernetes 服务的完全限定域名。回想上面的 Vault Kubernetes Service 段落
  • 在连接超时和读取超时中,设置一个合理的超时时间。我们放了一个大的进行测试。放一个小的(比如几秒钟)用于生产
  • 在认证中,输入TOKEN,表示我们将通过安全令牌登录
  • 在令牌中,确保您在之前的“为加密和解密创建令牌”段落中输入了 client_token 值。

   vault:

     scheme: https

     host: vault.default.svc

     port: 8200

     connection-timeout: 3600000

     read-timeout: 3600000

     authentication: TOKEN

     token: s.WuTNTDpBqsspinc6dlDN0cbz

     kv:

       enabled=true:

 

  • 接下来,在 com.azrul.ebanking.transaction.web.rest 包中,创建一个名为 TransactionKafkaResource 的控制器

网络异常,图片无法展示
|

  1. 首先,我们需要获取请求和响应主题。回想一下我们的架构。另外,我们还在我们的KafkaTemplate中进行了wire,方便我们调用Kafka
  2. 我们还在 VaultTemplate 中进行接线以方便我们调用 Vault
  3. 这是我们将收到一个宁静的电话的地方。我们将加密该调用中的数据,创建 ProducerRecord 并将消息发送到 deposit-debit-request 主题。然后,我们将等待来自 deposit-debit-response 主题的回复。回复将包含我们得到的余额。一旦我们有了这些数据,我们就会解密它并返回给调用者。
  4. 这是我们加密数据的地方。最初,我们的数据是对象(Transaction 类型)的形式。然后我们将其转换为一系列字节。然后将一系列字节转换为 Base64 字符串。接下来,我们使用 Vault Transit 引擎加密 Base64 字符串。
  5. 这是我们解密数据的地方。最初,我们会得到一个加密的 Base64 字符串。我们需要使用 Vault Transit 引擎解密这个字符串。这将产生一个解密的 Base64 字符串。接下来,我们将 Base64 解密后的字符串解码为一系列字节。最后,我们将一系列字节转换回一个对象。

使用 Transaction 微服务的自签名证书处理 SSL

  • 请回想一下我们关于从微服务调用自签名保护端点的困难的讨论(准备信任库段落)。我们将利用 Jib 来帮助我们解决这个问题并部署到 Kubernetes。
  • 如果您注意到,JHipster 创建的文件夹之一称为 Jib ($PROJECTS/Transaction/src/main/jib)。此文件夹中的任何内容都将复制到根级别的 Docker 映像。
  • 例如。如果我们有 $PROJECTS/Transaction/src/main/jib/myfolder/myfile.txt,当我们创建 Docker 镜像时,Jib 会将 myfolder 和 myfile.txt 复制到 Docker 镜像中。这会在图像中创建 /myfolder/myfile.txt
  • 我们将创建一个名为 truststore 的文件夹,并在其中复制我们的主机/本地信任库(cacerts)。这会将 cacerts 复制到 /truststore/cacerts 的映像中。回想一下,我们可以找到信任库作为 JDK 的一部分。请在此处查看堆栈溢出讨论:https://stackoverflow.com/questions/11936685/how-to-obtain-the-location…

网络异常,图片无法展示
|

  • 接下来,我们需要告诉 Java 使用 /truststore/cacerts 中的 cacerts。在我们的 TransactionApp.java 文件的 main 方法中,添加以下行。确保我们使用正确的 cacerts 密码(默认为 changeit):

System.setProperty("javax.net.ssl.trustStore","/truststore/cacerts");

System.setProperty("javax.net.ssl.trustStorePassword","changeit");

网络异常,图片无法展示
|

设置 DepositAccount 微服务

启动命令行控制台并将其指向 $PROJECTS/DepositAccount 文件夹。跑:

> jhipster

将提出一系列问题。回答他们如下。请注意,当被问及您还想使用哪些其他技术时?不要选择卡夫卡。我们将单独处理 Kafka,而不是通过 JHipster:

? Which *type* of application would you like to create? Microservice application

? [Beta] Do you want to make it reactive with Spring WebFlux? No

? What is the base name of your application? DepositAccount

? As you are running in a microservice architecture, on which port would like yo

ur server to run? It should be unique to avoid port conflicts. 8082

? What is your default Java package name? com.azrul.ebanking.depositaccount

? Which service discovery server do you want to use? JHipster Registry (uses Eur

eka, provides Spring Cloud Config support and monitoring dashboards)

? Which *type* of authentication would you like to use? JWT authentication (stat

eless, with a token)

? Which *type* of database would you like to use? SQL (H2, MySQL, MariaDB, Postg

reSQL, Oracle, MSSQL)

? Which *production* database would you like to use? PostgreSQL

? Which *development* database would you like to use? H2 with disk-based persist

ence

? Do you want to use the Spring cache abstraction? No - Warning, when using an S

QL database, this will disable the Hibernate 2nd level cache!

? Would you like to use Maven or Gradle for building the backend? Maven

? Which other technologies would you like to use?

? Would you like to enable internationalization support? No

? Besides JUnit and Jest, which testing frameworks would you like to use?

? Would you like to install other generators from the JHipster Marketplace? (y/N

) No

指定对 Kafka 和 Vault 的依赖关系

 

  • DepositAccount 微服务的依赖与 Transaction 微服务相同。无论如何,我们将在这里重复以完成目的
  • 首先,让我们处理依赖关系。在文件 $PROJECTS/DepositAccount/pom.xml 中,在 <dependencies> </dependencies> 标记中添加以下依赖项。

      <dependency>

           <groupId>org.springframework.kafka</groupId>

           <artifactId>spring-kafka</artifactId>

           <version>2.4.8.RELEASE</version>

       </dependency>

       <dependency>

           <groupId>org.apache.kafka</groupId>

           <artifactId>kafka-clients</artifactId>

           <version>2.4.1</version>

       <dependency>

           <groupId>org.apache.kafka</groupId>

           <artifactId>kafka_2.13</artifactId>

           <version>2.4.1</version>

       </dependency>

        <dependency>

           <groupId>org.springframework.cloud</groupId>

           <artifactId>spring-cloud-starter-vault-config</artifactId>

           <version>2.2.5.RELEASE</version>

       </dependency>

 

  • 在同一个 pom.xml 文件下,我们还需要在 <dependencyManagement><dependencies> ... </dependencies>

           <dependency>

               <groupId>org.springframework.cloud</groupId>

               <artifactId>spring-cloud-dependencies</artifactId>

               <version>Hoxton.RELEASE</version>

               <type>pom</type>

               <scope>import</scope>

           </dependency>

 

  • 需要 spring-cloud-starter-vault-config 和 spring-cloud-dependencies 以允许 Vault 集成

为 DespositAccount 创建数据模型和存储库

 

  • 我们现在将为 DepositAccount 创建一个数据模型。
  • 在文件夹 $PROJECTS/DepositAccount/ 中创建一个名为 banking.jh 的文件。在那里,将数据模型放在下面

entity DepositAccount{  

   accountNumber String,  

   productId String,  

   openingDate ZonedDateTime,  

   status Integer,  

   balance BigDecimal  

}  


 

// Set service options to all except few  

service all with serviceClass

  • // 将服务选项设置为除少数之外的所有选项

使用 serviceClass 服务所有

然后,启动命令行控制台并将其指向文件夹 $PROJECTS/DepositAccount。 运行以下命令:

> jhipster import-jdl ./banking.jh

这将创建诸如 DepositAccountService 等可用于查询和保存存款账户数据的类。

编码 DespositAccount 微服务

 

  • 首先,我们需要与事务微服务相同的 DTO
  • 创建名为 com.azrul.ebanking.common.dto 的包,并在其中创建一个名为 Transaction 的类。回想一下,Transaction 类需要实现 Serialisable 接口,需要有一个默认构造函数,并且需要有 equals、hashCode 和 toString 方法:

网络异常,图片无法展示
|

网络异常,图片无法展示
|

  1. 卡夫卡配置
  2. Spring 使用 spring-kafka 库对 Kafka 提供了广泛的支持。这包括序列化器和反序列化器 - 这将使消息传递类型安全。另一方面,我们不会使用这些序列化器/反序列化器,因为我们将在消息到达我们自己的 Kafka 之前对其进行加密。我们将选择一个基本的字符串序列化器/反序列化器。
  3. 这是我们将用来连接到 Kafka 的 KafkaTemplate。请注意,我们使用的是一种特殊的 KafkaTemplate,称为 ReplyingKafkaTemplate。这个类将允许我们发送请求并获得响应,而无需我们自己做太多的管道
  • 我们还需要一个配置文件。在 $PROJECTS/DepositAccount/src/main/resources/config 文件夹下,在 application.yml 文件中添加:

kafka:

 bootstrap-servers: kafka-headless.default.svc.cluster.local:9092

 deposit-debit-request-topic: deposit-debit-request

 deposit-debit-response-topic: deposit-debit-response

 consumer:

   group.id: transaction

   auto.offset.reset: earliest

 producer:

 

  • 在 $PROJECTS/DepositAccount/src/main/resources/config 文件夹下,在文件 bootstrap.yml 中,在 spring.cloud 下添加以下属性。
  • 在方案中,确保我们把 https
  • 在主机中,确保我们放置自己的 Vault Kubernetes 服务的完全限定域名。回想上面的 Vault Kubernetes Service 段落
  • 在连接超时和读取超时中,设置一个合理的超时时间。我们放了一个大的进行测试。放一个小的(比如几秒钟)用于生产
  • 在认证中,输入TOKEN,表示我们将通过安全令牌登录
  • 在令牌中,确保您在之前的“为加密和解密创建令牌”段落中输入了 client_token 值。

 

   vault:

     scheme: https

     host: vault.default.svc

     port: 8200

     connection-timeout: 3600000

     read-timeout: 3600000

     authentication: TOKEN

     token: s.WuTNTDpBqsspinc6dlDN0cbz

     kv:

       enabled=true:

 

  • 接下来我们将创建一个监听器。在 com.azrul.ebanking.depositaccount.service 包中,创建一个名为 Transfer 的类,如下所示:

网络异常,图片无法展示
|

  • [完整源代码:https://github.com/azrulhasni/Ebanking-JHipster-Kafka-Vault/blob/master…]
  • 注入 VaultTemplate 允许我们解密进来的数据并加密返回的数据。
  • 注入 DespositAccountService 让我们可以查询和保存存款账户数据
  • 这是真正的听众。我们将通过输入参数从请求主题中获取我们的加密数据。我们十继续将这些数据解密到 Transaction 对象中。该对象将告诉我们要借记的源账户、要贷记的目标账户和金额。我们将继续执行该交易并计算借方和贷方账户中的结果余额。然后,我们将借记帐户余额放回消息中,并使用此编辑对象回复发布者。
  • 该方法与 Transaction 微服务中的方法相同,用于加密和对象
  • 该方法与 Transaction 微服务中的方法相同,用于解密和对象

使用 DepositAccount 微服务的自签名证书处理 SSL

 

  • 就像事务微服务一样,我们需要在这里做同样的事情
  • 我们将复制 cacerts(回想一下关于 stackoverflow 上关于 cacerts 在您的系统堆栈溢出中可用位置的讨论:https://stackoverflow.com/questions/11936685/how-to-obtain-the-location…- the-default-java-installation) 到 $PROJECTS/DepositAccounts/src/main/jib/truststore
  • 然后,我们需要通过添加以下代码来修改 main 方法(在文件 $PROJECTS/DepositAccounts/src/main/java/com/azrul/ebanking/depositaccount/DepositAccountApp.java 中):

System.setProperty("javax.net.ssl.trustStore","/truststore/cacerts");

System.setProperty("javax.net.ssl.trustStorePassword","changeit");

网络异常,图片无法展示
|

Tags

本文:https://architect.pub/secure-inter-micro-service-communication-spring-boot-kafka-vault-and-kubernetes-part-4-building

相关文章
|
21天前
|
安全 Java 数据安全/隐私保护
|
24天前
|
安全 Java API
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)
44 0
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
|
24天前
|
Java API 微服务
【Spring Boot系列】通过OpenAPI规范构建微服务服务接口
【4月更文挑战第5天】通过OpenAPI接口构建Spring Boot服务RestAPI接口
|
6天前
|
消息中间件 Java Kafka
spring kafka的问题集锦
spring kafka的问题集锦
17 0
|
14天前
|
Java Docker 微服务
|
15天前
|
消息中间件 Java RocketMQ
Spring Cloud RocketMQ:构建可靠消息驱动的微服务架构
【4月更文挑战第28天】消息队列在微服务架构中扮演着至关重要的角色,能够实现服务之间的解耦、异步通信以及数据分发。Spring Cloud RocketMQ作为Apache RocketMQ的Spring Cloud集成,为微服务架构提供了可靠的消息传输机制。
28 1
|
15天前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo: 微服务通信的高效解决方案
【4月更文挑战第28天】在微服务架构的发展中,服务间的高效通信至关重要。Spring Cloud Dubbo 提供了一种基于 RPC 的通信方式,使得服务间的调用就像本地方法调用一样简单。本篇博客将探讨 Spring Cloud Dubbo 的核心概念,并通过具体实例展示其在项目中的实战应用。
16 2
|
18天前
|
Java 数据安全/隐私保护 Sentinel
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
|
24天前
|
安全 Java API
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(下)
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)
26 0
|
24天前
|
安全 Java API
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(中)
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)
34 0