模板的应用场景
当我开始写这篇文章时,我想构建一个基础框架,可以作为起点,让Spring Boot应用在Kubernetes集群中运行自如。
当我思考的时候,我意识到,在开发应用时,我采用迭代的方式,尝试各种方法,探索不同的解决方案和设计。这意味着一个可以在本地快速设置、使用和调试的环境是必要的。更重要的是,它还需要足够灵活,既能在我的Kubernetes集群内部运行,也能在外独立运行。
我之前写过一篇关于如何为了这个目的创建用于本地开发的Kubernetes环境的文章:使用kind开发和测试Kubernetes部署
这个集群包括一些基础组件:服务网格、Postgres 数据库以及使用 Grafana/Loki/Prometheus 堆栈进行监控。除此之外,我写了一篇文章,讲解了如何在使用 kind 构建的开发 Kubernetes 集群中引入 Vault,文章链接为:https://medium.com/@martin.hodges/adding-vault-to-your-development-kubernetes-cluster-using-kind-6a352eda2ab7。通过我的其他文章,你可以添加 APISIX API 网关、Keycloak OIDC、MinIO 等等。
这篇文章使用Kind创建了一个3节点的Kubernetes集群来设置开发环境。在这个例子中,我们需要一个4节点的集群(1个主节点和3个工作节点)。我们还需要开放一些额外的端口。因此,你需要使用下面的Kind配置文件。
**kind/kind-config.yml**
<!-- 此文件为 kind 配置文件 -->
apiVersion: kind.x-k8s.io/v1alpha4 kind: 集群实例 nodes: - role: 控制平面 extraPortMappings: # 应用 - containerPort: 30000 hostPort: 30000 # PostgreSQL 数据库 - containerPort: 31321 hostPort: 31321 # Grafana - containerPort: 31300 hostPort: 31300 # Vault - containerPort: 31400 hostPort: 31400 # 调试端口 - containerPort: 30500 hostPort: 30500 - role: 工作节点(worker) - role: 工作节点 - role: 工作节点
在本文中,我假设你已经知道如何搭建一个使用Kind的Kubernetes集群(至少安装Postgres和Vault这两个组件)。本文的GitHub仓库在此提供了你需要的所有文件,并包括在README文件里解释如何使用这些文件。
这个环境虽然对于本地运行应用程序很有用,但在开发过程中,会涉及大量的调试工作,因此,我们构建的任何应用程序都需要能够在集群内部和外部都能方便地进行调试。
所以,根据这些需求,我建立了一个起点骨架。虽然你可以在Github上找到它,但对于首次在Kubernetes集群中运行Spring Boot的新手开发者,我建议你阅读我在这里的说明,以便了解具体情况。
我想你能够使用Spring Boot框架开发Java应用程序,并且你有工具可以使用集成开发工具(IDE)。
我使用Mac和IntelliJ来开发,我在这篇文章中的所有说明都是基于我使用的这个开发环境。
我们来详细看看 skeleton 应用程序的应用场景。
使用框架的场景
在这个情况下,我们希望在开发过程中能够运行程序。在这个阶段,你可能想使用模拟环境来进行单元测试和集成测试的运行和开发。
此配置文件在您的IDE中运行您的应用,不会与其他任何内容连接。
我们将给它设置一个 Spring 配置文件名为:“standalone
”
在这种情况下,我们希望能够将应用程序连接至本地的 Kubernetes 集群并使用集群中的数据库。这通常是在我们试图找出特定问题的原因,并需要利用集群中的数据时。我们不想继续将应用程序作为 Docker 镜像部署到集群中,所以我们希望从集群外部连接。
此环境在你的IDE中运行你的应用程序,并连接到你本地的Kubernetes集群中的数据库。
我们将设置一个名为 connected
的 Spring 配置属性。
我们希望使用Docker镜像在本地的Kubernetes集群中调试我们应用程序的代码。这让我们可以测试与集群的集成以及部署设置。
为了便于测试和调试,Vault secrets将保持不变,以避免它们过期。
我们将给这设置一个名为 k8s-debug
的 Spring 配置文件名。
这个场景与之前的类似,我们将在这个本地 Kubernetes 集群中运行我们的应用。这次,我们将把用于测试和调试的配置替换为接近最终的版本,例如使用动态密钥值。这使得它更接近于生产环境。
我们将给它指定一个 Spring 配置文件名:local-cluster
当然,这四个场景只考虑了您生命周期中的开发部分。您还需要为其他环境设置不同的配置,例如系统集成测试(SIT)、用户验收测试(UAT)、预生产和生产。
这些其他个人档案将非常符合您的需求。
这个骨架设计包含了:
其他文章将进一步在此基础上发展。
zh:# 依赖关系
如果你想自己搭建一个框架,而不是仅仅复制我在GitHub上的代码,你可以使用你的IDE或Spring Initializr来启动项目。我们将会用到一些库和框架。该项目在GitHub上使用Gradle进行包管理。
您可以在 build.gradle
文件中找到详细信息。文件中还可能包含其他依赖项,但这些依赖项是用于骨架的其他高级功能,这些高级功能在其他文章中有详细介绍。
这是一个Spring Boot应用。它可以直接运行,并且可以在上述任何开发环境、测试环境或生产环境中运行。
这是一个有趣的应用程序,让你可以创造鱼儿和鱼缸。然后你就可以把鱼儿放进鱼缸里。
应用模板架构
我们只关注后端应用的模板化,这里没有用户界面。
这个例子包含足够的特性来展示如何在Kubernetes集群里做持久存储、RESTful API、日志记录和健康状况检查等操作。
代码采用了标准的n层架构,包括控制器、服务和存储层。控制器依赖于数据传输对象(DTO)类,这些类,而存储层依赖于实体对象。
所有的实体使用唯一的主键(UUID),因为这便于在测试(或数据修复)时插入数据而无需担心序列号的问题。当然,这会在生成这个键时影响性能,使得它对用户来说稍微不那么友好。
你可以根据自己的风格和需求来调整任何内容。
为了管理项目骨架中的数据库架构和数据,我选择了Liquibase工具。
就像其他管理工具一样,它通过将定义在 changelog
文件中的变更应用到数据库来运行。这些变更可以更新数据库结构或数据。Liquibase 记录它执行过的所有变更,并确保每个变更只被执行一次。
在这一个数据库的情况下,db.changelog.master
文件是用 YAML 编写的,而不是 XML 或 JSON。我更喜欢将实际变更与 changelog
文件分离,以防它变得难以管理。我通过从一个子文件夹中包含 SQL 文件来实现,我喜欢使用这样的文件夹来跟踪模式版本,比如版本 v1.00
。
之前我说过,骨骼结构使用了四个配置文件(profiles)。
独立运行
连接模式
k8s-debug
本地群集
利用 Spring 的特性,可以覆盖属性,我们首先创建一个默认的 application.yml
文件作为基础配置,然后用特定环境的 application-<环境名>.yml
文件来覆盖它。
你可以通过修改 application.yml
文件或更优选地,从你的 IDE 的 JVM 命令行参数中选择所需的配置文件或配置。根据不同的场景和需求,其他可能需要设置的参数包括数据库用户名和密码。
-Dspring.profiles.active=connected # 设置spring配置文件的活动配置为connected -Ddb.username="app-user" # 设置数据库用户名为app-user -Ddb.password="app-secret" # 设置数据库密码为app-secret
注意,用户名和密码是根据你在集群中的数据库设置确定的(参考我之前的文章)。链接文本保持不变:deploying kafka on a kind kubernetes cluster for development and testing purposes。
为了确保包含适当的细节层次,我将在单独的文章中描述每个配置文件。本文将描述 standalone
和 connected
配置文件。
这形成了所有其他配置文件的基础。它定义了以下内容。
默认配置是独立模式,因为这是您最可能需要的配置文件。在您的持续集成/持续部署(CI/CD)流程中,您会运行单元测试和集成测试。
此基础属性文件需要一个特定的配置文件来定义数据源信息,因为这些信息在每个配置文件中会有所变化。
此配置文件使用Hibernate自动创建模式的H2内存数据库。
由于 Liquibase 与瞬态数据库配合不佳,因此被禁用。此配置使用 Hibernate 自动根据你的实体生成所需的模式,并记录生成的模式。这非常有用,可以作为创建 Liquibase 脚本的基础以生成所需的模式。
你可以在这个开发环境中运行这个配置。因为它是一个内存数据库,每次运行应用时都会重置。
在这个配置文件里,数据库连接更改为Postgres配置,并假设本地数据库运行在localhost:31321
。如果你按照文章开头提到的步骤创建了Kind集群,你会知道这是本地Kind Kubernetes集群里用来暴露Postgres数据库的NodePort
服务的端口。
这种方式允许你连接到 Kubernetes 集群中的数据库,同时保留你在 IDE 中的所有功能。然而,这还意味着你无法使用集群内的其他服务,例如 Vault 和 Grafana。
请注意,现在此配置启用了Liquibase,并启用了Hibernate的自动模式创建。这意味着您仍然可以用Hibernate来调整Liquibase的设置。
通过使用集群中的数据库,数据会在运行之间持久保存。
在这篇文章里,我讲了关于 Spring Boot 的骨架设计,它能帮助你开始搭建自己的 Kubernetes 应用。
我已经展示了我们可以使用Spring配置文件(profiles)根据不同的使用情况来配置骨架。接着,我们选择了前两个配置文件,展示了它们如何帮助你获得一个不依赖集群的独立开发版本以及一个连接到集群内部数据库的版本。
接下来的两篇文章将讨论剩余的场景。下一篇文章将介绍如何在 Kubernetes 集群内调试应用程序:如何在 Kubernetes 集群内调试应用程序。
希望你喜欢这篇文章,并至少学到了一点东西。
如果你觉得这篇文章很有意思,请给我点个赞哦,这能让我知道大家喜欢什么,以及我今后应该写些什么。或者你有任何想法,可以在评论里添加。