以重庆的用户管理项目为例
由于使用虚机部署,跟结合k8s和docker有一些区别,且此部署是针对私有化部署,例如本例中的重庆项目,外面是无法访问到服务器的,像这种场景的部署,需要具备以下条件:
- 提供一台局域网内的代理机,能通过公网IP进行SSH方式连接
- 该代理机需能免密或者使用同一密码进行连接到各业务服务器
- 该代理机连接各业务服务器时使用的SSH端口保持一致
当然,后面两点不是必须的!但要知道每台机器的密码和SSH端口,否则无法实现部署
Jenkins配置
由于我已经实现准备好了针对虚机的Jenkins配置,所以只需要改下配置即可,以user-manage为例:
1)点击配置
2)修改用于回滚时的前缀名
这里的前缀就是每一个任务名的前缀,例如:chongqing-user-manage,shanxi-user-manage
3)修改pipeline脚本
代码语言:javascript复制node {
def ip_addr = "47.95.131.241" //代理机的IP地址
def ip_port = "2222" //代理机的SSH端口
def bk_script = "/data/jenkins/workspace/scripts/backupjar.sh" //用于本地备份jar包的脚本
def git_address = "git@codehub.devcloud.huaweicloud.com:yhgl_liuxin00001/cloud-userAPI.git" //代码仓库地址
def git_auth = "d5941eda-4cd0-4dfd-9d37-13dbad31e766" //用于拉取代码时进行认证
def apps_name = "user-manager" //服务名称,supervisor启动时会启动此名称
def dst_dir = "/usr/local/user-manager" //存放jar包的路径
def dst_user = "root" //默认都是root用户启动的程序
if (env.Action == "Deploy") {
stage('代码拉取') {
deleteDir() //构建前先清空目录
checkout([$class: 'GitSCM', branches: [[name: '${Branch}']], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]]) //拉取代码
script {
git_cm_id = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim() //获取commit id
date_time = sh(script: "date %Y%m%d%H%M", returnStdout: true).trim() //获取当前时间
pom = readMavenPom file: 'pom.xml' //读取pom.xml文件
project_version = "${pom.version}"
pkg_name = "${pom.artifactId}-${pom.version}"
project_name = "${pom.artifactId}"
jar_name = "${pkg_name}-${date_time}-${git_cm_id}.jar"
pkg_dirs = "target" //有的项目在打包后,生成的jar包在父目录的target下,有的是在其他路径下,指定此变量可以获取到jar包
//start_cmd_java = "'/usr/local/jdk1.8.0_191/bin/java -jar ${pkg_name}-${date_time}-${git_cm_id}.jar --spring.cloud.nacos.config.server-addr=${nacos_url} --spring.cloud.nacos.config.namespace=${nacos_namespace} --spring.cloud.nacos.config.group=${nacos_group} --spring.profiles.active=${EnvName}'"
}
}
stage('代码构建及分析') {
sh "mvn clean package -Dmaven.test.skip=true" //maven打包
}
stage('清理旧文件') {
sh "ssh root@${ip_addr} -p ${ip_port} 'mkdir -p /ansible-deploy/pkg/${apps_name}'" //远程执行创建存放jar包的目录,不同的项目放在不同目录下,以项目名区分
sh "ssh root@${ip_addr} -p ${ip_port} 'rm -rf /ansible-deploy/pkg/${apps_name}/${pkg_name}-*.jar'" //删除远程目录下的所有jar包,不删除也可,因为jar包加了时间戳,所以不会重复,但不删会导致磁盘空间愈发的大
sh "ssh root@${ip_addr} -p ${ip_port} 'rm -rf /ansible-deploy/roles/deploy-server/files/${pkg_name}-*.jar'" //删除ansible-playbook中files目录下的所有jar包,原因同上
}
stage('传包至电视台') {
sh "scp -P ${ip_port} -r target/${pkg_name}.jar root@${ip_addr}:/ansible-deploy/pkg/${apps_name}/${jar_name}" //将本地打好的jar包发送到远程代理机上,并加上时间戳和commit id和版本
}
stage('代码发布') {
sh """
ssh root@${ip_addr} -p ${ip_port} "bash /ansible-deploy/main.sh --action_name=Deploy --app_name=${apps_name} --jar_file=${jar_name} --deploy_dir=${dst_dir} --cur_user=${dst_user} --group_name=${ClusterName}" //执行此脚本实际上就是执行的ansible-playbook,作用就是将jar包发送到目标服务器上,并使用supervisor启动,然后清理旧的jar包
"""
}
stage('备份文件') {
sh "bash ${bk_script} --jar_file=${pkg_name} --commit_id=${git_cm_id} --date_time=${date_time} --pkg_dir=${pkg_dirs}" //备份此次打包好的jar包,放在这个位置执行,是为了当前面整个构建操作完成后再去备份jar包,否则就会每构建一次就备份一次,不管成功与否
}
}
if (env.Action == "RollBack") {
sh """
ssh root@${ip_addr} -p ${ip_port} "bash /ansible-deploy/main.sh --action_name=RollBack --app_name=${apps_name} --jar_file=${RollbackName} --deploy_dir=${dst_dir} --cur_user=${dst_user} --group_name=${ClusterName}" //用于回滚,唯一不同的地方在于jar_file这个参数的值变成了${RollbackName}
"""
}
}
ansible-playbook参考
ansible-playbook的目录结构
playbook示例下载: [点击下载][1]
playbook中提供了两种方式启动,一种是supervisor,另一种是通过执行shell脚本方式,最好是通过supervisor方式启动,这样更加规范,更加稳定和安全。
另外,supervisor如果已经安装好的,且通过yum安装的方式,最好卸载掉(这里ansible会自动卸载),因为版本非常低,比较容易出错。
Jenkins构建
修改完jenkins的pipeline,和ansible-playbook之后,就可以进行构建了,方法如下:
选择要构建的服务,例如:user-api,还是以重庆项目为例
1)右上角搜索user-api,点击进入
2)选择 Build with Parameters
3)选择分支进行构建
4)查看部署日志
5)最后输出SUCCESS表示成功
6)回滚操作
7)选择RollBack之后,就会列出前几次的jar包,选择指定日期的jar包即可
选择完成后,点击构建,查看日志,出现SUCCESS表示回滚成功