概念
java编写开源软件
作用
CI:持续集成、构建和测试各种项目
CI是目前最流行的应用程序开发实践方式
CI工具可以自动构建和自动测试代码程序,检测问题提供反馈
CD:持续交付
Jenkins可以构建项目(需要编译的c、c++、java、go(这类代码本身无法像python、shell、php直接调用代码就能用,需要经过编译成项目才能使用))
Jenkins可以做交付服务器,把项目给到应用服务器。需要在Jenkins服务器上部署http或者ftp服务
部署安装
环境:java
首先准备java环境,安装JDK
yum -y install java
安装
方法一:
软件包是rpm:官网https://jenkins.io/zh/download/
rpm -ivh jenkins-2.190.1-1.1.noarch.rpm
systemctl start/enable jenkins
方法二:使用Jenkins的war包
直接下载war包jenkins.war,官网https://jenkins.io/download
可以使用命令直接运行war包就启动Jenkins:java -jar jenkins.war
修改默认端口
方法是在命令行后面添加--httpPort=8899这个参数就可以了,其实就是配置jetty的启动端口:
nohup java -jar jenkins.war --httpPort=8899 &
方法三:直接用容器镜像起jenkins
信息
/usr/lib/jenkins/:jenkins安装目录,WAR包会放在这里。
/etc/sysconfig/jenkins:jenkins配置文件,“端口”,“JENKINS_HOME”等都可以在这里配置。
/var/lib/jenkins/:默认的JENKINS_HOME。
/var/log/jenkins/jenkins.log:Jenkins日志文件
配置
直接访问http://x.x.x.x:8080,Jenkins的默认端口是8080
Jenkins访问页面
需要管理员密码:Jenkins自动生成在jenkins的安装路径下\secrets\initialAdminPassword、默认用户admin
|
自定义部署
点击“选择插件安装”,再选“无”后安装
因为Jenkins使用的是国外的安装站点,如果安装默认插件可能会需要很久,等安装结束后可以选择国内的站点
点击“使用admin继续登录”,保存并完成,开始使用
修改管理员密码
页面右上角admin->configure->password->Save保存
安装插件
改为国内镜像站点安装插件
首页---Manage Jenkins系统管理---Manage Plugins插件管理 --- Advanced高级 ---- Update Site升级站点:地址(可以搜索Jenkins插件镜像:比如清华大学的https://mirrors.tuna.tsinghua.edu.cn/jenkins/) --- Submit
如果找到插件显示如图,是因为版本太低的问题
安装需要的插件:支持中文和支持git连接的插件
Available可选插件 -> 搜索框ctrl+f-> 选中Localization: Chinese (Simplified)\和Git Parameter(直接连接git) -> Install without restart -> 勾选Restart Jenkins when installation is complete and no jobs are running安装后重启
一直报错安装插件失败,换了一种方法:官网搜索自己需要的插件,然后上传插件
进入https://plugins.jenkins.io/,搜索自己需要的插件,然后点击查找出来的,在点击右上角archives进入版本页面,最后选择版本下载xxx.hpi
注意:
可能需要重新起jenkins服务才会生效:包括换url或者换安装插件的方式
版本:0.9.11上传jenkins-2.190.3-1.1.noarch.rpm可以成功,但是上传jenkins-2.138.2-1.1.noarch.rpm版本失败
构建项目:CI/CD流程(使用git)
Jenkins服务器从git服务器上拉取代码,并构建成具体的项目
配置Jenkins下载gitlab代码
选择Item或者新建任务 ->任务名:website (自己定义,这个是者构建的项目的标签tag或者分支,是个变量,后面会被调用)/ Freestyle project -> 勾选This project is parameterized(这个项目是参数化的) -> 添加参数 -> Git Parameter(因为是git所以选择这个)=> Name: webver / Parameter Type: Branch or Tag (指开发写的代码是那个版本)/ Default Value: origin/master(分支) -> 源码管理 => Git => Repository URL: http://192.168.4.5/devops/website.git (这个是gitlab的项目路径)/ Branches to build:$webver(这个变量是指要构建的项目变量就是定义的Name) -> 保存
构建:选择哪个tag就构建哪个
Build with Parameters ---选择相关的tag进行构建,构建完成后内容自动生成
在还没有构建的时候在Jenkins下是看不到开发写的项目的,构建好了jenkins服务器上就会自动生成git服务器上的开发代码
到这里实现了jenkins同步gitlab服务器上开发写的代码,等同于git clone的功能
构建失败可以看控制台输出的错误信息,左下角有构建状态:蓝色圆点构建成功,红色圆点构建失败
修改工程
将程序代码下载到子目录中,现在不管是哪个tag构建后都是website
配置 --- 源码管理 --- Additional Behaviours/checkout to a sub-direcotry:website-$webver --- 保存测试
对下载的程序代码进行打包管理,便于web应用服务器获取。在execute shell中配置好脚本代码之后,选择构架jenkins会自动做这些操作并生成结果在jnekins服务器上
execute.shell里面可以写所有的系统及服务的命令,脚本,这里面的命令就是jenkins系统终端运行的
构建后会生成对应的代码tar包、生成版本号文件(代码最新版依据)、Md5值文件
要用ls -R才能看到
上线代码
自动部署上线:在web应用下执行脚本,可以实现自动部署程序应用
部署代码思路
软连接方式:好处可以随时改软链接的指定文件,等于可以随时更新和回滚版本
传统代码部署到目录下比较麻烦和应用不方便
可以直接在execute shell里面写,把代码传给应用服务器,最简单的
| #打包过程cd /var/lib/jenkins/workspace/test && zip -r web.war ./*
| #停止tomcat服务ssh -p2022 root@192.168.33.144 “systemctl stop tomcat”
| #拷贝压缩包到web服务器scp -P2022 web.war 192.168.33.144:/data/tomcat/webapps/testapp
| #代码替换ssh -p2022 root@192.168.33.144 “cd /data/tomcat/webapps/testapp && rm ./index.* && unzip web.war && rm -rf web.war”
| #启动tomcat服务ssh -p2022 root@192.168.33.144 “systemctl start tomcat”
代码python脚本如下:
/var/www/download:保存下载的压缩包、/var/www/deploy:保存live_ver文件和解压目录、/var/www/html/nsd1906:指向发布的应用目录
| import wget
| import os
| import requests
| import hashlib
| import tarfile
|
| def has_new_ver(ver_url, ver_fname):
| '有新版本返回True,否则返回False'
| # 如果本地没有版本文件,则为True
| if not os.path.isfile(ver_fname):
| return True
|
| # 取出本地版本
| with open(ver_fname) as fobj:
| local_ver = fobj.read()
|
| # 本地版本与网上版本比较,如果不一致返回True
| r = requests.get(ver_url)
| if local_ver != r.text:
| return True
| else:
| return False
|
| def file_ok(md5_url, fname):
| '如果文件已损坏返回False,否则返回True'
| # 计算本地文件的md5值
| m = hashlib.md5()
| with open(fname, 'rb') as fobj:
| while 1:
| data = fobj.read(4096)
| if not data:
| break
| m.update(data)
|
| # 取出网上的md5值,进行比较
| r = requests.get(md5_url)
| if m.hexdigest() == r.text.strip():
| return True
| else:
| return False
|
| def deploy(app_fname):
| '部署软件'
| deploy_dir = '/var/www/deploy'
| dest = '/var/www/html/nsd1906'
| # 解压
| tar = tarfile.open(app_fname)
| tar.extractall(path=deploy_dir)
| tar.close()
|
| # 取出软件目录名
| app_dir = app_fname.split('/')[-1]
| app_dir = app_dir.replace('.tar.gz', '')
| app_dir = os.path.join(deploy_dir, app_dir)
|
| # 如果目标链接文件已存在,先删除
| if os.path.exists(dest):
| os.remove(dest)
|
| # 创建软链接
| os.symlink(app_dir, dest)
|
|
| if __name__ == '__main__':
| # 判断是否有新版本,没有则退出
| ver_url = 'http://192.168.4.6/deploy/live_ver'
| ver_fname = '/var/www/deploy/live_ver'
| if not has_new_ver(ver_url, ver_fname):
| print('未发现新版本。')
| exit(1)
|
| # 下载新版本软件
| r = requests.get(ver_url)
| ver = r.text.strip() # 把额外的\n删除,得到版本
| app_url = 'http://192.168.4.6/deploy/pkgs/website-%s.tar.gz' % ver
| down_dir = '/var/www/download'
| wget.download(app_url, down_dir)
|
| # 校验。如果下载的文件已损坏,删除它
| md5_url = app_url + '.md5'
| app_fname = app_url.split('/')[-1]
| app_fname = os.path.join(down_dir, app_fname)
| if not file_ok(md5_url, app_fname):
| os.remove(app_fname)
| print('文件已损坏。')
| exit(2)
|
| # 部署软件
| deploy(app_fname)
|
| # 更新live_ver文件的版本
| if os.path.exists(ver_fname):
| os.remove(ver_fname)
|
| wget.download(ver_url, ver_fname)
回滚代码
回滚思路:
1、只需要把软链接指定到上一个版本(这部分脚本里面没有需要自己写)
取出last_ver版本号,赋值给ver(因为之前下载的版本都在web应用服务器上)
构建本地目录'/var/www/deploy/website-%s' % ver
把/var/www/html/nsd1906删除
创建软链接
2、直接旧版本代码推送覆盖,等同于上线新版本