docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > 在Docker中部署运行jar

如何在Docker中部署运行jar

作者:justry_deng

这篇文章主要介绍了如何在Docker中部署运行jar问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

基本前提条件

1、系统已安装Docker。

2、系统可上网。

第一大步

docker search justrydeng搜索Docker的JDK镜像

注:这是本人自己组装并上传到Docker官方仓库里的一个jdk8的镜像。如果读者不想用这个镜像,那么也可以使

用其他的jdk镜像。

第二大步

docker pull justrydeng/jdk8拉取(下载)镜像

此时,就可以看到:本地有镜像了:

第三大步

根据要运行的.jar文件,使用Dockerfile + build生成对应的新镜像,并利用该镜像生成容器

假设:我们要运行的jar包是jenkins-0.0.1-SNAPSHOT.jar。

第一小步:创建一个Dockerfile文件并编写,如(这是编写后的样子):

FROM justrydeng/jdk8
MAINTAINER dengshuai<13548417409@163.com>
RUN mkdir /var/jarDir && mkdir /var/jarDir/jenkins-docker-test
CMD ["nohup","java","-jar","/var/jarDir/jenkins-docker-test/jenkins-0.0.1-SNAPSHOT.jar","&"]

提示:此CMD里为启动jar包的指令,根据不同的需求,编写对应的启动jar包指令即可。

说明一:RUN指令的作用是当利用新的镜像创建容器后,容器马上再创建一个目录,来放置后面会放进去的jar文件,这么做的目的是为了归类方便管理。

追注:实际上,此一步不是必要的,因为一般而言,一个Docker容器就运行一个jar包,所以也可以直接将jar包放置在/下也行。

说明二:CMD指令的作用是:当docker start 启动容器后(注意:是启动,而不是创建),会马上执行该指令。

第二小步:使用docker build指令,生成新的镜像;如这里:

docker build -t justrydeng/jar . -f jarDockerfile

说明一:因为我们创建新的镜像时,不需要什么外部的东西,所以我们指定其上下文“母体”时,最好指定一个空的文件夹或者指定一个几乎不含内容的文件夹。本人这里为了方便,指定的是当前文件夹。

此时,可看见,已经生成了新的镜像:

第三小步:使用docker run指令,配置映射、生成容器,如:

docker run -p 8080:8080 --name jenkins-docker-test -d justrydeng/jar

说明一:-p 8080:8080作用是,将宿主机的端口8080(前面那个),与docker的端口8080(后面那个)映射。

说明二:docker ps 只能查看正在运行着的容器,而docker ps -a可以查看所有的容器。

第四大步

使用docker cp将宿主机中的jar包,拷贝至容器中的对应位置

如:

docker cp jenkins-0.0.1-SNAPSHOT.jar jenkins-docker-test:/var/jarDir/jenkins-docker-test

说明一:将jar包放进容器中的对应的位置(即:Dockerfile的CMD指令对应的位置)。

说明二:只要容器存在(无论容器是否正在运行),就能将东西放进去。

第五大步

docker start启动容器即可

如:

docker start jenkins-docker-test

第六大步

http://宿主机ip:映射后的宿主机端口访问测试

提示,该jar包中的Controller方法有:

访问:http://10.8.109.60:8080/jenkins/test?name=JustryDeng

由此可见:在Docker的容器中部署运行jar包,成功!

拓展一

编写一个通用的运行jar包的镜像(这里只给思路,不给具体示例)

> Dockerfile如:

FROM justrydeng/jdk8
MAINTAINER dengshuai<13548417409@163.com>
RUN mkdir /jarAppDir/
CMD ["nohup","java","-jar","/jarAppDir/app.jar","&"]

> 生成镜像docker build -t justrydeng/common-run-jar . -f jarDockerfile

注: -f 可以指定Dockerfile文件的文件名。

> 在后面使用时,我们可以使用同一个镜像来制作对应不同端口(不同服务)的容器

docker run -p 宿主机端口:要映射的容器端口 --name 容器名 -d justrydeng/common-run-jar

> 在更新jar包时,需要在把xxx.jar包复制进容器时,统一重命名为app.jar

docker cp 宿主机jar包 容器名(或容器ID):/jarAppDir/app.jar

说明:此方式的优势在于:每次如果要更新jar包,只需要先将容器stop,然后直接替换容器里面的jar包,最后再将该容器start即可。无需每次都创建新的镜像,创建新的容器。

拓展二

解决Docker部署微服务时,服务之间不能调用的问题(示例)

调用服务出错时的Eureka:

如图所示:

eureka找服务时,会根据服务名【efficiency-taskrelease-service】,找到对应的要访问的地址【6129d46c643e:2050】;一般的,如果我们在微服务中只配了:

的话,那么这个服务注册到eureka中的就可能是【主机名:服务应用名称:服务端口号】。

如果主机名是localhost的话,那可能影响不大;

但是如果主机名是其他的什么的话(如:6129d46c643e),那么就可能造成java.net.UnknownHostException: 6129d46c643e异常,将微服务放在Docker容器中进行服务注册时可能会出问题,微服务会将Docker容器的主机名(而不是宿主机的主机名)注册到eureka上,这时我们可以通过配置,来指定使用宿主机的ip,如:

注:此时,可以不需要指定server.port了,因为我们已经在eureka.instance.instance-id中指明了;但spring.application.name还是需要指明的。

配置完成后,再重启服务,再次查看eureka,可看见:

此时,微服务集成Docker时,各个服务不能调用的问题就得到了解决!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文