基于K8S平台springMVC,springboot项目通过jenkins实现CI/CD

一、背景和原理

1.1 背景

由于公司新项目线采用K8S来管理应用,所以会出现应用频繁发版的情况。

1.2 原理

大致过程就是从gitlab上拉取代码,然后编译,修改配置文件为生产环境配置,通过写好的dockerfile打包应用成镜像,然后push到远程镜像仓库,最后通过kubectl set image实现服务无中断更新。

二、基础jenkins项目搭建过程

2.1 参数化构建项目 【This project is parameterized】

2.1.1 projectVals

项目名称由两部分组成,“,”前面的是k8s中的deploymentName,“,”后面的是服务名称;这些参数在下面的执行时shell会使用到。

2.2.2 gitVersion

应用的git版本号,这个参数由用户传入。

2.1.3 isSpringBoot

boolean 类型的参数,用来判断应用是否为springboot项目,默认不勾选为springMVC项目

2.1.4 isMvnBuild

boolean 类型的参数,用来判断应用是否需要编译,默认勾选启用编译

2.1.5 dockerStore

choice 类型的参数,阿里云远程镜像仓库名称

2.1.6 dockerHubName/dockerHubPasswd

远程镜像仓库名称,因为把镜像push到远程镜像仓库是需要用户名和密码的,这些参数作为参数传递进去。

2.1.7 isUpdateDPM

是否需要更新应用镜像,默认勾选

2.1.8 nameSpace

选择生产环境执行在那个命名空间更新镜像

2.2 限制项目运行的节点 【Restrict where this project can be run】

2.3 通过执行时shell构建项目 【Execute shell】

2.3.1 执行时shell

  • 执行时shell需要根据自身的应用针对性的修改下,以下执行时shell只是提供参考
contentName="$project"
currentTime=`date "+%Y%m%d%H%M"`
echo $currentTime
export PATH="/opt/apache-maven-3.3.3/bin:$PATH"

projectVals=(${projectVals//,/ })
projectName=${projectVals[0]}
project=${projectVals[1]}
finalName=${projectVals[2]}

if [ "$finalName" == "" ]; then
  finalName=$project
fi

tag=$finalName-${gitVersion##*/}-$currentTime

if [ "true" = "$isMvnBuild" ]; then

  echo "编译开始……"
  cd /programs
  
  if [ -d $project ]; then 
	echo $project" is exist"
  else 
	git clone [email protected]:backstage/$project.git
  fi

  cd /programs/$project/
  
  if [ "true" = "$isMvnBuild" ]; then
    git fetch origin
    git checkout $gitVersion
    git pull origin $gitVersion
  fi
  
  rm -rf ~/.m2/repository/com/mogucaifu/

  if [ "mogu-im" = "$project" ]; then
    sh insurance.sh  
  else
    mvn clean package -Dmaven.test.skip=true
  fi
  
  echo "编译完成。"
fi

cd /programs/$project/

if [ "true" != "$isSpringBoot" ] ; then

  cd target/$finalName/WEB-INF/classes
  pwd
  ls
  if [ -f "$finalName-mq.properties" ] ; then
  	sed -i 's|.mg.addr|1-mg-addr|g' $finalName-mq.properties
  	sed -i 's|mq-mg-addr|mq1-mg-addr|g' $finalName-mq.properties
  fi
  
  echo "set prod zookeeper"
  sed -i 's|{dubbo.registry.address}|{dubbo.registry.cluster.address}|g' $finalName-*.xml
  
  if [ ! -z "`grep 'redis' $finalName-spring-context-server.xml`" ]; then
    echo "set prod redis config"
    sed -i 's|redis-cluster|redis|g' $finalName-spring-context-server.xml
    sed -i 's|=redis.mg.addr|=mgy-insurance-redis.redis.rds.aliyuncs.com|g' $finalName-*redis.properties
    sed -i 's|=Mogu07550831..|=Mogu07550831**|g' $finalName-*redis.properties
  fi
  
  if [ ! -z "`grep 'jdbc.properties' $finalName-spring-context-server.xml`" ]; then
    echo "set prod mysql config"
    sed -i 's|jdbc.mg.addr|mgy-insurance.mysql.rds.aliyuncs.com|g' *jdbc.properties
    sed -i 's|jdbc.moni.username=moni|jdbc.moni.username=insurance|g' *jdbc.properties
    sed -i 's|jdbc.moni.password=moni_test|jdbc.moni.password=Insurance07550831**|g' *jdbc.properties
    sed -i 's|jdbc.game.username=game|jdbc.game.username=insurance|g' *jdbc.properties
    sed -i 's|jdbc.game.password=game_test|jdbc.game.password=Insurance07550831**|g' *jdbc.properties
  fi
  
  if [ ! -z "`grep 'mongo.properties' $finalName-spring-context-server.xml`" ]; then
    echo "set prod mongo config"
    sed -i 's|=mongo.mg.addr:27017|=mgyinsurance.mongodb.rds.aliyuncs.com:3717,mgyinsurancesec.mongodb.rds.aliyuncs.com:3717|g' *-mongo.properties
    sed -i 's|mongo.mg.addr|mgyinsurancesec.mongodb.rds.aliyuncs.com|g' *-mongo.properties
    sed -i 's|mongo.readonly.mg.addr|mgyinsurancesec.mongodb.rds.aliyuncs.com|g' *-mongo.properties
    sed -i 's|27017|3717|g' *-mongo.properties
  fi

  if [ ! -z "`grep 'redisson' $finalName-spring-context-server.xml`" ]; then
    echo "set prod redisson config"
    sed -i 's|redisson-cluster.xml|redisson.xml|g' $finalName-spring-context-server.xml
  fi


  if [ -f "mogu-user-center-server-conf.properties" ] ; then
    sed -i 's|sys.orgId=1000|sys.orgId=12000|g' mogu-user-center-server-conf.properties
  fi

  cd /programs/$project/target
  cp /programs/Dockerfile .
  sed -i "s|{project}|${finalName}|g" Dockerfile

else

  cd /programs/$project/target
  jarfile=`ls *.jar | head -1`
  
  pwd
  ls
  
  if [ "chicken-server" = "$project" ]; then
    jar -xf $jarfile
    	
    sed -i 's|dubbo.registry.address|dubbo.registry2.address|g' BOOT-INF/classes/application.properties
    sed -i 's|dubbo.registry.cluster.address|dubbo.registry.address|g' BOOT-INF/classes/application.properties
    sed -i 's|jdbc.mg.addr|mgy-insurance.mysql.rds.aliyuncs.com|g' BOOT-INF/classes/application.properties
    sed -i 's|spring.datasource.username=moni|spring.datasource.username=insurance|g' BOOT-INF/classes/application.properties
    sed -i 's|spring.datasource.password=moni_test|spring.datasource.password=Insurance07550831**|g' BOOT-INF/classes/application.properties
    sed -i 's|redis.conf.path=redis-cluster.properties|redis.conf.path=redis.properties|g' BOOT-INF/classes/application.properties
    sed -i 's|redis.xml.path=chicken-server-redis-cluster.xml|redis.xml.path=chicken-server-redis.xml|g' BOOT-INF/classes/application.properties
    
    sed -i 's|redis.mg.addr|mgy-insurance-redis.redis.rds.aliyuncs.com|g' BOOT-INF/classes/redis.properties
    sed -i 's|Mogu07550831..|Mogu07550831**|g' BOOT-INF/classes/redis.properties
    
    sed -i 's|.mg.addr|1-mg-addr|g' BOOT-INF/classes/chicken-server-mq.properties
  	sed -i 's|mq-mg-addr|mq1-mg-addr|g' BOOT-INF/classes/chicken-server-mq.properties
    
    sed -i 's|=mongo.mg.addr|=mgyinsurance.mongodb.rds.aliyuncs.com|g' BOOT-INF/classes/mongodb.properties
    sed -i 's|27017|3717|g' BOOT-INF/classes/mongodb.properties
    
    cp -f BOOT-INF/classes/application.properties classes/
  
    jar -uvf $jarfile BOOT-INF/classes/application.properties BOOT-INF/classes/mongodb.properties BOOT-INF/classes/redis.properties BOOT-INF/classes/chicken-server-mq.properties
   
  fi
  
  cp -f /programs/sbDockerfile Dockerfile
  sed -i "s|{project}|${project}|g" Dockerfile
  sed -i "s|{jarfile}|${jarfile}|g" Dockerfile

fi

sudo docker login --username $dockerHubName --password $dockerHubPasswd registry-internal.cn-shenzhen.aliyuncs.com
sudo docker build -t registry-internal.cn-shenzhen.aliyuncs.com/moguyun-prod/$dockerStore:$tag .
sudo docker push registry-internal.cn-shenzhen.aliyuncs.com/moguyun-prod/$dockerStore:$tag 


echo "tag=${tag}" > /programs/temp-propfile.txt
echo "projectName=${projectName}" >> /programs/temp-propfile.txt


  • 执行时shell用到的Dockerfile
FROM registry.moguyun.com/tomcat:9.26
MAINTAINER XXX moguyun.com

ENV SOURCEPATH {project}
ENV TARGETPATH /opt/tomcat/webapps
ENV RUN_OPTION "-Xms1g -Xmx4g -Xmn256m -Dfile.encoding=UTF-8"

ADD $SOURCEPATH $TARGETPATH/$SOURCEPATH

RUN echo 'echo "export dubboPort=$DUBBO_PORT" >> /etc/profile' >> /bin/sysinit.sh

EXPOSE 8080
CMD ["sh", "-c", "/bin/sysinit.sh \"$RUN_OPTION\" \"$PNAME\" 0 \"$DUBBO_PORT\" "]
  • 执行时shell用到的sbDockerfile
FROM registry.moguyun.com/centos:7.6
MAINTAINER XXX moguyun.com

ENV JAR_FILE {jarfile}
ENV RUN_PORT 8080
ENV RUN_OPTION "-server -Xms1g -Xmx4g -Xmn256m -Dfile.encoding=UTF-8"

COPY $JAR_FILE /opt/app.jar
COPY classes/application* /opt/

WORKDIR /opt
RUN cd /opt && mkdir logs && sh -c "touch /opt/app.jar"

ENTRYPOINT ["sh","-c","java $RUN_OPTION -jar app.jar --server.port=$RUN_PORT "]

2.3.2 注入环境变量 【Inject environment variables】

  • 把执行时shell生成的包含tag和project的文件填入配置文件路径

  • 配置文件内容

2.4 生成后操作 【Post-build Actions】

  • 由于生产环境K8S只允许内网访问,上面项目运行的 “docker-build” 机器为测试环境机器。所以需要跳到生产内网机器【监控看板】上执行 k8s-dpm-update这个自由风格的项目。

2.5 参数化构建项目 【build with parameter】

  • 选好参数就可以进行构建了,这个项目会触发"k8s-dpm-update"这个自由风格的项目,下面我们看看被触发的项目是怎么定义的

三、更新镜像jenkins项目搭建过程

3.1 项目运行节点 【Restict where this project can be run】

  • podK8SNode是生产内网的一台机器,可以通过kubctl访问到生产K8S

3.2 执行时shell

  • 由于 “基础jenkins项目” 已经注入了环境变量,所以这些变量可以在这个项目中直接使用,就可以实现更新镜像了
echo "isUpdateDPM=${isUpdateDPM}"
echo "imageTag=${imageTag}"
echo "depName=${depName}"
echo "dockerStore=${dockerStore}"
echo "nameSpace=${nameSpace}"

if [ "true" = "$isUpdateDPM" ] ; then

  kubectl set image deployment/$depName $depName=registry-vpc.cn-shenzhen.aliyuncs.com/XXXX/$dockerStore:$imageTag -n $nameSpace
 
fi
发布了161 篇原创文章 · 获赞 40 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_36441027/article/details/103028356