部署由 Vert.x 驱动的 Knative 服务

本操作指南将向您展示如何部署基于 Vert.x 的 Knative 服务。

您将构建什么

  • 您将编写一个接受 Asciidoc 文本并使用 Asciidoctor 生成 HTML 渲染的服务。

  • 此服务将使用 Kotlin 编写。

  • 将使用 Jib 创建包含该函数的容器镜像。

  • 此服务将使用 Knative/serving 进行部署。

您需要什么

  • 文本编辑器或 IDE

  • Java 11 或更高版本

  • Maven 或 Gradle

  • Docker

  • 一个已安装 Knative/serving 的正常运行的 Kubernetes 集群。

什么是 Knative 服务?为什么 Vert.x 是一个很好的选择?

Knative 启动容器镜像(默认 3 个)以响应请求,并在没有流量一段时间后缩减到 0。Knative/serving 提供的“函数”本质上是一个用任何语言编写并打包为容器镜像的 HTTP 服务。

Vert.x 是在 JVM 上编写 Knative 服务的理想选择,因为

  1. Vert.x 应用程序启动非常快,因为运行时没有“魔法”发生,

  2. 可以使用 GraalVM 编译进一步减少启动时间和内存占用(超出本操作指南的范围),

  3. Vert.x 应用程序资源高效,即使在高负载下也能保持响应,

  4. Vert.x 为其他中间件(数据库、消息传递等)提供了庞大的响应式客户端生态系统,

  5. 一个 main 方法/函数就足以引导 Vert.x 应用程序!

创建项目

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

使用 Gradle

以下是您应该使用的 build.gradle.kts 文件的内容

  1. 我们需要 Kotlin、vertx-webasciidoctorj

  2. Gradle 应用程序插件允许我们使用 run 命令在本地运行应用程序。

  3. 用于生成镜像的 Jib 配置。

使用 Maven

以下是您应该使用的 pom.xml 文件的内容

  1. 我们需要 Kotlin、vertx-webasciidoctorj

  2. 允许使用 mvn exec:java 运行。

  3. 用于生成镜像的 Jib 配置。

编写服务

该服务暴露一个 HTTP 服务器。Asciidoc 通过 HTTP POST 请求传递给函数。对于每个请求,Asciidoctor 用于执行到 HTML 的转换

package io.vertx.howtos.knative.serving

import io.vertx.core.Vertx
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.BodyHandler
import org.asciidoctor.Asciidoctor
import org.asciidoctor.Options
import org.asciidoctor.SafeMode

fun main() {
  val vertx = Vertx.vertx() // (1)

  val asciidoctor = Asciidoctor.Factory.create()  // (2)
  val options = Options.builder()
    .safe(SafeMode.SAFE)
    .backend("html5")
    .standalone(true)
    .build()

  val router = Router.router(vertx)
  router.route().handler(BodyHandler.create())  // (3)

  router.post().handler { ctx ->  // (4)
    ctx.response()
      .putHeader("Content-Type", "text/html")
      .end(asciidoctor.convert(ctx.body().asString(), options))
  }

  vertx.createHttpServer()
    .requestHandler(router)
    .listen(8080)
    .await()
}
  1. 我们创建一个 Vert.x 上下文。

  2. 我们配置一个 Asciidoctor 渲染器。

  3. 我们安装了一个 HTTP 请求体处理器,这样我们就可以直接处理整个请求体,而不是手动组装缓冲区。

  4. 对于每个请求,我们从 Asciidoc 渲染 HTML。

我们可以将 Vert.x 代码编写为一个 verticle,但在这里,无论如何我们都只部署一个 verticle,所以在 main 函数中这样做可以减少样板代码。

在本地运行函数

我们可以轻松测试服务是否正常工作

  1. 从您的 IDE 运行 main 函数,或者

  2. 使用 Gradle:./gradlew run(Linux、macOS)或 gradle run(Windows)。

  3. 使用 Maven:mvn compile exec:java

然后,您可以上传 Asciidoc 文件的内容,例如此仓库根目录下的 README.adoc 文件。使用 HTTPie,您可以运行类似于以下命令:

http POST :8080/ @README.adoc

准备您的集群

本操作指南中的命令假定您已使用 快速启动安装 Knative 和 Minikube。

构建您的容器镜像

Gradle 或 Maven 构建中的 Jib 插件将自动组装一个容器镜像,其中包含正确的入口点以运行应用程序,并暴露 8080 端口。然后,该容器镜像必须推送到您喜欢的仓库中。

如果您正在使用 Minikube,可以直接构建并标记容器镜像

eval $(minikube docker-env -p knative)
./gradlew jibDockerBuild    # or mvn package jib:dockerBuild

Docker 应该会列出该镜像

docker image ls

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

REPOSITORY                                    TAG       IMAGE ID
(...)
dev.local/jponge/knative-vertx-asciidoctor    latest    4ca7aafd590c
dev.local/jponge/knative-vertx-asciidoctor    v1        4ca7aafd590c
(...)

为 Knative 描述服务

以下是文件 service.yaml 中用于使用 Knative/serving 暴露我们服务的描述符

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: knative-vertx-asciidoctor
  namespace: default
spec:
  template:
    spec:
      containers:
        - image: dev.local/jponge/knative-vertx-asciidoctor:v1

然后,我们可以应用配置并检查服务是否可用

kubectl apply -f service.yaml

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

service.serving.knative.dev/knative-vertx-asciidoctor created

然后

kubectl get ksvc

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

NAME                        URL                                                               LATESTCREATED                     LATESTREADY                       READY   REASON
knative-vertx-asciidoctor   http://knative-vertx-asciidoctor.default.10.101.169.49.sslip.io   knative-vertx-asciidoctor-00001   knative-vertx-asciidoctor-00001   True

测试 Knative 暴露的服务

使用 Minikube,向函数发出请求类似于

http POST knative-vertx-asciidoctor.default.10.101.169.49.sslip.io @README.adoc

您应该在响应中看到 HTML。

注意

如果您的系统无法解析 sslip.io 名称,请从 URL 中提取 IP 并尝试类似以下内容:

http POST 10.101.169.49 'Host:knative-vertx-asciidoctor.default.10.101.169.49.sslip.io' @README.adoc

您还应该看到您的服务的 Pod

kubectl get pods

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

NAME                                                          READY   STATUS    RESTARTS   AGE
knative-vertx-asciidoctor-mlhwq-deployment-5cc999bdb7-jx2ff   3/3     Running   0          2m5s

过了一会儿,您可以检查 Knative 自动扩缩器是否已移除所有 Pod

kubectl get pods

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

No resources found.

发出一个新请求,然后您会看到新的 Pod 再次被创建。

总结

  • 我们使用 Vert.x 和 Kotlin 编写了一个 Knative 服务,它将 Asciidoc 文本渲染为 HTML。

  • 我们构建了一个容器镜像。

  • 我们使用 Knative/serving 部署了此服务。


最近发布:2025-02-03 00:48:12 +0000。