JKube快速部署Java应用至k8s-热部署

641 阅读3分钟

本文介绍kubernetes-maven-plugin使用k8s:watch实现热部署功能。

kubernetes-maven-plugin目前支持两种监视模式:

  • Docker Image Watcher(watches docker images)
  • Spring Boot Watcher(based on Spring Boot Devtools)

spring boot Watcher针对springboot工程。当你修改java代码并执行mvn package命令后,会触发热部署,此功能依赖Spring Boot Devtools。

docker imager Watcher则比较通用。工程里任何打包进Image的文件发生变化,或者Image自身发生变化,在执行mvn package命令后会触发热部署。

在进入监视模式前,必须生成docker映像和Kubernetes资源,并在Kubernetes上部署应用程序。所以kubernetes-maven-plugin插件需要添加如下execution配置,增加resource和build过程

<plugin>
    <groupId>org.eclipse.jkube</groupId>
    <artifactId>kubernetes-maven-plugin</artifactId>
    <version>${jkube.version}</version>

    <executions>
        <execution>
            <goals>
                <goal>resource</goal>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
</plugin>

springboot watcher基于Spring Boot Devtools实现,需要在pom中引入相关依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

同时打包时,也需要将Spring Boot Devtools打包进最终的jar,否则部署到k8s的jar包里不包含Spring Boot Devtools工具,就无法实现热装载功能。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <excludeDevtools>false</excludeDevtools>
    </configuration>
</plugin>

然后你需要在src/main/resources/application.properties文件中添加一个spring.devtools.remote.secret属性,设置你的密钥。如果不设置,执行k8s:watch时,会报如下错误,然后自动生成一个密钥。

No spring.devtools.remote.secret found in application.properties. Plugin has added it, please re-run goals

下面是插件自动生成的application.properties文件内容:

# Remote secret added by jkube-kit-plugin
spring.devtools.remote.secret=53c6fc0b-da6b-4b2c-bd62-165c303179e7

自此就可以愉快的体验热部署功能。 创建一个hot-depolyment工程和一个演示用的Controller。

@RestController
public class HotDeploymentController {
    @RequestMapping("/")
    public String index() {
        return "使用k8s:watch实现热部署!";
    }
}

执行k8s:resource和k8s:build命令创建k8s资源描述文件和docker镜像。 也可以直接运行mvn package命令,其会触发kubernetes-maven-plugin插件resource和build过程执行。

[INFO] --- kubernetes-maven-plugin:1.9.1:resource (default) @ hot-deployment ---
[INFO] k8s: Running generator spring-boot
[INFO] k8s: spring-boot: Using Docker image quay.io/jkube/jkube-java:0.0.16 as base / builder
[INFO] k8s: Using resource templates from D:\i-workspace\jkube-examples\hot-deployment\src\main\jkube
[INFO] k8s: jkube-controller: Adding a default Deployment
[INFO] k8s: jkube-service: Adding a default service 'hot-deployment' with ports [8080]
[INFO] k8s: jkube-healthcheck-spring-boot: Adding readiness probe on port 8080, path='/actuator/health', scheme='HTTP', with initial delay 10 seconds
[INFO] k8s: jkube-healthcheck-spring-boot: Adding liveness probe on port 8080, path='/actuator/health', scheme='HTTP', with initial delay 180 seconds
[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 D:\i-workspace\jkube-examples\hot-deployment\target\classes\META-INF\jkube\kubernetes\hot-deployment-deployment.yml resource

最后执行k8s:watch,部署应用至k8s,同时进入监控模式。

[INFO] k8s: spring-boot: Spring-Remote: WARN 22428 --- [main] o.s.b.d.r.c.RemoteClientConfiguration    : The connection to http://localhost:59740 is insecure. You should use a URL starting with 'https://'.
[INFO] k8s: spring-boot: Spring-Remote: INFO 22428 --- [main] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
[INFO] k8s: spring-boot: Spring-Remote: INFO 22428 --- [main] o.s.b.devtools.RemoteSpringApplication   : Started RemoteSpringApplication in 0.918 seconds (JVM running for 1.575)

下面测试一下热加载的效果,在controller中新增一个方法如下:

@RequestMapping("/newMethod")
public String newMethod() {
    return "新增一个方法";
}

执行mvn package命令。大约5秒左右,刷新页面,可以看到新增的方法:

image.png

5秒的等待时间有点长,可以在pom.xml中设置如下参数,每1000毫秒(默认值是5000毫秒)检查一次变更,这样可以更快的看到效果。

<properties>
    <jkube.watch.interval>1000</jkube.watch.interval>
</properties>

本文示例代码 :github.com/tzjavadmg/j…