本文梳理不同Java应用如何迁移到k8s。
定时任务(Maven)
确定基础镜像
openjdk:8-jre-alpine
搞定服务运行的相关文件
查看Java源码
1 | package com.mooc.demo.cronjob; |
用Maven将应用打成jar包
1 | mvn package |
确保应用可以直接运行:
1 | java -jar xxx.jar |
或采用library方式运行:
1 | java -cp xxx.jar com.mooc.xxx.Main |
构建Dockerfile
1 | FROM hub.wangfanggang.com/kubernetes/openjdk:8-jre-alpine |
编写k8s配置文件
cronjob.yaml
1 | apiVersion: batch/v1beta1 |
部署到k8s
1 | kubectl apply -f cronjob.yaml |
检查服务是否正常运行
1 | kubectl get cronjob |
刚部署时ACTIVE=0
,过一段时间后,cronjob被自动调度起来,ACTIVE=1
查看pod信息
1 | kubectl get pods -o wide |
可以看到cronjob服务被部署在了w2
节点上,而且如我们预期,k8s保留了3次成功的pod信息。
切换到w2
上检查docker是否正常运行了
1 | docker ps -a | grep cronjob |
通过 docker logs [container_id]
可以看到cronjob正常完成了。
如果发现pod的状态是
ErrDockerPull
,说明节点从镜像仓库下载镜像时出错了,切换到对应节点,用docker login hub.wangfanggang.com
检查是否可以访问镜像仓库。
SpringBoot
将springboot打成jar包
DemoController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package com.mooc.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
public class DemoController {
"/hello") (
public String sayHello(@RequestParam String name) {
return "Hello "+name+"! I'm springboot-web-demo controller!";
}
}
用maven将springboot应用打包
1 | mvn package |
查看生成的jar文件1
jar -tf springboot-web-demo-1.0-SNAPSHOT.jar
运行jar包,检查服务是否可以正常启动。
1 | java -jar target/springboot-web-demo-1.0-SNAPSHOT.jar |
打开浏览器,访问一下hello
服务 http://localhost:8080/hello?name=kenny
可以看到服务正常返回结果了,说明我们的jar包没问题。
编写Dockerfile
1 | FROM hub.wangfanggang.com/kubernetes/openjdk:8-jre-alpine |
构建Docker镜像
1 | docker build -t springboot-web:v1 . |
测试Docker容器
1 | docker run -it -p 8080:8080 springboot-web:v1 |
可以看到springboot服务可以正常启动。
编写k8s配置文件
这里的k8s服务发现策略是用ingress-nginx
来做服务发现。
springboot-web.yaml
1 | #deploy |
可以看到,配置文件里
ingress
下添加了跳转规则,凡是访问springboot.xyz.com
的,都会自动跳转到springboot-web-demo
这个服务上,且端口是80。
部署springboot服务到k8s
1 | kubectl apply -f springboot-web.yaml |
测试服务是否正常,访问http://springboot.xyz.com/hello?name=kwang
说明springboot服务已被k8s正常调度了。
传统Dubbo应用
Dubbo源码介绍
dubbo-demo-api
模块定义的API接口DemoService.java
1 | package com.mooc.demo.api; |
dubbo-demo
模块下实现API接口DemoServiceImpl.java
1 | package com.mooc.demo.service; |
dubbo.properties
1
2
3
4
5dubbo.application.name=demo
dubbo.registry.address=zookeeper://10.155.20.62:2181
dubbo.spring.config=classpath*:spring/provider.xml
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
start.sh
1 |
|
stop.sh
1 |
|
由于没有用SpringBoot,需要自己来实现打包。
打包Dubbo应用
安装必要的API接口服务
1 | cd dubbo-demo-api |
执行mvn package
将应用打包。
1 | cd dubbo-demo |
打包成功,查看打包好的文件是否包含了我们需要的所有文件。
1 | tar -tf target/dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz |
测试打包文件,运行start.sh
脚本启动应用。
1 | cd target |
测试dubbo服务是否正常。
编写Dockerfile
1 | FROM hub.wangfanggang.com/kubernetes/openjdk:8-jre-alpine |
注意:由于我们的
start.sh
脚本里是以后台启动的dubbo服务(nohup
),这样的话一旦脚本运行完毕,docker容器也会推出,所以需要把nohup
去掉,让脚本在前台执行,避免docker容器自动推出。
构建Docker镜像
1 | docker build -t dubbo:v1 . |
测试Doker镜像
1 | docker run -it dubbo:v1 |
确定k8s服务部署策略
采用hostNetwork
方式部署dubbo服务,需要修改Dockerfile
动态修改服务端口。
重新构建docker镜像。
将Docker镜像推送到镜像仓库上
1 | docker tag dubbo:v1 hub.wangfanggang.com/kubernetes/dubbo:v1 |
编写k8s配置文件
dubbo.yaml
1 | #deploy |
注意:这里的
podAntiAffinity
可以阻止服务被部署在同一个节点上,发生端口冲突。
在k8s配置文件里定义一个环境变量
DUBBO_PORT
, 对应我们刚才修改的start.sh
里的变量。
部署k8s服务
1 | kubectl apply -f dubbo.yaml |
测试k8s服务
迁移传统的Web服务
查看Java源码
DemoController.java
1 | package com.mooc.demo.controller; |
applicationContext-service-config.xml
1 | <?xml version="1.0" encoding="UTF-8"?> |
applicationContext.xml
1 | <?xml version="1.0" encoding="UTF-8"?> |
确定基础镜像
因为是传统的Web服务,需要选择一个tomcat容器。
打包Java文件
1 | mvn package |
将打包文件解压到待安装目录中
1 | cd target |
编写Dockerfile
1 | FROM hub.wangfanggang.com/kubernetes/tomcat:8.0.51-alpine |
编写一个脚本文件,在tomcat启动后,执行一个
tail
命令,以便让脚本在容器中挂起。
start.sh
1 |
|
构建Docker镜像
1 | docker build -t web:v1 . |
测试Docker镜像
1 | docker run -it web:v1 |
将Docker镜像上传到镜像仓库
1 | docker tag web:v1 hub.wangfanggang.com/kubernetes/web:v1 |
确定k8s服务发现策略
使用ingress-nginx
编写k8s配置文件
web.yaml
1 | #deploy |
部署到k8s
1 | kubectl apply -f web.yaml |