一、背景
由于公司业务发展,更新过于频繁,需要引入一套CI/CD工作流,希望有代码push到gitlab上项目的master分支上自动触发jenkins项目,然后通过jenkins实现自动部署到服务器。
二、构建CI工作流
2.1 配置jenkins中的job
2.1.1 勾选“Build when a change is pushed to GitLab”
- 勾选触发gitlab trigger的事件
- 选取指定分支通过事件触发trigger
- 生成secret,记录CI url
2.2 配置Gitlab
2.2.1 勾选Allow requests to the local network from hooks and services
2.2.2 配置webhook
- 填入jenkins中生成的url和secret
2.2.3 验证webhook
- 点击Test的Push event进行测试,返回200证明已经通过webhook触发了jenkins自动部署项目
2.3 Jenkins自由风格项目构建
2.3.1 构建参数
- 项目名称,预先填入容器名称和服务名称,在后面的执行时shell会用到这个参数
- git分支,默认是master分支,因为这个项目是由合并代码到master分支的事件来触发的
- 镜像仓库名称,本项目中是生产B环境,所以镜像仓库名称为env-b
- 是否需要进行灰度更新,默认为true
- 灰度环境机器ip地址,因为编译源代码,构建镜像是在一台单独的机器,和灰度环境是隔离开的
2.3.2 执行时shell
- 从gitlab上拉取指定项目的代码,切换到master分支,编译代码
- 把rocketmq,zookeeper,mysql,mongo,redis的测试配置替换为生产配置
- 替换Dockerfile中的{project}为指定项目名称,通过指定Dockerfile制作镜像,push到远程仓库
- 到指定灰度机器启动镜像,这样服务就跑在灰度机器上了
currentTime=`date "+%Y%m%d%H%M"`
echo $currentTime
export PATH="/opt/apache-maven-3.3.3/bin:$PATH"
projectVals=(${projectVals//,/ })
projectName=${projectVals[0]}
containerArray=(${projectName//-/ })
container=${containerArray[1]}
project=${projectVals[1]}
tag=$project-${gitVersion}-$currentTime
echo "编译开始……"
cd /plk/source
if [ -d $project ]; then
echo $project" is exist"
else
git clone [email protected]:backstage/$project.git
fi
cd /plk/source/$project/
git fetch origin
git checkout $gitVersion
git pull origin $gitVersion
rm -rf ~/.m2/repository/com/mogucaifu/
mvn clean package -Dmaven.test.skip=true
echo "编译完成。"
echo "替换生产配置"
cd target/$project/WEB-INF/classes
if [ -f "$project-mq.properties" ] ; then
sed -i 's|.mg.addr|-mg-addr|g' $project-mq.properties
sed -i 's|mq-mg-addr|mq1-mg-addr:9876;mq2-mg-addr:9876;mq3-mg-addr|g' $project-mq.properties
fi
sed -i 's|{dubbo.registry.address}|{dubbo.registry.cluster.address}|g' $project-*.xml
if [ ! -z "`grep 'jdbc.properties' $project-spring-context-server.xml`" ]; then
echo "set prod mysql config"
sed -i 's|jdbc.mg.addr:3306/moni|rm-***.mysql.rds.aliyuncs.com:3306/moni_b|g' *jdbc.properties
sed -i 's|jdbc.mg.addr:3306/game|rm-***.mysql.rds.aliyuncs.com:3306/game_b|g' *jdbc.properties
sed -i 's|.username=moni|.username=***|g' *jdbc.properties
sed -i 's|.username=game|.username=***|g' *jdbc.properties
sed -i 's|.password=moni_test|.password=***|g' *jdbc.properties
sed -i 's|.password=game_test|.password=***|g' *jdbc.properties
fi
if [ ! -z "`grep 'mongo.properties' $project-spring-context-server.xml`" ]; then
echo "set prod mongo config"
sed -i 's|=mongo.mg.addr:27017|=dds-***.mongodb.rds.aliyuncs.com:3717|g' *-mongo.properties
sed -i 's|mongo.mg.addr|dds-***.mongodb.rds.aliyuncs.com|g' *-mongo.properties
sed -i 's|mongo.readonly.mg.addr|dds-***.mongodb.rds.aliyuncs.com|g' *-mongo.properties
fi
if [ ! -z "`grep 'redis' $project-spring-context-server.xml`" ]; then
echo "set prod redis config"
sed -i 's|redis-cluster|redis|g' $project-spring-context-server.xml
sed -i 's|=redis.mg.addr|=mgsc-env-b.redis.rds.aliyuncs.com|g' $project-*redis.properties
sed -i 's|=***|=***|g' $project-*redis.properties
fi
cd /plk/source
cp -f /plk/source/Dockerfile.mvc_v2 Dockerfile/Dockerfile.${project}
sed -i "s|{project}|${project}|g" Dockerfile/Dockerfile.${project}
sudo docker build -f /plk/source/Dockerfile/Dockerfile.${project} -t registry-vpc.cn-shenzhen.aliyuncs.com/moguyun-pre/$dockerStore:$tag .
sudo docker login --username $dockerHubName --password $dockerHubPasswd registry-vpc.cn-shenzhen.aliyuncs.com
sudo docker push registry-vpc.cn-shenzhen.aliyuncs.com/moguyun-pre/$dockerStore:$tag
if [ "true" == "$isPreUpdate" ] ; then
sshpass -p Mogupro0601sz ssh root@$preEnvHost "cd /docker/k8s; sh -x ${projectName}.sh $tag 2>&1 &"
fi
- 制作镜像Dockerfile文件
1.Dockerfile.mvc_v2
FROM registry.moguyun.com/tomcat:9.26
MAINTAINER heqx moguyun.com
ENV SOURCEPATH {project}
ENV TARGETPATH /opt/tomcat/webapps
ENV RUN_OPTION "-Xms1g -Xmx4g -Xmn256m -Dfile.encoding=UTF-8"
ADD $SOURCEPATH $TARGETPATH/$SOURCEPATH
EXPOSE 8080
CMD ["sh", "-c", "/bin/sysinit.sh \"$RUN_OPTION\" \"$PNAME\" 0 \"$DUBBO_PORT\" "]
- 灰度机器运行镜像脚本
1.app-ttkx.sh
/docker/k8s/common.run game-ttkx-server ttkx $1 6204 9904
2.common.run
#!/bin/sh
project=${1}
pro=${project//_/-}
pname=${2}
RUN_PORT=${4}
DEBUG_PORT=${5}
version="registry-vpc.cn-shenzhen.aliyuncs.com/moguyun-pre/env-b:${3}"
JVM_OPTION="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${DEBUG_PORT}
-Duser.timezone=GMT+08 -Dfile.encoding=UTF-8 -server -Xms256m -Xmx1024m "
echo "/docker/tomcat/logs/$project"
echo "JVM_OPTION=$JVM_OPTION"
echo "a1=$1"
echo "a2=$2"
echo "a3=$3"
echo "a4=$4"
echo "a5=$5"
docker stop $pname && docker rm $pname
docker run -d --name $pname \
-v /etc/hosts:/etc/hosts:ro \
-v /docker/tomcat/logs/$project:/opt/tomcat/logs:rw \
-p $RUN_PORT:8080 \
-p $DEBUG_PORT:$DEBUG_PORT \
-e RUN_OPTION="$JVM_OPTION" \
-e PNAME="$pname" \
$version
sleep 35
docker logs --tail 1500 $pname
参考链接: