Kubernetes 客户端负载均衡

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

您将构建什么

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

  • 监听针对 / URI 的 HTTP 请求

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

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

它由一个名为 microservice 的单一部分组成,与部署在 Kubernetes 中的另一个 Pod 进行通信。

您需要什么

  • 文本编辑器或 IDE

  • Java 11 或更高版本

  • Maven 或 Gradle

  • Minikube 或任何 Kubernetes 集群

  • kubectl 命令行工具

创建项目

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

依赖项

项目依赖于

Service Resolver 库是一个插件,它允许 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 环境变量进行配置。

负载均衡部分采用轮询策略,非常简单。

还有其他可用策略。

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

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

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

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

部署到 Kubernetes

首先,使用 minikube status 确保 Minikube 已启动。

注意
如果您不使用 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 服务进行容器化


最后发布时间:2025-02-06 00:41:51 +0000。