CI/CD-云主机场景CD篇-[前端后端项目|发布|回滚|ActiveChoice参数]
前端后端项目发布
前端项目
- 复制静态文件到nginx站点目录,nginx -s reload
## 进入Web服务器的站点目录下 ## 下载包 [root@master html]# curl -u admin:admin123 http://192.168.1.200:8081/repository/anyops/com/anyops/anyops-devops-ui/1.1.1/anyops-devops-ui-1.1.1.tar.gz -o anyops-devops-ui-1.1.1.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 196k 100 196k 0 0 24.0M 0 --:--:-- --:--:-- --:--:-- 24.0M ## 解压包 [root@master html]# tar zxf anyops-devops-ui-1.1.1.tar.gz [root@master html]# ls anyops-devops-ui-1.1.1.tar.gz index.html static ## 触发nginx重载 [root@master html]# nginx -s reload
后端项目
- 复制jar包到目标目录, 使用nohup java -jar 启动服务。
- nohup java -jar app.jar >output 2>&1 &
cd.jenkinsfile
// 使用共享库 @Library("hwf-jenkins@main") _ // 导入类方法 def gitlab = new hwf.devops.Gitlab() //def mytools = new org.devops.mytools() //def deploy = new org.devops.deploy() appName = "${JOB_NAME}".split('/')[-1].split('_')[0] // Day5/acmp-myapp-service server_dir = "/data/${appName}" env.userEmail = "30772818@qq.com" currentBuild.description ="Trigger by admin \n version: ${env.releaseVersion}" pipeline { agent { label "build" } options{ skipDefaultCheckout true } stages{ // 生成版本文件 stage("PullArtifacts"){ steps { script { //下载版本库文件 devops02-env/release.yaml response = gitlab.GetRepoFile(17,"${appName}%2frelease-${env.releaseVersion}.yaml", "main") //println(response) //替换文件中内容 yamlData = readYaml text: """${response}""" println(yamlData.artifact.toString()) artifactUrl = yamlData.artifact.toString() withCredentials([usernamePassword(credentialsId: '6ac312c6-9282-42ec-89a3-680356304ea2', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) { sh """ wget --http-user=${USER} \ --http-passwd=${TOKEN} \ ${artifactUrl} -q ls -l """ } } } } // 发布 stage("DeployHosts"){ steps{ script{ //下载服务脚本 response = gitlab.GetRepoFile(17,"service.sh", "main") println(response) writeFile file: 'service.sh', text: "${response}" sh "ls -a " //将主机写入清单文件 sh "rm -rf hosts" for (host in "${env.deployHosts}".split(',')){ sh " echo ${host} ansible_ssh_user=root ansible_ssh_pass=123456 >> hosts" } sh "cat hosts" //ansible 发布 if ( projectType == "service" ){ sh """ # 主机连通性测试 ansible "${deployHosts}" -m ping -i hosts # 清理和创建发布目录 ansible "${deployHosts}" -i hosts -m shell -a "rm -rf ${server_dir}/* && mkdir -p ${server_dir} || echo file is exists" # 复制app ansible "${deployHosts}" -i hosts -m copy -a "src=${appName}-${releaseVersion}.jar dest=${server_dir}/${appName}-${releaseVersion}.jar" ansible "${deployHosts}" -i hosts -m copy -a "src=service.sh dest=${server_dir}/service.sh" # 启动服务 ansible "${deployHosts}" -i hosts -m shell -a "cd ${server_dir};source /etc/profile && sh service.sh ${appName} ${releaseVersion} ${env.port} start" -u root # 检查服务 sleep 10 ansible "${deployHosts}" -i hosts -m shell -a "cd ${server_dir};source /etc/profile && sh service.sh ${appName} ${releaseVersion} ${env.port} check" -u root """ } if ( projectType == "ui" ){ } } } } } post { always{ script { cleanWs() } } failure{ script{ sh "ls" } } } }
service.sh
#!/bin/bash # sh service.sh anyops-devops-service 1.1.1 8091 start APPNAME=$1 VERSION=$2 PORT=$3 start(){ port_result=`netstat -anlpt | grep "${PORT}" || echo false` if [[ $port_result == "false" ]];then nohup java -jar -Dserver.port=${PORT} ${APPNAME}-${VERSION}.jar >${APPNAME}.log.txt 2>&1 & else stop sleep 5 nohup java -jar -Dserver.port=${PORT} ${APPNAME}-${VERSION}.jar >${APPNAME}.log.txt 2>&1 & fi } stop(){ pid=`netstat -anlpt | grep "${PORT}" | awk '{print $NF}' | awk -F '/' '{print $1}'` kill -15 $pid } check(){ proc_result=`ps aux | grep java | grep "${APPNAME}" | grep -v grep || echo false` port_result=`netstat -anlpt | grep "${PORT}" || echo false` url_result=`curl -s http://localhost:${PORT} || echo false ` if [[ $proc_result == "false" || $port_result == "false" || $url_result == "false" ]];then echo "error" else echo "ok" fi } case $4 in start) start sleep 5 check ;; stop) stop sleep 5 check ;; restart) stop sleep 5 start sleep 5 check ;; check) check ;; *) echo "sh service.sh {start|stop|restart|check}" ;; esac
应用发布与回滚策略
蓝绿发布
环境存在两个版本,蓝版本和绿版本同时存在,部署新版本然后进行测试,将流量切到新版本,最终实际运行的只有一个版本(蓝/绿)。好处是无需停机,并且发布风险较小。
nginx upstream模块实现:
upstream webservers { server 192.168.1.253:8099 weight=100; server 192.168.1.252:8099 down; } server { listen 8017; location / { proxy_pass http://webservers; } } nginx -s reload
灰度发布
将发行版发布到一部分用户或服务器的一种模式。这个想法是首先将更改部署到一小部分服务器,进行测试,然后将更改推广到其余服务器。一旦通过所有运行状况检查,当没有问题时,所有的客户将被路由到该应用程序的新版本,而旧版本将被删除。
nginx 权重模拟:
upstream webservers { server 192.168.1.223:8099 weight=100; server 192.168.1.222:8099 weight=100; server 192.168.1.221:8099 weight=100; } server { listen 8017; location / { proxy_pass http://webservers; } } nginx -s reload
版本回滚
- 版本一直升级,则无需回滚。
- 选择旧版本文件,进行发布。
扩展ActiveChoice参数实践
在使用Pipeline项目时 一般都是参数化构建工作,在Jenkins的构建需要使用参数类型有复选框,单选按钮,多选值等输入的情景。
下载安装插件
转到→管理Jenkins→选择管理插件→选择可用选项卡,然后搜索主动选择插件。安装并重新启动Jenkins,以正确安装插件。我的已经安装好,因此在“已安装”标签中列出。
single select单一选项
主动选择反应参数
当作业中UI控件的值发生更改时,可以动态更新(主动选择和响应参考参数) 这里可以使用IF进行条件判断,输出相关的值。
定义发布主机
if (envType.equals("dev (开发)")){ if (projectTyp.equals("service")){ return ["192.168.1.200","192.168.1.201","192.168.1.202"] } if (projectTyp.equals("ui")){ return ["192.168.10.100","192.168.10.101","192.168.10.102"] } } if (envType.equals("uat (测试)")){ if (projectTyp.equals("service")){ return ["192.168.55.31","192.168.55.32"] } if (projectTyp.equals("ui")){ return ["192.168.55.33","192.168.55.34"] } } if (envType.equals("stag (预生产)")){ if (projectTyp.equals("service")){ return ["192.168.1.200","192.168.1.201","192.168.1.202"] } if (projectTyp.equals("ui")){ return ["192.168.10.100","192.168.10.101","192.168.10.102"] } } if (envType.equals("prod (生产)")){ if (projectTyp.equals("service")){ return ["192.168.1.200","192.168.1.201","192.168.1.202"] } if (projectTyp.equals("ui")){ return ["172.16.10.100","172.16.10.101","172.16.10.102"] } }
选择关联的参数,多个参数用逗号分割
继续阅读

我的微信
这是我的微信扫一扫
评论