HTTP 与 Web

Kubernetes 上的客户端负载均衡

本文档将向您展示如何在 Kubernetes 上使用微服务执行客户端负载均衡。

您将构建什么

您将构建一个 Vert.x 微服务,它

  • 监听针对 / URI 的 HTTP 请求

  • 使用负载均衡器向后端服务发起 HTTP 请求

  • 发送后端服务的 HTTP 响应内容

它包含一个名为 microservice 的单一组件,该组件与部署在 Kubernetes 中的另一个 Pod 进行通信。

您需要什么

  • 文本编辑器或 IDE

  • Java 11 或更高版本

  • Maven 或 Gradle

  • Minikube 或任何 Kubernetes 集群

  • kubectl 命令行工具

创建项目

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

依赖项

该项目依赖于

服务解析器库是一个插件,它允许 Vert.x 客户端使用逻辑服务名称而不是网络地址调用服务。服务解析器还能够使用常用策略执行客户端负载均衡。

容器化

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

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

  • 它同时支持 Maven 和 Gradle

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

使用 Maven

以下是您应该用于 microservicepom.xml 文件的内容

使用 Gradle

假设您使用带有 Kotlin DSL 的 Gradle,以下是您的 microservicebuild.gradle.kts 文件应有的样子

实现服务

让我们实现 microservice,然后在开发机器上进行测试。

前端服务被封装在 MicroServiceVerticle 类中。

该服务将使用服务地址请求 Kubernetes 集群中的另一个 Pod。microservice Verticle 创建一个配置了负载均衡器解析器HttpClient

为此,我们创建一个地址解析器,它将逻辑 ServiceAddress 作为输入,并返回 HTTP 客户端在实践中可以使用的地址列表。

KubeResolver 是在 Kubernetes 中部署时首选的解析器。请注意,该解析器是使用 new KubeResolverOptions() 创建的,并根据 Kubernetes 设置的 Pod 环境变量进行配置。

负载均衡器部分采用轮询(round-robin)策略,非常简单。

还有其他可用的策略。

我们还需要为我们的服务创建并绑定一个 Web 服务器,这非常简单

最后,让我们看看服务请求处理。

首先,我们向后端服务器创建一个 HTTP 服务器请求。我们不传递后端服务器的套接字地址,而是使用逻辑服务地址,即 Kubernetes 中服务的名称 (hello-node)。

然后我们实现后端服务器的响应处理。我们将原始响应作为我们响应的一部分发送回去,并附加响应的套接字地址,以便我们可以确定服务与哪个服务器进行了交互。

部署到 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 插件文档,了解在推送到注册表时如何配置它们。

后端服务部署

为了简单起见,我们将重用 Minikube 教程中的 HTTP 服务器。

出于本操作指南的目的,我们只需创建一个包含 3 个 Pod 的部署。

kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.39 -- /agnhost netexec --http-port=8080

验证 Pod 已成功启动

kubectl get pods --selector=app=hello-node

您应该看到类似如下内容

NAME                          READY   STATUS    RESTARTS   AGE
hello-node-66d457cb86-vndgc   1/1     Running   0          45s

出于本操作指南的目的,我们将副本数量增加到 3。

kubectl scale deployment hello-node --replicas=3

并验证新的 Pod 已成功启动

NAME                          READY   STATUS    RESTARTS   AGE
hello-node-66d457cb86-m9nsr   1/1     Running   0          11s
hello-node-66d457cb86-vndgc   1/1     Running   0          2m51s
hello-node-66d457cb86-z6x26   1/1     Running   0          11s

最后,我们需要将 Pod 作为服务暴露

kubectl expose deployment hello-node --type=LoadBalancer --port=8080

再次验证服务已成功创建

kubectl get services hello-node

您应该看到类似如下内容

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
hello-node   LoadBalancer   10.101.56.23   <pending>     8080:32159/TCP   2m31s

微服务部署

现在我们可以在 Kubernetes 中部署我们的微服务了。

应用此配置

kubectl apply -f deployment.yml

验证 Pod 已成功启动

kubectl get pods --selector=app=microservice

您应该看到类似如下内容

NAME                                       READY   STATUS    RESTARTS   AGE
microservice-deployment-69dfcbc79c-kk85f   1/1     Running   0          117s

我们还需要一个服务来负载均衡 HTTP 流量。

Pod 将通过部署中定义的标签 app:microservice 进行选择

应用此配置

kubectl apply -f service.yml

验证服务已成功创建

kubectl get services microservice

您应该看到类似如下内容

NAME           TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
microservice   LoadBalancer   10.109.6.50   <pending>     80:30336/TCP   2m3s

最后,我们需要配置 *default* 服务账户,以授予 Vert.x 服务解析器观察端点的权限。

应用此配置

kubectl apply -f roles.yml

测试微服务

现在是时候测试我们的微服务并观察客户端负载均衡的实际运行情况了。

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

minikube service microservice

这将打开一个网页浏览器并展示我们的微服务正在运行,您应该会看到类似以下内容:

Hello from: 10.244.0.48:8080 with: NOW: 2024-11-27 17:18:37.179191424 +0000 UTC m=+1267.971197286

您可以刷新页面,以显示我们的微服务所交互的后端服务的 IP 地址已更改。

后续活动

您可以进一步实现以下功能

总结

本文档涵盖了

  • 在 Kubernetes Pod 之间部署微服务负载均衡所需的依赖项

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