微服务架构持续集成:(四)通过jenkins + docker 部署spring cloud微服务

​ 以上我们已经创建了一个项目futurecloud-eshop,并配置Github,包括github地址,用户名和密码,分支,且构建成功。

​ 接下来,我们需要将此项目通过jenkins部署到docker。

1、配置构建环境

  • 增加构建步骤:调用顶级maven目标

    Add pre-build step -> invoker top-level-Maven targets

微服务架构持续集成:(四)通过jenkins + docker 部署spring cloud微服务_第1张图片

配置maven信息

微服务架构持续集成:(四)通过jenkins + docker 部署spring cloud微服务_第2张图片

Maven version: maven-3.6.0 #之前配置的全局maven名
Goals: clean package
POM: pom.xml

  • 继续增加构建步骤:执行shell脚本

    Add post-build step -> execute shell

微服务架构持续集成:(四)通过jenkins + docker 部署spring cloud微服务_第3张图片
在command中添加以下shell脚本

#docker运行服务URL
REGISTRY_URL=xxx.xxx.xxx.xxx:2375
#操作/项目路径(Dockerfile存放的路劲)
BASE_PATH=/work/project
# 源项目工作空间  
SOURCE_PATH=/root/.jenkins/workspace  
#docker 镜像路径,也是父项目路径
PARENT_PATH=futurecloud-eshop
#docker 镜像/容器/项目名字或者jar名字数组 这里都使用项目名命名
PROJECT_NAMES=("eshop-eureka-server" "eshop-product-service" "eshop-price-service" "eshop-inventory-service" "eshop-datasync-service" "eshop-dataaggr-service" "eshop-datalink-service" "eshop-one-service")
#项目版本号/docker 容器tag,使用项目版本号来做tag,版本号要与项目数组PROJECT_NAMES一一对应
PROJECT_VERSIONS=("1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT")
#docker容器暴露的端口,端口号要与项目数组PROJECT_NAMES一一对应,这里为了简化,docker容器端口与宿主机端口配置成一样的。
EXPOSE_PORTS=("8761" "8762" "8763" "8764" "8765" "8766" "8767" "8768")

##############以下内容不用修改

DATE=`date +%Y%m%d%H%M`

#创建项目环境目录
function projectDir(){
	for (( i = 0 ; i < ${#PROJECT_NAMES[@]} ; i++ ))
	do
	  if [ ! -e $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]} ] && [ ! -d $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]} ]; 
		then
		    mkdir -p $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}
		    echo "Create Dir: $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}"
		fi
	done

}

# 备份
function bakup(){
		for (( i = 0 ; i < ${#PROJECT_NAMES[@]} ; i++ ))
		do
			if [ -f "$BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}.jar" ]; then
    		echo "${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}.jar 备份..."
        cp $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}/${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}.jar $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}/backup/${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}-$DATE.jar
        cp $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}/Dockerfile $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}/backup/Dockerfile-$DATE.jar
        echo "备份 ${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}.jar 完成"
	    else
	    	echo "$BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}.jar不存在,跳过备份"
    	fi
		
		done
	
}
 
# 最新构建代码 移动到项目环境
function transfer(){
	
		for (( i = 0 ; i < ${#PROJECT_NAMES[@]} ; i++ ))
		do
			echo "最新构建代码 $SOURCE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}/target/${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}.jar 迁移至 $BASE_PATH/$PARENT_PATH ...."
      cp $SOURCE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}/target/${PROJECT_NAMES[$i]}-${PROJECT_VERSIONS[$i]}.jar $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}
      cp $SOURCE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}/Dockerfile $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}
    	echo "迁移完成"
		done
}
 
# 构建docker镜像
function build(){
	
	for (( i = 0 ; i < ${#PROJECT_NAMES[@]} ; i++ ))
	do
		#镜像id
		IID=$(docker images | grep "${PROJECT_NAMES[$i]}" | awk '{print $3}')
		if [ -n "$IID" ]; then
			echo "存在${PROJECT_NAMES[$i]}镜像,IID=$IID"
		else
			echo "不存在${PROJECT_NAMES[$i]}镜像,开始构建镜像"
			cd $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}
			docker build -t $PARENT_PATH/${PROJECT_NAMES[$i]} .
		fi
	done
	
	
}

function runContainer(){
	
	for (( i = 0 ; i < ${#PROJECT_NAMES[@]} ; i++ ))
	do
		#容器id
		CID=$(docker ps -a | grep "${PROJECT_NAMES[$i]}" | awk '{print $1}')
		if [ -n "$CID" ]; then
			echo "存在${PROJECT_NAMES[$i]}容器,CID=$CID,重启docker容器 ..."
			docker restart ${PROJECT_NAMES[$i]}
			echo "${PROJECT_NAMES[$i]}容器重启完成"
		else
			echo "不存在${PROJECT_NAMES[$i]}容器,docker run创建容器..."
			docker run --name ${PROJECT_NAMES[$i]} -v $BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]}:$BASE_PATH/$PARENT_PATH/${PROJECT_NAMES[$i]} -d -p ${EXPOSE_PORTS[$i]}:${EXPOSE_PORTS[$i]} $PARENT_PATH/${PROJECT_NAMES[$i]}
			echo "${PROJECT_NAMES[$i]}容器创建完成"
		fi
	done
	
}
 
# 运行docker容器
function run(){
	projectDir
	bakup
	transfer
	build
	
	#runContainer
	#启动容器,我们采用docker compose来编排docker容器,解决docker容器之间网络访问的问题
	#先编写docker-compose.yml文件后,放入项目路径下
	cd  $BASE_PATH/$PARENT_PATH
	docker-compose up -d
	
}
 
#入口
run 

​ 以上脚本适合于maven构建的父项目下有多个子模块的项目,在构建项目时,只需要修改以下几个属性。

#docker运行服务URL
REGISTRY_URL=xxx.xxx.xxx.xxx:2375
#操作/项目路径(Dockerfile存放的路劲)
BASE_PATH=/work/project
# 源项目工作空间  
SOURCE_PATH=/root/.jenkins/workspace  
#docker 镜像路径,也是父项目路径
PARENT_PATH=futurecloud-eshop
#docker 镜像/容器/项目名字或者jar名字数组 这里都使用项目名命名
PROJECT_NAMES=("eshop-eureka-server" "eshop-product-service" "eshop-price-service" "eshop-inventory-service" "eshop-datasync-service" "eshop-dataaggr-service" "eshop-datalink-service" "eshop-one-service")
#项目版本号/docker 容器tag,使用项目版本号来做tag,版本号要与项目数组PROJECT_NAMES一一对应
PROJECT_VERSIONS=("1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT" "1.0-SNAPSHOT")
#docker容器暴露的端口,端口号要与项目数组PROJECT_NAMES一一对应,这里为了简化,docker容器端口与宿主机端口配置成一样的。
EXPOSE_PORTS=("8761" "8762" "8763" "8764" "8765" "8766" "8767" "8768")

6、在每个子模块(项目中)编写Dockerfile文件

​ 以下是项目eshop-eureka-server中的Dockerfile脚本

#基于java:8
FROM java:8
VOLUME /tmp
ADD eshop-eureka-server-0.0.1-SNAPSHOT.jar app.jar
#RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
EXPOSE 8761

7、执行构建

8、访问eureka服务,可以看到eureka的页面

微服务架构持续集成:(四)通过jenkins + docker 部署spring cloud微服务_第4张图片

你可能感兴趣的:(微服务架构,分布式架构)