在 Kubernetes 上使用 Infinispan 部署 Vert.x 集群应用程序

本文档将向您展示如何在 Kubernetes 上使用 Infinispan 部署 Vert.x 集群应用程序。

您将构建什么

您将构建一个 Vert.x 集群应用程序,该应用程序

  • 监听对 /hello URI 的 HTTP 请求

  • 提取 HTTP 查询参数 name

  • 回复一条问候语,例如 "Hello <name> from <pod>,其中

    • <name> 是查询参数值

    • <pod> 是生成问候语的 Kubernetes pod 的名称

它由两个部分(或微服务)组成,通过 Vert.x 事件总线进行通信。

前端处理 HTTP 请求。它提取 name 参数,向总线上的 greetings 地址发送请求,并将回复转发给客户端。

后端消费发送到 greetings 地址的消息,生成问候语并回复给前端

您需要什么

  • 文本编辑器或 IDE

  • Java 11 或更高版本

  • Maven 或 Gradle

  • Minikube 或任何 Kubernetes 集群

  • kubectl 命令行工具

创建项目

前端后端项目的代码包含功能等效的 Maven 和 Gradle 构建文件。

依赖项

两个项目都依赖于

Vert.x Infinispan 是一个基于 Infinispan 内存键/值数据存储的 Vert.x 集群管理器。在 Vert.x 中,集群管理器用于各种功能。特别是,它提供集群节点的发现/成员管理并存储事件总线订阅数据。

Vert.x Web 是一组构建块,可轻松创建 HTTP 应用程序。

Vert.x Health Check 是一个组件,它标准化了检查系统不同部分、推断状态并公开状态的过程。

容器化

为了创建容器,我们将使用 Jib,因为

  • 它为依赖项、资源和类创建具有不同层次的镜像,从而节省了构建时间和部署时间

  • 它支持 Maven 和 Gradle

  • 它既不需要 Docker 也不需要 Podman

使用 Maven

以下是您应该用于前端pom.xml 文件的内容

对于后端,内容类似

使用 Gradle

假设您使用带有 Kotlin DSL 的 Gradle,以下是您的 build.gradle.kts 文件在前端中的样子

对于后端,内容类似

实现服务

让我们从后端服务开始。我们将继续编写前端,然后在开发机器上测试它们。

后端服务

后端服务封装在 BackendVerticle 类中。

它通过环境变量进行配置

当 Verticle 启动时,它会注册一个事件总线消费者,设置一个 Vert.x Web Router 并绑定一个 HTTP 服务器

事件总线消费者接收发送到 greetings 地址的消息并格式化回复

Router 通过 HTTP 暴露健康和就绪检查

提示
Vert.x Infinispan 开箱即用地提供集群健康检查。io.vertx.ext.cluster.infinispan.ClusterHealthCheck 验证底层 Infinispan 集群状态。

对于本地测试,一个 main 方法是直接从 IDE 启动 Verticle 的简便方法

启动时,Vert.x Infinispan 使用默认的网络堆栈,该堆栈结合了用于发现的 IP 多播和用于组消息的 TCP 连接。这个网络堆栈非常适合在我们的开发机器上进行测试。我们稍后将看到如何切换到适合部署到 Kubernetes 的堆栈。

前端服务

前端服务封装在 FrontendVerticle 类中。

它通过环境变量进行配置

当 Verticle 启动时,它会设置一个 Vert.x Web Router 并绑定一个 HTTP 服务器

Router/hello URI 定义了一个 GET 处理程序,此外它还通过 HTTP 暴露健康和就绪检查

/hello URI 的 HTTP 请求处理程序提取 name 参数,通过事件总线发送请求并将回复转发给客户端

对于本地测试,一个 main 方法是直接从 IDE 启动 Verticle 的简便方法

本地测试

您可以启动每个服务

  • 直接从您的 IDE 运行,或者

  • 使用 Maven:mvn compile exec:java,或者

  • 使用 Gradle:./gradlew run (Linux, macOS) 或 gradlew run (Windows)。

前端服务输出应打印一条类似以下内容的消息

2020-07-16 16:29:39,478 [vert.x-eventloop-thread-2] INFO  i.v.howtos.cluster.FrontendVerticle - Server started and listening on port 8080

后端

2020-07-16 16:29:40,770 [vert.x-eventloop-thread-2] INFO  i.v.howtos.cluster.BackendVerticle - Server started and listening on port 38621
提示
记下 backend HTTP 服务器端口。默认情况下,它使用随机端口以避免与 frontend HTTP 服务器冲突。
注意
以下示例使用 HTTPie 命令行 HTTP 客户端。如果您的系统尚未安装,请参阅其安装文档。

首先,让我们向前端发送一个对 /hello URI 的请求,并将 name 查询参数设置为 Vert.x Clustering

http :8080/hello name=="Vert.x Clustering"

您应该会看到类似以下内容:

HTTP/1.1 200 OK
content-length: 36

Hello Vert.x Clustering from unknown
注意
unknown后端POD_NAME 环境变量未定义时使用的默认 pod 名称。

我们还可以验证前端的就绪状态

http :8080/readiness
HTTP/1.1 200 OK
content-length: 65
content-type: application/json;charset=UTF-8

{
    "checks": [
        {
            "id": "cluster-health",
            "status": "UP"
        }
    ],
    "outcome": "UP"
}

以及后端

http :38621/readiness
HTTP/1.1 200 OK
content-length: 65
content-type: application/json;charset=UTF-8

{
    "checks": [
        {
            "id": "cluster-health",
            "status": "UP"
        }
    ],
    "outcome": "UP"

部署到 Kubernetes

首先,请确保 Minikube 已通过 minikube status 命令启动。

注意
如果您不使用 Minikube,请验证 kubectl 已连接到您的集群。

推送容器镜像

不同的方法 将容器镜像推送到 Minikube。

在本文档中,我们将直接推送到集群内的 Docker 守护进程。为此,我们必须将 shell 指向 Minikube 的 Docker 守护进程

eval $(minikube -p minikube docker-env)

然后,在同一个 shell 中,我们可以使用 Jib 构建镜像

  • 使用 Maven:mvn compile jib:dockerBuild,或者

  • 使用 Gradle:./gradlew jibDockerBuild(Linux、macOS)或 gradlew jibDockerBuild(Windows)。

注意
Jib 不会使用 Docker 守护进程来构建镜像,而只用于推送镜像。
注意
如果您不使用 Minikube,请参阅 Jib MavenJib Gradle 插件文档,了解如何配置它们以推送到注册表。

集群应用程序无头服务

在 Kubernetes 上,Infinispan 不应使用默认网络堆栈,因为 IP 多播通常不可用。

相反,我们将配置它使用一个依赖于 无头服务 查找进行发现并使用 TCP 连接进行组消息传递的堆栈。

让我们创建一个 clustered-app 无头服务,它选择带有标签 cluster:clustered-app 的成员 pod

重要
即使 pod 尚未就绪(publishNotReadyAddresses 设置为 true),无头服务也必须考虑这些 pod。

应用此配置

kubectl apply -f headless-service.yml

然后验证它是否成功

kubectl get services clustered-app

您应该会看到类似以下内容:

NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
clustered-app   ClusterIP   None         <none>        7800/TCP   63m

前端部署和服务

现在让我们部署前端服务。

我们至少需要两个副本以实现高可用性。

为了配置 Vert.x Infinispan,我们需要使用一些系统属性启动 JVM

  • java.net.preferIPv4Stack

  • vertx.jgroups.config:网络堆栈配置文件,设置为 default-configs/default-jgroups-kubernetes.xml

  • jgroups.dns.query:我们刚刚创建的无头服务的 DNS 名称

然后 Kubernetes 需要知道用于存活、就绪和启动探针的 URI。

提示
启动探针可以指向具有不同超时设置的就绪 URI。

应用此配置

kubectl apply -f frontend/deployment.yml

验证 pod 是否已成功启动

kubectl get pods

您应该会看到类似以下内容:

NAME                                  READY   STATUS    RESTARTS   AGE
frontend-deployment-8cfd4d966-lpvsb   1/1     Running   0          4m58s
frontend-deployment-8cfd4d966-tctgv   1/1     Running   0          4m58s

我们还需要一个服务来负载均衡 HTTP 流量。Pod 将通过在部署中定义的标签 app:frontend 进行选择

应用此配置

kubectl apply -f frontend/service.yml

验证服务是否已成功创建

kubectl get services frontend

您应该会看到类似以下内容:

NAME       TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
frontend   LoadBalancer   10.106.16.88   <pending>     80:30729/TCP   62s

如果您使用 Minikube,请打开另一个终端窗口并运行

minikube tunnel

Minikube tunnel 作为单独的进程运行,并将服务暴露给主机操作系统。

如果您再次运行 kubectl get services frontend,那么外部 IP 应该已经设置。

NAME       TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
frontend   LoadBalancer   10.100.254.64   10.100.254.64   80:30660/TCP   30m
提示
记下外部 IP。
重要

Minikube tunnel 需要权限提升。如果您没有权限执行此操作,您仍然可以通过NodePort 使用 minikube service --url frontend 访问服务。

注意
如果您不使用 Minikube 并且没有为您的服务分配外部 IP,请参阅您的集群文档。

后端部署

后端服务部署与前端类似。

请注意,在这种情况下

  • 应该创建 3 个副本

  • POD_NAME 环境变量将在容器中设置

应用此配置

kubectl apply -f backend/deployment.yml

验证 pod 是否已成功启动

kubectl get pods

您应该会看到类似以下内容:

NAME                                  READY   STATUS    RESTARTS   AGE
backend-deployment-74d7f45c67-h7h9c   1/1     Running   0          63s
backend-deployment-74d7f45c67-r45bc   1/1     Running   0          63s
backend-deployment-74d7f45c67-r75ht   1/1     Running   0          63s
frontend-deployment-8cfd4d966-lpvsb   1/1     Running   0          15m
frontend-deployment-8cfd4d966-tctgv   1/1     Running   0          15m

远程测试

我们现在可以向前端发送一个对 /hello URI 的请求,并将 name 查询参数设置为 Vert.x Clustering

http 10.100.254.64/hello name=="Vert.x Clustering"

您应该会看到类似以下内容:

HTTP/1.1 200 OK
content-length: 64

Hello Vert.x Clustering from backend-deployment-74d7f45c67-6r2g2

请注意,我们现在可以看到 pod 的名称,而不是默认值(unknown)。

此外,如果您反复发送请求,您会看到 backend 服务以轮询的方式接收事件总线请求。

总结

本文档涵盖了

  • 在 Kubernetes 上使用 Infinispan 部署 Vert.x 集群应用程序所需的依赖项

  • 使用 Jib 对 Vert.x 服务进行容器化

  • Vert.x Infinispan 集群管理器在本地测试和 Kubernetes 部署中的配置


最后发布:2025-02-03 00:42:38 +0000。