目的:
将原本可以通过如下命令

//运行client.jar 包中的 io.grpc.examples.helloworld.HelloWorldServer 的主函数,并且要依赖同级目录libs下的jar包
java  -Djava.ext.dirs=libs  -cp client.jar  io.grpc.examples.helloworld.HelloWorldServer

运行的java项目打包为docker image镜像文件

grpc-demo目录结构如下(grpc-demo是一实现grpc的一个demo)

│  client.jar
└─libs
        error_prone_annotations-2.1.2.jar
        grpc-context-1.14.0.jar
        grpc-core-1.14.0.jar
        grpc-netty-shaded-1.14.0.jar
        grpc-protobuf-1.14.0.jar
        grpc-protobuf-lite-1.14.0.jar
        grpc-stub-1.14.0.jar
        gson-2.7.jar
        guava-20.0.jar
        hamcrest-core-1.3.jar
        jsr305-3.0.0.jar
        junit-4.11.jar
        opencensus-api-0.12.3.jar
        opencensus-contrib-grpc-metrics-0.12.3.jar
        proto-google-common-protos-1.0.0.jar
        protobuf-java-3.5.1.jar

流程:

将项目打包成docker镜像可以在ide中使用有关的打包并上传到镜像仓库的插件,这里介绍的是手动使用命令打包

1、 将grpc-demo项目上传至运行了docker 的主机上,并进入到grpc-demo目录中

2、 编写制作镜像的命令文件也就是DockerFile

vi DockerFileService

内容如下:

#指定以openjdk:8-jre 为基础镜像,来构建此镜像,可以理解为运行的需要基础环境
FROM openjdk:8-jre
#WORKDIR指令用于指定容器的一个目录, 容器启动时执行的命令会在该目录下执行。
WORKDIR /
#将当前client.jar 复制到容器根目录下
ADD client.jar client.jar
#将依赖包 复制到容器根目录/libs下
ADD libs /libs
#暴露容器端口为50051 Docker镜像告知Docker宿主机应用监听了50051端口
EXPOSE 50051
#容器启动时执行的命令
CMD java -Djava.ext.dirs=libs  -cp client.jar  io.grpc.examples.helloworld.HelloWorldServer

3、使用docker build 构建镜像

//docker build
// . 表示当前目录 -f 参数指定Dockerfile文件  -t 表示 制作的镜像tag  
docker build -f DockerfileServer  -t  grpcdemo/helloworld-server:1.0.0  .

4、 构建成功后使用 docker images 查看是否存在grpcdemo/helloworld-server:1.0.0 这个镜像

5 、可以使用docker run 运行打包好的镜像,查看是否能按需求运行

//-d 表示后台运行容器 如果使用-d  
docker run -d grpcdemo/helloworld-server:1.0.0

备注:在前台模式下(不指定-d参数即可),Docker会在容器中启动进程,同时将当前的命令行窗口附着到容器的标准输入、标准输出和标准错误中。也就是说容器中所有的输出都可以在当前窗口中看到。甚至它都可以虚拟出一个TTY窗口,来执行信号中断(不加 -d参数 可能会导致当前shell 窗口始终为容器中进程运行的输出内容,甚至(ctrl+c)都无法中断)
这里写图片描述

-d,那么容器将会运行在后台模式。此时所有I/O数据只能通过网络资源或者共享卷组来进行交互。因为容器不再监听你执行docker run的这个终端命令行窗口,只是会输出本次容器启动的containerID。可以使用docker logs containerID 来打印容器应用相关日志’
这里写图片描述
6、docker run 启动对dockerfile中的命令进行重写覆盖
可以在启动容器的时候,为docker run设置新的命令选项,从而覆盖掉Dockerfile文件中的CMD指令(不会再咨询Dockerfile文件中的CMD指令)。示例如下:

#docker run ... <New_Command>,可以给出其他命令以覆盖Dockerfile文件中的默认指令
docker run  -d grpcdemo/helloworld-server:1.0.0  java -cp client.jar  io.grpc.examples.helloworld.HelloWorldClient

7、 覆盖EXPOSE指令
Dockerfile文件中的 EXPOSE指令,用以向容器所在主机保留端口。
显然这是运行时容器的一个特性,所以docker run可以方便地覆盖该指令。示例如下:

docker run --expose="port_number:port_number"

相关链接

【docker 从入门到实践书籍pdf】 https://legacy.gitbook.com/book/yeasy/docker_practice/details
【十张图带深入理解docker 容器和镜像】http://dockone.io/article/783
【Run a Simple .jar Application in a Docker Container】 https://dzone.com/articles/run-simple-jar-application-in-docker-container-1

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐