陈奇网络工作室

给它一个钓鱼-操作和维护平台发布模块1(詹金斯)

网站建设服务器

基于步子迈得太大容易扯蛋的原则,平台设计的初衷是能够调用开源产品,绝对不能自己做,这样平台只能作为一个综合调度中心,而不考虑背后具体的功能实现逻辑。

詹金斯的使用可以追溯到我很久以前认识的一家公司。当时,技术总监张晓风向我介绍了持续集成引擎Hudson,也就是后来的Jenkins。以前詹金斯联合Maven,蚂蚁蚂蚁做敏捷开发,我只是用一些最基本的功能实现系统发布和更新。

传统操作和维护版本

SVN移民代码-本地键入的tar包(rar包)-sftp上传到服务器。

Jenkins建立了发布项目——SVN迁移代码——并通过SFTP插件将其直接分发到服务器。

优点:粗糙简单

缺点:

效率:分发方式——单台服务器在线,多台服务器分发效率下降。如果网络是统一门户登录(也就是堡垒机器是单一门户的时候),发布工作会变得异常困难。

安全风险:第二种发布方法的SSH帐户密码必须存储在Jenkins中,虽然不是明文,但是.还面临着这个服务器的22个端口要对詹金斯开放,安全性是个问题。

采用系统方案:YUM

我当时的想法:公司是三流公司。我在制定内网规则的时候,强烈建议一定要限制SSH登录范围,统一入口可以大大降低被* * * *的可能性,于是想到用YUM来更新:

发布:将代码移出SVN后,将其放入RPM包中(强烈推荐FPM)。

更新:利用YUM的特性,更新后的包每次都保持版本号1,比如test-519-1.x86_64(519是Jenkins的发布版本号),服务器每次只需要执行下面两条命令。

尝试

百胜清洗所有

yum安装测试

批量操作:通过Saltstack通知每个服务器做Yum动作。

后退:更简单。如果没礼貌的话,直接用mv Test-518-1 . x86 _ 64 Test-520-1 . x86 _ 64直接上YUM服务器就可以了。如果你比较温柔,当然要回调Jenkins的接口,用TAG回滚。

特定逻辑和实现

那么我们来解决播放RPM包和更新YUM源码的问题(我的Jenkins就是我们内网的YUM源码):

配置Jenkins

首先我们需要在Jenkins中打开批量任务(batch,其实是脚本),不会用Jenkins自己的百度。

单击添加后期生成操作-选择调用批处理任务。

在批处理任务中填写脚本。

尝试

mkdir-p/home/release/$ JOB _ NAME \ \ \ \

fpm-sdir-trpm-n $ JOB _ NAME-v $ BUILD _ NUMBER-prefix/home/www/BBS-C/var/lib/Jenkins/workspace/$ JOB _ NAME-p/home/release/$ JOB _ NAME。/\\\\

create repo-update/home/release/$ JOB _ NAME/\ \ \

curl-djob _ id=$ JOB _ name http://salt masterip/CMDB/salt _ Jenkins _ post/

这个詹金斯脚本的大致意思是:

创建/home/release/$JOB_NAME目录。

然后将/var/lib/Jenkins/workspace/$JOB_NAME(Jenkins项目工作空间)的代码键入到一个名为$ JOB _ NAME的RPM包中,该包存储在目录/home/release/$JOB_NAME中,并将解压到目录/home/www/bbs中。

然后create repo-update/home/release/$ job _ name/通知您更新YUM源代码。

最后回调我的Salt接口(这个接口的作用其实就是检查这个项目对应了哪些发布主机,然后在这些主机上执行yum install命令,是不是很没脑子~)

Saltstack接口(saltjenkinspost)

因为我的平台和Salt master是一样的(主要是为了省事),所以不需要调用API,直接调用本地Saltstack已经封装好的一些命令比如yum install。

Upgradeavailable验证yum源是否已更新。

安装安装

Modrepo创建yum源。

Getrepo验证yum源是否存在。

Intro执行一些更新的命令。

我在接口处理的每一步后都会验证返回的主机是否跟数据库预设的项目主机一样,只有一样了才会进行下一步(比如接口只返回了一台服务器通过盐执行的结果,而数据库里该项目是两台服务器,我会认为这个发布有问题,而进行中断)这样也是为了避免有的主机更新成功了,有的主机没更新成功,导致线上用户体验不好(目前已经成功从深信服公司要到了负载均衡的API)后面要做的就是采用灰度发布,从负载上摘除一个然后就更新一个,更新完毕再加回负载。

importjson

来自姜戈。httpimporthttpresponse

来自姜戈。观点。装修工。csrfimportcsrf _ exempt

尝试:

importsalt.client

除了:

及格

fromcmdb.modelsimport*

classSalt_jenkins:

def__init__(self,host_list,job):

自我。客户=盐。客户。本地客户端()

self.host _ list=主机列表

self.type=type

自我工作=工作

defupgradeavailable(self):

检测目标主机组项目在妙的上是否有新版本更新,返回可以更新的主机

ret=self。客户。cmd(\ \ \ ' % s \ \ \ ' % self。host _ list,\'pkg.upgrade_available\\\ '[\\\'%s\\\'%self.job],expr_form=\\\'list\\\ 'ret=\ \ \ ' ret=\ \ ' return _ Redis \ \ \ ')

true_hostlist=[]

forhostinret.keys():

ifret[\\\'%s\\\'%host]:

true_hostlist.append(主机)

否则:

及格

returntrue_hostlist

定义安装(自己):

妙的安装项目每分钟转数包

ret=self。客户。cmd(\ \ \ ' % s \ \ \ ' % self。host _ list,\'pkg.install\\\ '[\\\'%s\\\'%self.job],expr_form=\\\'list\\\ 'ret=\\\'return_redis\\\ ')

true_hostlist=[]

forhostinret.keys():

ifret[\\\'%s\\\'%host]!={}:

install _ ret=ret[\ \ \ ' % s \ \ \ ' % host][\ \ \ ' % s \ \ \ ' % self。工作]

ifinstall_ret!=\\\'\\\'

true_hostlist.append(主机)

否则:

及格

否则:

及格

returntrue_hostlist

defmodrepo(self):

创建项目妙的源

ret=self。客户。cmd(\ \ \ ' % s \ \ \ ' % self。host _ list,\'pkg.mod_repo\\\ '[\\\'repo=%s\\\'%self.job,\ ' base URL=http://172。18 .11 .98/release/% s \ \ \ ' % self。job,\'enabled=1\\\ '\\\'gpgcheck=0\\\ '\\\'name=%s\\\'%self.job优先级

true_hostlist=[]

forhostinret.keys():

if type(ret[\ \ \ ' % s \ \ \ ' % host])==dict:

true_hostlist.append(主机)

否则:

及格

returntrue_hostlist

defgetrepo(self):

验证项目妙的源是否存在

ret=self。客户。cmd(\ \ \ ' % s \ \ \ ' % self。host _ list,\'pkg.get_repo\\\ '[\\\'repo=%s\\\'%self.job],expr_form=\\\'list\\\ 'ret=\\\'return_redis\\\ ')

true_hostlist=[]

forhostinret.keys():

ifret[\\\'%s\\\'%host]!={}:

true_hostlist.append(主机)

否则:

及格

returntrue_hostlist

defintro(自我):

执行svn_intro内命令

命令=SVN。对象。get(SVN _ name=self。工作).svn_intro

ret=self。客户。cmd(\ \ \ ' % s \ \ \ ' % self。host _ list,\'cmd.run\\\ '[\\\'%s\\\'%command],expr_form=\\\'list\\\ 'ret=\\\'return_redis\\\ ')

返回浸水使柔软

@csrf_exempt

defsalt_jenkins_post(请求):

ifrequest.method==\\\'POST\\\ '

ip=请求. META.get(远程_ADDR,无)

ifip==\\\'172.18.11.98\\\ '

工作=请求POST.get(\\\'job_id\\\ ')

作业主机=SVN。对象。get(SVN名=作业)。svn _主机

if job==\ \ \ ' CMS _ template。青春。cn \ \ \ '或job==\ \ \ ' CMS _ assets。青春。cn \ \ \ '

及格

否则:

初始化盐_詹金斯

绍特_詹金斯=绍特_詹金斯(作业主机,作业)

目标主机检查妙的源是否存在

如果排序(salt _ Jenkins。get repo())==sorted(str(job _ hosts).拆分(\\\ '\\\ '):

及格

否则:

不存在就创建妙的源

salt_jenkins.modrepo()

目标主机检查妙的源是否更新

如果排序(salt _ Jenkins。upgrade available())==sorted(str(job _ hosts).拆分(\\\ '\\\ '):

如果排序(salt _ Jenkins。install())==sorted(str(job _ hosts).拆分(\\\ '\\\ '):

目标主机执行命令

salt_jenkins.install()

目标主机执行命令

salt_jenkins.intro()

returnHttpResponse(\ \ \ '安装成功\ \ \ ')

否则:

returnHttpResponse(\ \ \ '安装失败\ \ \ ')

否则:

returnHttpResponse(\ \ \ ' upgradeavailablefail \ \ \ ')

否则:

returnHttpResponse(\ \ \ ' IP拒绝\ \ \ ')

否则:

returnHttpResponse(\ \ \ ' getdeny \ \ \ ')

后续会介绍发布的状态返回,也就是盐堆的重大事件及通过詹金斯结合盐堆创新发布项目。

更多关于云服务器,域名注册,虚拟主机的问题,请访问西部数码代理商官网:www.chenqinet.cn

相关推荐

后台-系统设置-扩展变量-手机广告位-内容页底部广告位3