Jenkins持续集成-自动化部署脚本的实现《python》

读者须知:
1、本手记本着记续接前面的两张手记内容整理
2、本手记针对tomcat部署测试环境实现

最近工作比较繁忙,导致这章一直拖延,没有太抽出时间来总结。要实现Jenkins端的持续集成,其实在CI服务配置端很容易,难点呢?就是如何实现自动化的部署。我的脚本设计就是为了解决以下难题:

难点一、如何使得自动化部署脚本更通用

我用的脚本,依赖依赖一个配置文件的模块化,让每一个应用业务模块更加通用。自动化所执行的命令呢?
我也是设计想法本着更加通用平台的原则,至少对于tomcat+java or java+socket这种模式通用。

难点二、如何使得自动化的部署简单有效

本脚本,更加切合实际,例:自动化部署关闭tomcat,我们常常会选择catalina.sh stop去关闭,然而这里我选择了kill的方式,如果检测中没有顺利关闭,我将调用kill -9 去直接关闭。(没办法,选择了通用,你是没遇到过tomcat 一直有线程卡住,关闭不了的情况吧。)
难点三、需要让我们自动化的部署实现高的可靠性
体现在:
1、每一次的部署,配置选项中都会进行备份。(备份只一次)
2、服务自动备份完毕后,需要实现检测(这里我在配置模块中有加入日志终端输出)

当然,这个脚本中还有未完成的地方:
1、服务启动后,自动化的检测机制还是太薄弱。
2、暂时此脚本还无法通用到php,python等环境的更多平台
3、代码备份方式上,应该更加具更多灵活性。
这里,如果你觉得我的脚本可以补充,不如大家一起加入进来(留言、或者邮件我[email protected]),我也很想学习学习大家的想法。

一、自动化部署原理图示
1、2、3、4 表示执行的4个部署基础步骤
图片描述
二、实现

1、Tomcat 进程设置唯一标记

用于识别出一个服务器中唯一的Tomcat进程
java -Dmyapp.name=“project_name”
如果用的tomcat我们可以,直接修改启动控制文件catalina.sh。
JAVA_OPTS="-Dmyapp.name:"project_name" -server -Xms1024M -Xmx4096M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=1024M"

2、实现自动化登录

一般有两种方式:
方式一、模拟用户密码交互方式,大家可以学习家py中依赖pexcept模块。
方式二、用ssh + Key方式,这个是ssh的一种公钥认证机制。本脚本中用的这种,大家自行学习。

3、CI服务器需要在服务端配置rsync服务端
实现中,主要用于客户端服务拖取代码。

4、配置文件解释
[imoocc.com-server] //服务的模块名称,这里需要注意,需要具有唯一性,且服务的进程标示命名一致
CI_IP=ci.iaskjob.com //CI服务器地址
Login_ISA_Key=/back/key/jeson_iaskjob_rsa //登录ISA的key
Project_IP=192.168.10.99 //工程IP
Project_Login_User=root //对应工程机器登录用户
Project_Login_Port=22 //对应工程机器登录端口
Project_Code_File=/tmp/imoocc //对应工程在CI服务器构建后的执行代码目录
Project_Exclude_File="/var/cache","/var/tmp","jdbc.profile" //不需要向线上同步的文件,如配置文件等等
Project_Backup_Dir=/opt/Jenkins_Backup_Dir //工程备份目录
Project_Deploy_Path=/opt/imoocc //工程部署目录
Project_Start_Command=tomcat/bin/catalina.sh start //工程启动方式
Project_Log_Path=/tmp/imoocc.log //启动后日志的查看方式

分享代码如下:

# -*- coding: utf-8 -*-
#!/usr/bin/python
#########################################################################
# File Name: Jenkins_Project_Deploy.py
# Program function: ueed for deployment code in CI server.
# Author:Jeson
# mail:[email protected]
# Created Time: 一  6/20 19:24:33 2016
#========================================================================
import ConfigParser
import sys
from sys import argv
import paramiko

def Gennerate_cmd(Project_Name,CI_IP,Project_Code_File,Project_Exclude_File,Project_Backup_Dir,Project_Deploy_Path,Project_Start_Command,Project_Log_Path):
    cmd = []
    #生成备份命令
    if Project_Backup_Dir:
        #生成备份原有文件
        cmd.append("mkdir -p /opt/")
        cmd.append("rsync -avzP %s %s && touch /tmp/CI_%s_backuptrue"%(Project_Deploy_Path,Project_Backup_Dir,Project_Name))
    #生成关闭原有进程命令
    cmd.append(‘test -e /tmp/CI_%s_backuptrue && ps -auxgrep "name:%s"grep -v grepawk \‘{print $2}\‘xargs kill‘%(Project_Name,Project_Name))
    #生成命令-确认原来服务已经顺利关闭
    cmd.append(‘ps -auxgrep "name:%s"grep -v grepawk \‘{print $2}\‘&& touch /tmp/CI_killSucc  ps -auxgrep "name:%s"grep -v grepawk \‘{print $2}\‘xargs kill -9‘%(Project_Name,Project_Name))
    #生成命令-用于同步新的代码文件
    if Project_Code_File == "":
        cmd.append(‘test -e "/tmp/CI_%s_killSucc" && rsync -avzP --delete-after --exclude "{%s}" %s::%s %s‘%(Project_Name,Project_Exclude_File,CI_IP,Project_Name,Project_Deploy_Path))
    else:
        cmd.append(‘test -e "/tmp/CI_%s_killSucc" && rsync -avzP --delete-after --exclude "{%s}" %s::%s/%s %s‘%(Project_Name,Project_Exclude_File,CI_IP,Project_Name,Project_Code_File,Project_Deploy_Path))
    #生成命令-用于启动服务
    cmd.append(Project_Start_Command)
    #生成命令-查看服务启动后的日志
    cmd.append(‘tail -n 200 -f %s‘%Project_Log_Path)
    #生成命令-清理此次生成的临时文件
    # cmd.append(‘rm -f /tmp/\*%s\*‘%Project_Name)
    return cmd

def Login_Execute_Command(Project_IP,Project_Login_Port,Project_Login_User,Login_ISA_Key,cmds):
    Project_Port = int(Project_Login_Port) if Project_Login_Port else 22
    if Project_IP and Project_Login_User and Login_ISA_Key:
        key = paramiko.RSAKey.from_private_key_file(Login_ISA_Key)
        s = paramiko.SSHClient()
        s.load_system_host_keys()
        s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        s.connect(hostname=Project_IP,port=Project_Port,username=Project_Login_User,pkey=key)
        for cmd_item in cmds:
            stdin,stdout,stderr=s.exec_command(cmd_item)
            print stdout.read()
        return True
    else:
        return false

def main():
    if len(argv) > 2:
        Config_File = argv[1] if argv[1] else "./Jenkins_Project_Deploy.conf "
        Project_Name = argv[2] if argv[2] else ""
    else:
        print "Error 0:Input argv format error! ./Jenkins_Project_Deploy.py ./test.conf testname"
        sys.exit()
    try:
        cf = ConfigParser.ConfigParser()
        cf.read(Config_File)
        CI_IP = cf.get(Project_Name, "CI_IP")
        Project_Code_File = cf.get(Project_Name, "Project_Code_File")
        Project_Exclude_File = cf.get(Project_Name, "Project_Exclude_File")
        Project_Backup_Dir = cf.get(Project_Name, "Project_Backup_Dir")
        Project_Deploy_Path = cf.get(Project_Name, "Project_Deploy_Path")
        Project_Start_Command = cf.get(Project_Name, "Project_Start_Command")
        Project_Log_Path = cf.get(Project_Name, "Project_Log_Path")

        execute_command = Gennerate_cmd(Project_Name,CI_IP,Project_Code_File,Project_Exclude_File,Project_Backup_Dir,Project_Deploy_Path,Project_Start_Command,Project_Log_Path)
        print "{Step 1: Command collected over!}",execute_command
        Project_IP = cf.get(Project_Name, "Project_IP")
        Project_Login_Port = cf.get(Project_Name, "Project_Login_Port")
        Project_Login_User = cf.get(Project_Name, "Project_Login_User")
        Login_ISA_Key = cf.get(Project_Name, "Login_ISA_Key")
    except Exception as e:
        print "Error 1: %s file open or read error!"%Config_File
        sys.exit()
    print "{Step 2:Prepare to loging...}",Project_IP
    result = Login_Execute_Command(Project_IP,Project_Login_Port,Project_Login_User,Login_ISA_Key,cmds=execute_command)
    if result is False:
        print "Error 3:Execute command failed!"
if __name__ == ‘__main__‘:
    main()

慕课网

前端入门
Java入门

手记 \ Jenkins持续集成-自动化部署脚本的实现

Jenkins持续集成-自动化部署脚本的实现
原创

2016-08-28 23:47:54
12643浏览
1评论

分享到

小字号

幕客技术

Python工程师

关注公众号"幕客技术"

35篇手记
4推荐

作者的热门手记

  • Jenkins-持续集成平台(安装篇)

    15969浏览
    60推荐
    1评论

  • 云时代!我们该如何成为一个优秀的运维工程师

    4432浏览
    52推荐
    4评论

  • 日志大了,怎么办?用我的日志切割脚本吧!

    10008浏览
    51推荐
    3评论

  • 用Jenkins构建一个新工程,我们一起试一下!

    11317浏览
    36推荐
    3评论

  • 从小站到大站的部署架构总结

    2347浏览
    27推荐
    0评论

读者须知:

1、本手记本着记续接前面的两张手记内容整理

2、本手记针对tomcat部署测试环境实现

最近工作比较繁忙,导致这章一直拖延,没有太抽出时间来总结。要实现Jenkins端的持续集成,其实在CI服务配置端很容易,难点呢?就是如何实现自动化的部署。我的脚本设计就是为了解决以下难题:

难点一、如何使得自动化部署脚本更通用

我用的脚本,依赖依赖一个配置文件的模块化,让每一个应用业务模块更加通用。自动化所执行的命令呢?

我也是设计想法本着更加通用平台的原则,至少对于tomcat+java or java+socket这种模式通用。

难点二、如何使得自动化的部署简单有效

本脚本,更加切合实际,例:自动化部署关闭tomcat,我们常常会选择catalina.sh
stop去关闭,然而这里我选择了kill的方式,如果检测中没有顺利关闭,我将调用kill -9
去直接关闭。(没办法,选择了通用,你是没遇到过tomcat 一直有线程卡住,关闭不了的情况吧。)

难点三、需要让我们自动化的部署实现高的可靠性

体现在:

1、每一次的部署,配置选项中都会进行备份。(备份只一次)

2、服务自动备份完毕后,需要实现检测(这里我在配置模块中有加入日志终端输出)

当然,这个脚本中还有未完成的地方:

1、服务启动后,自动化的检测机制还是太薄弱。

2、暂时此脚本还无法通用到php,python等环境的更多平台

3、代码备份方式上,应该更加具更多灵活性。

这里,如果你觉得我的脚本可以补充,不如大家一起加入进来(留言、或者邮件我[email protected]),我也很想学习学习大家的想法。



一、自动化部署原理图示

1、2、3、4 表示执行的4个部署基础步骤

二、实现

  • 1、Tomcat 进程设置唯一标记

用于识别出一个服务器中唯一的Tomcat进程

java -Dmyapp.name=“project_name”

如果用的tomcat我们可以,直接修改启动控制文件catalina.sh。

JAVA_OPTS="-Dmyapp.name:"project_name" -server -Xms1024M -Xmx4096M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=1024M"

  • 2、实现自动化登录

一般有两种方式:

方式一、模拟用户密码交互方式,大家可以学习家py中依赖pexcept模块。

方式二、用ssh + Key方式,这个是ssh的一种公钥认证机制。本脚本中用的这种,大家自行学习。

3、CI服务器需要在服务端配置rsync服务端

实现中,主要用于客户端服务拖取代码。

4、配置文件解释

[imoocc.com-server] //服务的模块名称,这里需要注意,需要具有唯一性,且服务的进程标示命名一致

CI_IP=ci.iaskjob.com //CI服务器地址

Login_ISA_Key=/back/key/jeson_iaskjob_rsa //登录ISA的key

Project_IP=192.168.10.99 //工程IP

Project_Login_User=root //对应工程机器登录用户

Project_Login_Port=22 //对应工程机器登录端口

Project_Code_File=/tmp/imoocc //对应工程在CI服务器构建后的执行代码目录

Project_Exclude_File="/var/cache","/var/tmp","jdbc.profile" //不需要向线上同步的文件,如配置文件等等

Project_Backup_Dir=/opt/Jenkins_Backup_Dir //工程备份目录

Project_Deploy_Path=/opt/imoocc //工程部署目录

Project_Start_Command=tomcat/bin/catalina.sh start //工程启动方式

Project_Log_Path=/tmp/imoocc.log //启动后日志的查看方式



分享代码如下:

# -*- coding: utf-8 -*-#!/usr/bin/python########################################################################## File Name: Jenkins_Project_Deploy.py# Program function: ueed for deployment code in CI server.# Author:Jeson# mail:[email protected]# Created Time: 一  6/20 19:24:33 2016#========================================================================importConfigParserimport sys
from sys import argv
import paramiko

defGennerate_cmd(Project_Name,CI_IP,Project_Code_File,Project_Exclude_File,Project_Backup_Dir,Project_Deploy_Path,Project_Start_Command,Project_Log_Path):
    cmd =[]#生成备份命令ifProject_Backup_Dir:#生成备份原有文件
        cmd.append("mkdir -p /opt/")
        cmd.append("rsync -avzP %s %s && touch /tmp/CI_%s_backuptrue"%(Project_Deploy_Path,Project_Backup_Dir,Project_Name))#生成关闭原有进程命令
    cmd.append(‘test -e /tmp/CI_%s_backuptrue && ps -auxgrep "name:%s"grep -v grepawk \‘{print $2}\‘xargs kill‘%(Project_Name,Project_Name))#生成命令-确认原来服务已经顺利关闭
    cmd.append(‘ps -auxgrep "name:%s"grep -v grepawk \‘{print $2}\‘&& touch /tmp/CI_killSucc  ps -auxgrep "name:%s"grep -v grepawk \‘{print $2}\‘xargs kill -9‘%(Project_Name,Project_Name))#生成命令-用于同步新的代码文件ifProject_Code_File=="":
        cmd.append(‘test -e "/tmp/CI_%s_killSucc" && rsync -avzP --delete-after --exclude "{%s}" %s::%s %s‘%(Project_Name,Project_Exclude_File,CI_IP,Project_Name,Project_Deploy_Path))else:
        cmd.append(‘test -e "/tmp/CI_%s_killSucc" && rsync -avzP --delete-after --exclude "{%s}" %s::%s/%s %s‘%(Project_Name,Project_Exclude_File,CI_IP,Project_Name,Project_Code_File,Project_Deploy_Path))#生成命令-用于启动服务
    cmd.append(Project_Start_Command)#生成命令-查看服务启动后的日志
    cmd.append(‘tail -n 200 -f %s‘%Project_Log_Path)#生成命令-清理此次生成的临时文件# cmd.append(‘rm -f /tmp/\*%s\*‘%Project_Name)return cmd

defLogin_Execute_Command(Project_IP,Project_Login_Port,Project_Login_User,Login_ISA_Key,cmds):Project_Port=int(Project_Login_Port)ifProject_Login_Portelse22ifProject_IPandProject_Login_UserandLogin_ISA_Key:
        key = paramiko.RSAKey.from_private_key_file(Login_ISA_Key)
        s = paramiko.SSHClient()
        s.load_system_host_keys()
        s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        s.connect(hostname=Project_IP,port=Project_Port,username=Project_Login_User,pkey=key)for cmd_item in cmds:
            stdin,stdout,stderr=s.exec_command(cmd_item)print stdout.read()returnTrueelse:returnfalsedef main():if len(argv)>2:Config_File= argv[1]if argv[1]else"./Jenkins_Project_Deploy.conf "Project_Name= argv[2]if argv[2]else""else:print"Error 0:Input argv format error! ./Jenkins_Project_Deploy.py ./test.conf testname"
        sys.exit()try:
        cf =ConfigParser.ConfigParser()
        cf.read(Config_File)
        CI_IP = cf.get(Project_Name,"CI_IP")Project_Code_File= cf.get(Project_Name,"Project_Code_File")Project_Exclude_File= cf.get(Project_Name,"Project_Exclude_File")Project_Backup_Dir= cf.get(Project_Name,"Project_Backup_Dir")Project_Deploy_Path= cf.get(Project_Name,"Project_Deploy_Path")Project_Start_Command= cf.get(Project_Name,"Project_Start_Command")Project_Log_Path= cf.get(Project_Name,"Project_Log_Path")

        execute_command =Gennerate_cmd(Project_Name,CI_IP,Project_Code_File,Project_Exclude_File,Project_Backup_Dir,Project_Deploy_Path,Project_Start_Command,Project_Log_Path)print"{Step 1: Command collected over!}",execute_command
        Project_IP= cf.get(Project_Name,"Project_IP")Project_Login_Port= cf.get(Project_Name,"Project_Login_Port")Project_Login_User= cf.get(Project_Name,"Project_Login_User")Login_ISA_Key= cf.get(Project_Name,"Login_ISA_Key")exceptExceptionas e:print"Error 1: %s file open or read error!"%Config_File
        sys.exit()print"{Step 2:Prepare to loging...}",Project_IP
    result =Login_Execute_Command(Project_IP,Project_Login_Port,Project_Login_User,Login_ISA_Key,cmds=execute_command)if result isFalse:print"Error 3:Execute command failed!"if __name__ ==‘__main__‘:
    main()

相关标签: JAVA 云计算 测试

本文原创发布于慕课网 ,转载请注明出处,谢谢合作!

26 人推荐

相关阅读

  • 删除数组中的某个(多个)元素(分别用数组和集合的办法删除)

  • Java中Junit4测试实例

  • Spring+SpringMVC+MyBatis+easyUI整合优化篇(三)代码测试

  • Spring+SpringMVC+MyBatis+easyUI整合优化篇(四)单元测试实例

  • Spring+SpringMVC+MyBatis+easyUI整合优化篇(五)MockMvc服务端的单元测试

添加评论

1条评论

weixin_xiaodian_01F

老师为什么不用python的fabric模块自动部署打包

0回复 2017-09-14 23:13:40

Copyright ? 2017 imooc.com All Rights Reserved | 京ICP备 13046642号-2

时间: 2024-10-17 11:43:06

Jenkins持续集成-自动化部署脚本的实现《python》的相关文章

Linux-GitLab+Jenkins持续集成+自动化部署

GitLab+Jenkins持续集成+自动化部署 什么是持续集成? (1)Continuous integration (CI) 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过自动化的构建(包括编译.发布.自动化测试)来验证,从而尽快地发现集成错误.许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件. (2)没有持续集成 项目做模块集成的时候,发现很多接口都不通==>浪费大量时间 需

持续集成+自动化部署[代码流水线管理及Jenkins和gitlab集成]

持续集成+自动化部署[代码流水线管理及Jenkins和gitlab集成] 标签(空格分隔): Jenkins 一.代码流水线管理 Pipeline名词顾名思义就是流水线的意思,因为公司可能会有很多项目.如果使用jenkins构建完成后,开发构建项目需要一项一项点击,比较麻烦.所以出现pipeline名词. 代码质量检查完毕之后,我们需要将代码部署到测试环境上去,进行自动化测试 新建部署代码项目 点击新建 这里只需要写一下描述 执行Shell脚本 温馨提示:执行命令主要涉及的是权限问题,我们要搞明

Jenkins从零开始搭建持续集成+自动化部署详细说明

说明:该说明文档的案例是:在windows上部署Jenkins服务,最终将持续集成的war包自动部署到远程服务器(Centos 7)上. 一.Jenkins安装 1. Jenkins下载地址:https://jenkins.io/download/,如图,我现在的是windows版本的: 2. 下载之后,解压点击msi文件运行,如图: 3. 我已经安装过一次了,这儿就不详细描述,安装教程请参考百度经验:https://jingyan.baidu.com/article/cbcede077f62b

Jenkins持续集成与部署

1.1 开发写代码的演变 好景不长,开发越来越多,代码文件越来越多,每天下班前合并代码时,发现很多合并失败的文件.最后每天加班3小时人工合并代码. 解决方法:将合并代码的周期缩短,以前一天,现在一小时,半小时... 随时随地地将代码合并,这种方法叫做持续集成. 1.2 持续集成(简称CI) 说明:持续集成说的是频繁地(一天多次)将代码集成到主干. 它的好处主要有两个: 1.快速发现错误.每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易. 2.放置分支大幅偏离主干.如果不是经常集

Jenkins持续集成环境部署

一.下载Jenkins Jenkins下载地址:https://jenkins.io/download/ 这里我们下载的是jenkins.war 二.启动Jenkins 在Linux下启动Jenkins有两种方式,一种是在jenkins.war的存放目录下使用命令java -jar jenkins.war启动,另外一种是把jenkins.war放在tomcat的webapps目录下,然后启动tomcat就可以了,如下图: 三.安装Jenkins 在浏览器中输入http://192.168.182

docker搭建gitlab+Jenkins持续集成环境

安装docker 此处省略一.使用docker安装gitlab docker pull gitlab/gitlab-ce:latest下载完成之后使用docker生成容器docker run -dit \-p 8443:443 \-p 8080:80 \-p 2222:22 \-p 9090:9090 \--name gitlab \--restart always \-v /home/gitlab/config:/etc/gitlab \-v /home/gitlab/logs:/var/lo

Jenkins持续集成。

Jenkins持续集成 自动化运维 Jenkins所有包下载 链接:https://pan.baidu.com/s/1SXg-Av99xeyR3OdvJhv7Dg 提取码:dara Jenkins环境搭建 由于Jenkins是依赖于java的,所以先介绍java环境的搭建 (1)使用官方的二进制包解压安装(上方有下载链接) 官方二进制包的下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133

jenkins持续集成工作原理、功能、部署方式等介绍

超详细的jenkins持续集成工作原理.功能.部署方式等介绍 原创 波波说运维 2019-08-29 00:01:00 概述 今天简单整理了一下jenkins的一些概念性内容,归纳如下: 1.概念 jenkins是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上.同时 Jenkins 能实时监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性. Jenkins可以构建一个自动化的持续集成

git jenkins 基本部署 jenkins持续集成

1.什么是持续集成?  持续集成来简化我们的工作 还能让产品可以快速迭代,同时还能保持代码高质量产出.2.Jenkins的安装配置:        [[email protected] ~]# yum install java -y        [[email protected] ~]# yum localinstall jenkins-2.176.1-1.1.noarch.rpm -y        [[email protected] ~]# systemctl start jenkin