Git-GitLab-Jenkins
准备:主机4台
git : 192.168.4.70
gitlab : 192.168.4.71
jenkins : 192.168.4.72
server : 192.168.4.73
Git
Git是一个开源的分布式版本控制系统,用于敏捷高效的处理任何或大或小的项目。
Git是一个开源的版本控制软件
Git与常用版本控制工具CVS,Subversion等不同,采用分布式版本库方式,不必服务器端软件支持
Git安装
yum -y install git
Git配置用户相关信息
git config --global user.name 'Miku' //设置用户名
git config --global user.email 'xxxx@xx.xxx' //设置邮箱
git config --global core.editor vim // 设置编辑器为vim
git config --list //查看配置信息
cat ~/.gitconfig
Git工作区域
工作区:代码目录
暂存区:工作区与版本库隐藏地带,.git/index
版本库:工作区中有.git隐藏目录,这个目录就是版本库
工作区-git add->暂存区 -git commit->版本库
Git应用
1、创建版本库
git init 项目名 //在项目刚开始

在项目文件里面使用初始化
git init // 适合已经编写部分代码的情况

2、查看状态
git status

创建一个文件

可以通过git status -s 来查看文件状态 ??表示未知状态

3、添加文件至暂存区
git add 文件名 // 单独添加一个文件
git add . //添加所有文件

4、将文件从暂存区撤出
git rm --cached 文件名

5、确认版本库
git commit //会出现vim输入说明,如果直接存盘退出则不会提交

git commit -m "描述信息"

6、删除文件
git ls-files //查看版本库中存在的文件

git rm 文件名

git commit //提交操作结果

7、查看所有提交
git log

8、返回之前状态
git checkout ID // 可以将文件拷贝出来,但不建议直接在文件上做修改

9、返回最新状态
git checkout master

10、在暂存区恢复已删除文件
git checkout -- * //恢复所有删除但未提交的文件
将以下文件存放至暂存区

删除以.log结尾的文件

查询状态,会显示删除的文件

使用git checkout -- * 来恢复所有文件

11、tag管理,可以给某一次提交打标记,常用于版本号
git tag //查看标记
git tag 信息 // 打标记,将当前commit标记



分支管理
git中默认有一个master主干分支
可以自己创建分支,不同分支使用工作区一样
git branch //查看分支
git branch 分支名 // 创建一条分支
git checkout 分支名 //切换分支

修改分支内容
在test分支下添加文件
cp /etc/passwd passwd
git add passwd
git commit -m 'add passwd'

切换回主干master

分支合并会主干
git merge 分支名 -m '描述' //合并分支到master

删除分支
git branch -d 分支名 // 删除分支

创建一个提交忽略的文件
可以在工作区创建一个.gitignore文件,存放所有不需要commit到版本库中的内容
vim .gitignore


GitLab
gitlab中重要的概念
群组Group:对应一个开发团队
项目Project:对应软件项目
成员member:对应用户,将用户加入到组
Gitlab安装
至少 4 GB 内存,需要网络
yum install -y curl policycoreutils-python-utils openssh-server
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
yum install -y gitlab-ce
安装后启动:gitlab-ctl reconfigure
GitLab登录
登录名root
密码在这个文件当中:cat /etc/gitlab/initial_root_password

创建组

下面权限按需求设置


创建账户Sayu

权限依旧按需求

修改密码,密码要大于8位且不能位简单密码


创建项目myweb,授权Sayu为程序员


这里内容也是按需求去选择


授权用户Sayu


也可以将Sayu加入群组,流程和加入项目一样,只不过需要在组下面成员添加

使用Sayu登录,会要求修改密码


可以看到已经被加入项目和组


上传代码
可以直接上传文件,也可以使用git上传

在git服务器上新建文件夹,提交一次初始化master后连接远程仓库
git remote add 命名 http://IP或域名/yunwei_devops/mypro.git

重命名:git remote rename 旧名字 新名字

推送代码:
git push -u mypro --all

推送tag标记到远程仓库
git tag 0.1 //创建0.1标签
git push -u mypro --tags // 上传标签

查看仓库的master分支,已经有了提交的代码
Jenkins
持续集成(CI)是当下最为流行的应用程序开发实践方式
程序员在代码仓库中集成了修复bug、新特性开发或是功能革新
CI工具通过自动构建和自动测试来验证结果,这可以检测到当前程序代码的问题,迅速提供反馈
Jenkins特点:
简单、可扩展、用户界面友好
支持各种SCM(软件配置管理)工具,如GIT、SVN、CVS等
能够构建各种风格的项目
跨平台,几乎支持所有平台
主要流程:
程序员提交代码更新到软件仓库(git)--> CI服务器基于计划任务查询仓库,并下载代码 --> CI服务器运行构建过程,并生成软件包 --> CI服务器进行单元和集成测试、存储测试结果 --> 向开发团队发送构建通知
安装Jenkins
Jenkins官网网络安装网址:https://www.jenkins.io/doc/book/installing/linux/#fedora-stable
下载yum仓库:wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/rpm-stable/jenkins.repo
依赖安装:
安装fontconfig ,java-21-openjdk
yum -y install fontconfig java-21-openjdk
rocky9 可以直接yum安装java21,rocky8需要网上下载
yum install fontconfig java-21-openjdk
jdk21下载网址,这一个是下载的官方的rpm包,不是openjdk的二进制包:https://www.oracle.com/java/technologies/downloads/#java21
openjdk源码下载地址:https://jdk.java.net/archive/
安装就是将压缩包解压移动达到/usr/local下然后配置以下java环境
export JAVA_HOME=/usr/local/jdk21
export PATH= PATH: JAVA_HOME/bin
yum仓库安装jenkins并起服务:
Jenkins安装:yum install jenkins
重新加载systemd服务: systemctl daemon-reload
启动服务并配置开机自启:systemctl enable jenkins
如果自己下载的war包,Jenkins起服务要使用下面的命令:
java -jar jenkiins.war
登录Jenkins
打开edge访问jenkins服务器8080端口

查看密码

选择选择插件来安装

因为Jenkins连接国外站点,所以选择无,进去后再安装

这里先不创建用户,直接admin继续


修改账户密码
修改密码

更新插件

设置华为云的Jenkins源
https://mirrors.huaweicloud.com/jenkins/updates/update-center.json

安装中文汉化包

下面的方框打勾可以在安装插件后自动重启jenkins服务

安装Git Parameter


安装其他插件
插件的格式为.hpi文件,有些使用不是最新版本的插件或仓库没有的插件可以使用这种方式安装
在管理界面插件管理的高级(advanced settings)里面有一个部署插件,可以安装下载下来的插件


下面的网址可以填写提供其他仓库没有的插件的网址来下载安装插件

CI / CD流程
整个完整的devops流程为
开发团队 --编写--> 源码 --使用Git/SVN上传--> GitLab等代码仓 --被Jenkins拉取--> 自动构建、测试、打包、归档成软件包 --被Jenkins发送--> 服务器 --通过ansible或者python代码等--> 自动部署安装交付
其中CI流程为:Jenkins拉取代码仓代码自动构建、测试、打包、归档成软件包
CD流程为:Jenkins发送软件包到服务器自动部署安装交付
完整devops流程:
例如:编写一个简单的网站服务部署到server上
本地提交代码到GitLab上
1、编写简单网页代码
初始化git项目文件夹:
git init website

编写一个index.html文件

将index.html提交以初始化master分支

为website创建一个0.1的tag

在追加一行到index.html来形成不同的版本

将0.2版本提交并创建标签

2、在GitLab上创建项目,项目类型为公开的,Sayu用户和Miku用户为项目主程序员
先创建一个群组用于这个项目(如有其他可用群组可以直接用)



添加Sayu用户为开发者



为创建的组创建项目



查看项目成员可以发现,Sayu用户已经跟着组自动成为项目程序员,添加Miku为主程序员




3、上传代码到GitLab
先复制项目克隆地址,根据提示,我们可以直接将项目连接到本地git


直接将代码push上代码仓,因为代码仓创建默认主分支main
而git默认主分支为master,所以上传后会新增一个master分支

查看代码仓

切换后可以看到现在是0.2版本,因为最开始初始化本地git时用的Miku,所以创建者叫Miku


查看历史,会发现0.1版本也有



Jenkins构建CI
1、新建一个项目



这里选择gitlab项目http网址,下面报错放在jenkins主机72上执行一下发现是因为72没装git,安装一下




2、下载代码
执行Jenkins任务,会将代码下载到/var/lib/jenkins/workspace目录下



查看jenkins主机的目录,已经拉取成功

3、修改任务
下载的软件放到子目录当中
软件最终是为了部署到服务器上,为了方便应用获取jenkins上的软件,需要在jenkins服务器上安装web服务
下载的软件拷贝到web目录下,并打包压缩,方便应用服务器下载
计算压缩的md5值并计算,便于服务器做文件完整性校验
jenkins服务器要声明软件的当前版本和前一版本
安装web服务
yum -y install httpd
systemctl start httpd
创建软件子目录
mkdir -p /var/www/html/deploy/pkgs
修改权限另jenkins获得所有权
chown -R jenkins :jenkins /var/www/html/deploy
在jenkins项目里配置


pkg_dir=/var/www/html/deploy/pkgs // 定义软件压缩包路径参数
cp -r website-web_version pkg_dir //将从gitlab上下载的文件拷贝到webroot
cd p k g d i r r m − r f w e b s i t e − pkg_dir rm -rf website- pkgdirrm−rfwebsite−web_version/.git //删除版本库文件
tar -czf website- w e b v e r s i o n . t a r . g z w e b s i t e − web_version.tar.gz website- webversion.tar.gzwebsite−web_version //将软件目录打包。便于发布传输
rm -rf website- w e b v e r s i o n m d 5 s u m w e b s i t e − web_version md5sum website- webversionmd5sumwebsite−web_version.tar.gz | awk '{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 1}̲' > website-web_version.tar.gz.md5 //计算软件的md5值,用于完整性校验
cd ...
-f live_ver \] \&\& cat live_ver \> last_ver //创建上一版本号文件 echo $web_version \> live_ver //创建当前版本号文件 将这些配置完成后再去构建会发现   ### Jenkins构建CD 1、构建部署deploy脚本 /var/www/download/ 存储下载的软件包 /var/www/deploy/ 存储最新版文件和解压目录 /var/www/html/website-inuse 指向发布软件目录连接 在server机上创建上面两个目录 mkdir /var/www/{download,deploy} 编写python代码:使用到requests,wget等库,需要使用pip下载 ```c #! /bin/python3 import os import requests import wget import hashlib import tarfile # 用于判断是否有新软件包 def have_new_ver(version_file_name, version_url): # 如果本地没有版本文件,就说明本地部署过,直接返回True if not os.path.isfile(version_file_name): return True # 先从远程下载版本文件存放于version_fie_name r = requests.get(version_url) # 打开并读取本地的记录版本的文件 with open(version_file_name) as f : local_version = f.read() # 如果本地文件内容与远程下载的一致,就返回False,没有新版本需要部署,不一致就返回True,需要部署新版本 if local_version != r.text: return True else : return False # 检查软件包是否完整 def check_pkg_md5(path, url): m = hashlib.md5() # 打开压缩包并开始以4096个字节循环读取数据,当读到一批为空字节后停止,并不断更新md5输出码 with open (path, 'rb') as f : while 1 : date = f.read(4096) if not date : break m.update(date) # 获取远程的md5文件 r = requests.get(url) # 如果本地的md5码和远程下载下来的md5码一致,软件包完整就返回True,否则返回False if m.hexdigest() == r.text.strip(): return True else : return False # 部署软件包到服务器 def pkg_deploy(app_path, deploy_path): # 打开并解压tar包 tar = tarfile.open(app_path) tar.extractall(path=deploy_path) tar.close() # 定义部署目标地址 dest = app_path.split('/')[-1] dest = dest.replace(".tar.gz", '') dest = os.path.join(deploy_path, dest) # 定义链接文件地址 link = "/var/www/html/website_inuse" # 如果存在链接文件夹,需要删除再创建新的链接,否则会报错 if os.path.exists(link): os.remove(link) os.symlink(dest, link) if __name__ == "__main__" : # 参数记录当前版本文件地址和远程版本文件地址 version_file_name = "/var/www/deploy/live_ver" version_url = "http://192.168.4.72/deploy/live_ver" # 检查软件包是否最新的 if not have_new_ver(version_file_name, version_url): print("未发现新版本") exit(1) # 下载压缩包 r = requests.get(version_url) version = r.text.strip() # 去除结尾的/n # 远程压缩包下载地址 app_url = "http://192.168.4.72/deploy/pkgs/website-" + version + ".tar.gz" # 压缩包下载到本地存放地址 download_dir = "/var/www/download" wget.download(app_url, download_dir) # 检查软件包是否完整 md5_download_url = app_url + ".md5" # 本地压缩包路径 app_tar_path = "/var/www/download/website-" + version + ".tar.gz" if not check_pkg_md5(app_tar_path, md5_download_url): os.remove(app_tar_path) print("软件包已损坏") exit(2) else : # 压缩包解压路径 deploy_path = "/var/www/deploy" pkg_deploy(app_tar_path, deploy_path) # 完成上述操作后更新本地当前版本文件内容 if os.path.exists(version_file_name): os.remove(version_file_name) wget.download(version_url, version_file_name) ``` 然后每一次更新构建版本后在server机运行一次脚本就可以自动完成部署咯。 如果主机多,可以使用ansible去批量完成,如果想要连创建目录啥的一起自动化,也可以先编写一个shell脚本,将准备工作做好再运行python脚本,法无定数,根据自己的习惯就好