Docker(五):Docker 企业实战之部署SpringBoot项目

最终目标

通过docker-maven-plugin插件实现springboot项目自动构建镜像并将镜像推送到公司私有仓库,后续通过从私有仓库拉取项目镜像后启动项目,完成整个项目的发布部署

构建镜像文件

构建docker镜像可以使用两种方式

  • 第一种是将构建信息指定到 POM 中,支持FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD等dockerfile指令
  • 第二种是使用Dockerfile 构建,支持所有dockerfile命令
  • 但是如果使用 VOLUME 或其他 Dockerfile 中的命令的时候,需要使用第二种方式,所以

 注意:但是如果使用 VOLUME 或其他 Dockerfile 中的命令的时候,只能使用第二种方式,并需要在 POM 中配置 dockerDirectory 来指定Dockerfile路径

    POM文件

	
    
		 
		1.1.1
		
	    
        xx.xxx.xx.xx:5000
    
	
	
        
            

				
                
                    com.spotify
                    docker-maven-plugin
                    ${docker.maven.plugin.version}
                    
                        
                        ${project.build.outputDirectory}
                        

                        
                        ${docker.registry}/${project.artifactId}:${project.version}
                        
                       
					   
                        
                            ${project.version}
                        
						
						
                        
                            
                                /
								
								
                                ${project.build.directory}
								
								
                                ${project.build.finalName}.jar
								
                            
                        
						
                        
                        ${docker.registry}
                        
                        true
                        
                        docker-registry
                    
                

            
        

        
        	
    

    docker-registry
    demo
    demo
    
        [email protected]
    

 注意: pom中对应的对应的值也需要在maven的setting.xml中配置私有仓库认证信息 

    Dockerfile文件

# 基于jdk镜像
# jdk 版本=> anapsix/alpine-java:8_jdk_unlimited
FROM anapsix/alpine-java:8_server-jre_unlimited

# 将本地文件夹挂载到当前容器
VOLUME /tmp

# 配置主机和Docker服务时区和时间同步
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 维护人
MAINTAINER jqy 

# 设置语言
# 查看Docker支持的語言: locale -a, C.UTF-8可以支持中文。
ENV LANG C.UTF-8

# 开放端口
EXPOSE 67000

# 设置Java堆栈环境变量值(默认为空,建议由启动的shell脚本设置对应参数值)
ENV JAVA_OPTS ""

# 设置JVM Server环境变量值(默认为空,建议由启动的shell脚本设置对应参数值)
ENV JVM_SERVER_OPTS=""

# 拷贝文件到容器,也可以直接写成ADD
# 注意:如果使用*匹配文件,則在每次打包動作中都包含一次Clean動作,以保存文件的唯一性。
# 将项目构建生成的xxx-*.jar包复制到docker容器且名称为app.jar
#ADD xxx-1.0.0-RELEASE.jar /app.jar
ADD xxx-*.jar /app.jar

# 配置容器启动后执行的命令
#ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
ENTRYPOINT exec java $JAVA_OPTS $JVM_SERVER_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar

Idea配置Maven打包以及构建镜像命令

Run Configurations -> Goals:mvn clean package docker:build

注意:由于pom文件已配置自动推送,构建完镜像后自动推送到私有仓库,所以命令不需要显示执行docker push命令

启动

企业实际开发中,通常会采用shell脚本命令执行

#/bin/bash
# author: sb
# Description: Use docker shell to start micro-server.
# 注意:
# 此脚本必须预先执行如下指令:
# 1. $PROJECTNAME_VERSION
# 2. 服务器确保存在/data/gc/log文件夾

# JVM 默認常量
# JAVA_OPTS
JAVA_OPTS_6G="JAVA_OPTS=-Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M"
# JVM_SERVER_OPTS
JVM_SERVER_OPTS="JVM_SERVER_OPTS=-server -XX:+DisableExplicitGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+CMSClassUnloadingEnabled -XX:+ParallelRefProcEnabled -XX:+CMSScavengeBeforeRemark -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:ErrorFile=/var/app/gc/hs_err_pid%p.log -XX:HeapDumpPath=/var/app/gc -Xloggc:/var/app/gc/gc%t.log";

# 判断是否设置镜像版本以及日志文件
if [ ! -n "$PROJECTNAME_VERSION" ]; then
  echo "Please set    PROJECTNAME_VERSION at first"
  exit -1
fi

if [ ! -d "/data/gc/log/" ];then
    mkdir /data/gc/log
    echo 'the directory /data/gc/log is created.'
else
    echo 'the directory /data/gc/log is existed.'
fi

# 启动所有服务
function start_all()
{
    start_demo_web
    start_demo_report
}

#docker run 命令参数说明
#	#docker run 
#	-p 77770:77770                               #将容器的端口映射到主机(服务器)端口,即我们可以通过主机端口进行访问应用
#	-dit                                         # -d 后台模式,-it 交互对话模式,结合使用则保证容器不会退出,一直在后台运行
#	-e "SPRING_PROFILES_ACTIVE=test2"            #-e 设置使用的config配置文件;
#	-e "$JAVA_OPTS_6G" 				             #-e 设置环境变量;
#	-e "$JVM_SERVER_OPTS"                        #-e 设置环境变量;
#	-v /data/gc/log:/var/app/gc                  # 将宿主机的目录挂载到容器里,语法为“docker run -v /宿主机目录:/容器目录”
#	--name=demo-web                              #--name 为容器指定一个名称
#	-h "demo-web"                                #--h 设置一个主机名称
#	--add-host peer1:10.112.112.112              #添加自定义主机到IP的映射(host:ip)
#	--add-host peer2:10.112.112.112
#	-v /data/cdp-logs/demo:/logs                 #绑定挂载卷
#    仓库ip:5000/demo-web:$PROJECTNAME_VERSION   #镜像名


# 啟動 Demo_web
# 必須指定: $PROJECTNAME_VERSION
# 60290
function start_demo_web ()
{
    echo 'starting Demo_web'

    echo `docker run -p 77770:77770 -dit -e "SPRING_PROFILES_ACTIVE=test2" -e "$JAVA_OPTS_6G" -e "$JVM_SERVER_OPTS" -v /data/gc/log:/var/app/gc --name=demo-web -h "demo-web" --add-host peer1:10.112.112.112 --add-host peer2:10.112.112.112 -v /data/cdp-logs/demo:/logs 仓库ip:5000/demo-web:$PROJECTNAME_VERSION`

    echo 'Demo_web started'
}

# 啟動 Demo_ report
# 必須指定: $PROJECTNAME_VERSION
# 端口: 60295
function start_demo_report ()
{
    echo 'starting Demo_ report'
	
    echo `docker run -p 77770:77770 -dit -e "SPRING_PROFILES_ACTIVE=test2" -e "$JAVA_OPTS_6G" -e "$JVM_SERVER_OPTS" -v /data/gc/log:/var/app/gc --name=demo-report -h "demo-report" --add-host peer1:10.112.112.112 --add-host peer2:10.112.112.112 -v /data/cdp-logs/demo:/logs 仓库ip:5000/demo-web:$PROJECTNAME_VERSION`

    echo 'Demo_ report started'
}

# 刪除 Demo web 容器
function remove_container_demo_web ()
{
    echo 'starting remove container Demo_web'
    # stop and rm
    docker stop demo-web && docker rm -f demo-web
    echo 'contianer Demo_web removed'
}

# 刪除 Demo web 鏡像
function remove_image_demo_web ()
{
    echo 'starting remove image Demo_web'
    docker rmi 私有仓库ip:5000/demo-web:$PROJECTNAME_VERSION
    echo 'image Demo_web removed'
}

# 刪除 Demo_ report 容器
function remove_container_demo_report ()
{
    echo 'starting remove container Demo_ report'
    docker rm -f demo-report
    echo 'contianer Demo_ report removed'
}

# 刪除 Demo_ report 鏡像
function remove_image_demo_report ()
{
    echo 'starting remove image Demo_ report'
    docker rmi 私有仓库ip:5000/demo-report:$PROJECTNAME_VERSION
    echo 'image Demo_ report removed'
}

# 啟動入口
case "$1" in
all)
    # 啟動所有 Demo 應用
    start_all
    ;;
web)
    # 僅啟動 Demo Web
    start_demo_web
    ;;
report)
    # 僅啟動 report
    start_demo_report
    ;;

remove_container_web)
    # 移除 Demo web 容器
    start_demo_web
    start_demo_report
    ;;
remove_all_containers)
    # 移除所有
    remove_container_Demo_web
    remove_container_Demo_report
    ;;
remove_image_web)
    # 移除 web 鏡像
    remove_container_Demo_web
    remove_image_Demo_web
    ;;
remove_image_report)
     # 移除 report 鏡像
    remove_container_Demo_report
    remove_image_Demo_report
    ;;

remove_all_images)
    # 移除所有鏡像
    remove_container_Demo_web
    remove_image_Demo_web

    remove_container_Demo_report
    remove_image_Demo_report

    ;;
*)
    echo "please input start key, all|web|remove_container_web|report|remove_container_report|remove_all_containers|remove_image_web|remove_image_report|remove_all_images"
    exit -2
    ;;
esac

 其中shell脚本命令中关于JVM参数设置说明

# JVM 默認常量
# JAVA_OPTS
JAVA_OPTS_6G="
	JAVA_OPTS=               #JAVA_OPTS用来设置JVM相关运行参数的变量
		-Xmx1344M            #java Heap堆最大内存
		-Xms1344M            #java 初始Heap 堆内存大小
		-Xmn448M             #young Generation的堆内存大小,一般设置为Xmx的三分之一或者四分之一
		-XX:MaxMetaspaceSize=192M  #设置元空间最大大小,java8后永久代称为元空间,相比永久代元空间不受制于堆内存而是基于操作系统内存,但仍需要设置上限
		-XX:MetaspaceSize=192M"    #设置元空间大小

# JVM_SERVER_OPTS
JVM_SERVER_OPTS=
	"JVM_SERVER_OPTS=
		-server 
		-XX:+DisableExplicitGC  #禁止显式执行GC,不允许调用System.gc()的方法,否则并发度高的情况下STW的短暂停顿效果就被强化成了长时间停顿甚至对外展示效果就是服务不响应
		-XX:+UseParNewGC        #设置年轻代为多线程收集。可与CMS收集同时使用。在serial基础上实现的多线程收集器。
		-XX:+UseConcMarkSweepGC #基于标记清除算法实现的多线程老年代垃圾回收器。CMS为响应时间优先的垃圾回收器
		-XX:+UseCMSInitiatingOccupancyOnly   #在使用CMS收集器的情况下,指定老年代被使用的内存空间的阈值,达到该阈值则触发Full GC,参数CMSInitiatingOccupancyFraction才会生效
		-XX:CMSInitiatingOccupancyFraction=70  #回收阈值
		-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses   #触发full gc 只不过在CMS在full gc 效率比较高。
		-XX:+CMSClassUnloadingEnabled          #相对于并行收集器,CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收
		-XX:+ParallelRefProcEnabled            #开启尽可能并行处理Reference对象,建议开启
		-XX:+CMSScavengeBeforeRemark           #在CMS的重新标记阶段之前执行年轻代Young GC,可减少相当一部分的需要标记的对象,减少CMS重新标记时间的开销,建议开启
		-XX:+HeapDumpOnOutOfMemoryError        #当发生 OOM时,自动转储堆内存快照,缺省情况未指定目录时,JVM 会创建一个名称为 java_pidPID.hprof 的堆 dump 文件在 JVM 的工作目录下
		-XX:+PrintGCDetails     #打印详细的GC日志
		-XX:+PrintGCTimeStamps 
		-XX:+PrintHeapAtGC                     #在GC前后打印GC日志
		-XX:+PrintGCApplicationStoppedTime     #打印应用暂停时间
		-XX:+PrintGCDateStamps                 #GC日志打印时间戳信息
		-XX:ErrorFile=/var/app/gc/hs_err_pid%p.log 
		-XX:HeapDumpPath=/var/app/gc           #指定OOM时堆内存转储快照位置
		-Xloggc:/var/app/gc/gc%t.log";         #指定GC日志目录和文件名
		/logs 10.175.94.63:5000/cdp-cofa-offline-report-ws

你可能感兴趣的:(Docker,docker,java,springboot)