1. 概述

如今,Java 开发者在使用 Kubernetes 构建和部署应用程序时拥有多种选择。本文档将介绍其中一个名为 JKube 的工具。

2. 什么是 JKube?

JKube 是一组工具,旨在简化构建具有部署到云环境意图的 Java 应用程序的过程。它是由 Eclipse 基金会管理的项目,并在他们的 ECL-2.0 许可证下提供使用。

更具体地说,JKube 允许我们将 Java 应用程序编译成 Docker 容器镜像,然后将这些镜像部署到 Kubernetes 或 OpenShift。

它还提供了其他工具来使监控和调试云应用更加容易。

3. 使用 JKube 上手

JKube 的核心工具大多通过 Maven 或 Gradle 插件提供。出于简洁考虑,下面的例子仅关注使用 Maven 插件与 Kubernetes 环境。

要开始使用,我们只需将 插件添加到我们的 Maven POM:

<plugin>
    <groupId>org.eclipse.jkube</groupId>
    <artifactId>kubernetes-maven-plugin</artifactId>
    <version>1.13.1</version>
</plugin>

值得注意的是,Maven Kubernetes 插件采取了一些意见化的观点以简化设置。然而,它也支持通过 XML 和 YAML 配置进行精细控制。有关详细信息,请参阅 开发者文档

3.1. 构建 Docker 镜像

无需进一步配置,我们就可以生成 Docker 镜像:

mvn package k8s:build

它检查项目结构并选择合适的基镜像使用:

[INFO] --- kubernetes-maven-plugin:1.13.1:build (default-cli) @ jkube-demo ---
[INFO] k8s: Building Docker image
[INFO] k8s: Running generator spring-boot
[INFO] k8s: spring-boot: Using Docker image quay.io/jkube/jkube-java:0.0.19 as base / builder
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Created docker-build.tar in 112 milliseconds
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Built image sha256:6c9d0
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Removed old image sha256:e2458
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Tag with latest

并且我们可以确认该镜像存在于本地 Docker 服务器中:

> docker image ls
REPOSITORY                                 TAG              IMAGE ID       CREATED         SIZE
example/jkube-demo                         latest           6c9d08bcd538   5 minutes ago   605MB

3.2. 部署到 Kubernetes

除了构建 Docker 镜像之外,我们还可以使用 JKube 生成资源描述符并部署我们的应用程序到 Kubernetes

为此,我们需要执行两个 Maven 目标:

mvn k8s:resource k8s:apply

第一个目标生成了我们的应用程序的 部署服务 YAML 文件,尽可能多地设置默认值:

[INFO] --- kubernetes-maven-plugin:1.13.1:resource (default-cli) @ jkube-demo ---
[INFO] k8s: Running generator spring-boot
[INFO] k8s: spring-boot: Using Docker image quay.io/jkube/jkube-java:0.0.19 as base / builder
[INFO] k8s: Using resource templates from jkube-demo/src/main/jkube
[INFO] k8s: jkube-controller: Adding a default Deployment
[INFO] k8s: jkube-service: Adding a default service 'jkube-demo' with ports [8080]
[INFO] k8s: jkube-service-discovery: Using first mentioned service port '8080'
[INFO] k8s: jkube-revision-history: Adding revision history limit to 2
[INFO] k8s: validating jkube-demo/target/classes/META-INF/jkube/kubernetes/jkube-demo-deployment.yml resource
[INFO] k8s: validating jkube-demo/target/classes/META-INF/jkube/kubernetes/jkube-demo-service.yml resource

第二个目标实际上部署到了 Kubernetes 集群:

[INFO] --- kubernetes-maven-plugin:1.13.1:apply (default-cli) @ jkube-demo ---
[INFO] k8s: Using Kubernetes at https://kubernetes.docker.internal:6443/ in namespace null with manifest /Users/mike/github/jkube-demo/target/classes/META-INF/jkube/kubernetes.yml
[INFO] k8s: Creating a Service from kubernetes.yml namespace default name jkube-demo
[INFO] k8s: Created Service: target/jkube/applyJson/default/service-jkube-demo.json
[INFO] k8s: Creating a Deployment from kubernetes.yml namespace default name jkube-demo
[INFO] k8s: Created Deployment: target/jkube/applyJson/default/deployment-jkube-demo.json

最后,我们可以使用 JKube 从 Kubernetes 集群中卸载我们的应用程序:

mvn k8s:undeploy

请记住,构建 Docker 镜像和部署到 Kubernetes 的每个命令都采用了意见化的观点。然而,JKube 提供了自定义每个它们的能力。有关详细信息,请参阅 目标概览

4. JKube 特性

除了构建 Docker 镜像并将其部署到 Kubernetes 外,JKube 还提供了帮助开发应用程序的其他工具。以下我们更详细地了解其中的一些。

4.1. 日志

此目标类似于 Unix 中的 tail 命令它持续显示之前部署的应用程序的输出

要运行此目标,我们使用以下命令:

mvn k8s:log

4.2. 调试

调试 目标允许我们连接 Java 调试器到已部署的应用程序。命令语法如下:

mvn k8s:debug -Djkube.debug.port=8000

运行此命令会执行几项操作。首先,它重新部署应用程序并启用调试。其次,它在指定的调试端口上创建 Kubernetes 端口转发。在运行此命令后,我们可以将 Java 调试器连接到指定的端口并开始远程调试。

由于不断重新部署我们的应用程序可能会耗费时间,我们可以加快速度,总是通过始终启用调试进行部署。为了做到这一点,我们有两个选项。首先,我们可以向 部署 命令添加额外的标志:

mvn k8s:deploy -Djkube.debug.enabled=true

或者,我们可以通过更新 Maven settings.xml 文件:

<?xml version="1.0"?>
<settings>
    <profiles>
        <profile>
            <id>enable-debug</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <jkube.debug.enabled>true</jkube.debug.enabled>
            </properties>
        </profile>
    </profiles>
</settings>

通过这样做,我们避免了每次运行 调试 目标时等待容器重启的时间。

4.3. 监控

此目标自动在检测到项目中文件更改时重新部署应用程序。要启用它,我们运行命令:

mvn k8s:watch

启用监控后,每当项目中的文件发生变化时,JKube 就会为我们重建和重新部署。JKube 提供了针对各种框架的几种 不同的监视器,包括 Spring Boot。

4.4. 推送

我们前面看到的 构建 命令将新镜像发布到本地 Docker 服务器。我们可以通过使用 推送 目标将这些镜像发布到任何远程注册表:

mvn k8s:push

4.5. Helm

类似于上面的 资源 目标,此目标使用从项目中检测到的适当默认值生成 Helm 部署描述符:

mvn k8s:resource k8s:helm

值得注意的是,我们必须先运行 资源 目标才能运行 helm 目标。生成的 Helm 图表有多种 配置方式

5. 总结

在这篇文章中,我们研究了 JKube,一个简化构建 Java 应用程序并部署到 Kubernetes 和 OpenShift 的工具。

通过强大的 Maven 和 Gradle 插件,它提供了构建、监控和部署到两种最受欢迎的容器管理系统(即 Kubernetes 和 OpenShift)的几个工具。

上述示例可以在 GitHub 上找到。