docker是一个非常方便的部署工具,一般来说我们会把每个jar包打成一个docker镜像,如果jar包非常多,就会非常占资源,所以就直接一个容器多个jar运行,做个笔记以防忘记,内容多为copy而来。
首先需要一个Dockerfile文件
# 环境
FROM java:8
# 作者信息
MAINTAINER wyler "467135974@qq.com"
# 将本地文件tmp挂载到容器
VOLUME /tmp
#拷贝
COPY run.sh /run.sh
COPY gateway-0.0.1-SNAPSHOT.jar /gateway-0.0.1-SNAPSHOT.jar
COPY admin-client-0.0.1-SNAPSHOT.jar /admin-client-0.0.1-SNAPSHOT.jar
COPY device-client-0.0.1-SNAPSHOT.jar /device-client-0.0.1-SNAPSHOT.jar
COPY admin-server-0.0.1-SNAPSHOT.jar /admin-server-0.0.1-SNAPSHOT.jar
COPY device-server-0.0.1-SNAPSHOT.jar /device-server-0.0.1-SNAPSHOT.jar
# RUN命令
RUN chmod 777 /run.sh
# 执行命令
ENTRYPOINT ["/run.sh"]
然后还有一个run.sh文件
#!/bin/bash
start1(){
echo "starting gateway....."
nohup java -jar /gateway-0.0.1-SNAPSHOT.jar > gateway.log &
}
start2(){
echo "starting admin-client....."
nohup java -jar /admin-client-0.0.1-SNAPSHOT.jar > adminclient.log &
}
start3(){
echo "starting device-client....."
nohup java -jar /device-client-0.0.1-SNAPSHOT.jar > deviceclient.log &
}
start4(){
echo "starting admin-server....."
nohup java -jar /admin-server-0.0.1-SNAPSHOT.jar > adminserver.log &
}
start5(){
echo "starting device-server....."
nohup java -jar /device-server-0.0.1-SNAPSHOT.jar > deviceserve.log &
}
#定义一个方法pid_health_check $1是这个方法的参数,其他地方调用此方法传入进来
pid_health_check(){
#定义一个linux的命令字符串 $1是这个方法的参数类似于(ps -ef|grep tomcat 的命令),其他地方调用此方法传入进来
#这个命令解释: 搜索linux中的进程 并且过滤掉-带grep的那条
process_cnt=`ps -ef | grep $1 | grep -v grep | wc -l`
#表示执行上面定义的process_cnt命令
echo $process_cnt
#返回值-上面命令查询出来的日志的条数
return $?
}
##在脚本最后一行添加tail -f /dev/null,这个命令永远完成不了,所以该脚本一直不会执行完,所以该容器永远不会退出
##tail -f /dev/null
##我这里写的死循环就不用上面的那个查看日志的命令了
start1
start2
start3
start4
start5
while [[ 1 -gt 0 ]]
do
echo "check healthy of gateway...."
process_cnt=$(pid_health_check gateway-0.0.1-SNAPSHOT)
##if语句 (ps -ef|grep relations-analysis)查询结果小于1表示此服务已经停了
if [[ $process_cnt -lt 1 ]]
then
start1
fi
echo "check healthy of admin-client...."
process_cnt=$(pid_health_check admin-client-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start2
fi
echo "check healthy of device-client...."
process_cnt=$(pid_health_check device-client-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start3
fi
echo "check healthy of admin-server...."
process_cnt=$(pid_health_check admin-server-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start4
fi
echo "check healthy of device-server...."
process_cnt=$(pid_health_check device-server-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start5
fi
##睡眠1
sleep 1m
done
自己有多少个jar就写多少个start方法,run.sh里的 /admin-client-0.0.1-SNAPSHOT.jar 是与Dockerfile里 /admin-client-0.0.1-SNAPSHOT.jar 是对应的。
运行docker命令打包镜像
docker build -t cloud .
注意后面的 . 不能省略
运行打包成功后的镜像容器
docker run -d --name cloud --restart=always -p 8799:8799 cloud
--restart=always 表示一直运行 -p 表示映射的端口,可以映射多个,这里我是把我的网关服务端口映射出来,毕竟我只需要这个端口来作为访问入口。
还有个容易出现的小问题,可能运行容器时会失败,可以通过 docker logs cloud 查看日志报错
可能会看到如下错误:
standard_init_linux.go:178: exec user process caused "no such file or directory"
standard_init_linux.go:178: exec user process caused "no such file or directory"
standard_init_linux.go:178: exec user process caused "no such file or directory"
原因是镜像的entrypoint设置的启动脚本格式是dos,在linux系统上用vi修改成unix格式即可
# vi filename(run.sh)
# :set ff 回车后看到当前文件的fileformat格式
# :set ff=unix 回车后输入:wq保存文件,重新build镜像即可。
添加日志分割版本
安装cronolog
yum install cronolog
查看cronolog
which cronolog
run.sh
#!/bin/bash
start1(){
echo "starting gateway....."
nohup java -jar /gateway-0.0.1-SNAPSHOT.jar | /usr/sbin/cronolog /logs/gateway/gateway-%Y-%m-%d.log &
}
start2(){
echo "starting admin-client....."
nohup java -jar /admin-client-0.0.1-SNAPSHOT.jar | /usr/sbin/cronolog /logs/adminclient/adminclient-%Y-%m-%d.log &
}
start3(){
echo "starting device-client....."
nohup java -jar /device-client-0.0.1-SNAPSHOT.jar | /usr/sbin/cronolog /logs/deviceclient/deviceclient-%Y-%m-%d.log &
}
start4(){
echo "starting admin-server....."
nohup java -jar /admin-server-0.0.1-SNAPSHOT.jar | /usr/sbin/cronolog /logs/adminserver/adminserver-%Y-%m-%d.log &
}
start5(){
echo "starting device-server....."
nohup java -jar /device-server-0.0.1-SNAPSHOT.jar | /usr/sbin/cronolog /logs/deviceserver/deviceserver-%Y-%m-%d.log &
}
#定义一个方法pid_health_check $1是这个方法的参数,其他地方调用此方法传入进来
pid_health_check(){
#定义一个linux的命令字符串 $1是这个方法的参数类似于(ps -ef|grep tomcat 的命令),其他地方调用此方法传入进来
#这个命令解释: 搜索linux中的进程 并且过滤掉-带grep的那条
process_cnt=`ps -ef | grep $1 | grep -v grep | wc -l`
#表示执行上面定义的process_cnt命令
echo $process_cnt
#返回值-上面命令查询出来的日志的条数
return $?
}
##在脚本最后一行添加tail -f /dev/null,这个命令永远完成不了,所以该脚本一直不会执行完,所以该容器永远不会退出
##tail -f /dev/null
##我这里写的死循环就不用上面的那个查看日志的命令了
start1
start2
start3
start4
start5
while [[ 1 -gt 0 ]]
do
echo "check healthy of gateway...."
process_cnt=$(pid_health_check gateway-0.0.1-SNAPSHOT)
##if语句 (ps -ef|grep relations-analysis)查询结果小于1表示此服务已经停了
if [[ $process_cnt -lt 1 ]]
then
start1
fi
echo "check healthy of admin-client...."
process_cnt=$(pid_health_check admin-client-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start2
fi
echo "check healthy of device-client...."
process_cnt=$(pid_health_check device-client-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start3
fi
echo "check healthy of admin-server...."
process_cnt=$(pid_health_check admin-server-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start4
fi
echo "check healthy of device-server...."
process_cnt=$(pid_health_check device-server-0.0.1-SNAPSHOT)
if [[ $process_cnt -lt 1 ]]
then
start5
fi
##睡眠1
sleep 1m
done
/usr/sbin/cronolog 是通过查看命令获取具体位置
/logs/gateway/gateway-%Y-%m-%d.log 是具体生成的日志
打包 docker build -t cloud .
运行
docker run -d --name cloud --restart=always -p 8799:8799 \
-v /root/logs/gateway:/logs/gateway \
-v /root/logs/adminclient:/logs/adminclient \
-v /root/logs/deviceclient:/logs/deviceclient \
-v /root/logs/adminserver:/logs/adminserver \
-v /root/logs/deviceserver:/logs/deviceserver \
-v /usr/sbin/cronolog:/usr/sbin/cronolog \
cloud
-v 代表挂载,将本地目录与容器内目录挂载