Jenkins 项目管理、构建分发服务器、自动化上线
Jenkins 项目管理、构建分发服务器、自动化上线
永久关闭防火墙和selinux
[root@gitlab ~]# systemctl stop firewalld
[root@gitlab ~]# systemctl disable firewalld
[root@gitlab ~]# setenforce 0
[root@gitlab ~]# vim +7 /etc/selinux/config
7 SELINUX=disabled
CI/CD
- 启动之前准备好的机器:192.168.4.10(develop)、192.168.4.20(gitlab)、192.168.4.30(jenkins)
- 设置gitlab容器开机自启:/etc/rc.local是开机后会自动运行的脚本,写到这个文件中的命令,开机后都会自动运行
[root@gitlab ~]# vim /etc/rc.d/rc.local # 在文件尾部追加一行内容如下:
... ...
podman start gitlab
[root@gitlab ~]# chmod +x /etc/rc.d/rc.local
配置jenkins
- 访问http://192.168.4.30:8080(以自己的jenkins服务器的ip为准),用户名是admin
- 安装插件:jenkins的很多功能都是能过插件实现的,比如发邮件、比如中文支持。
[root@jenkins ~]# yum install -y tar
[root@jenkins ~]# tar xf jenkins_plugins.tar.gz
# 拷贝文件的时候,注意选项,-r可以拷贝目录,-p保留权限
[root@jenkins ~]# cp -rp jenkins_plugins/* /var/lib/jenkins/plugins/
[root@jenkins ~]# systemctl restart jenkins
# 刷新web页面,如果出现中文,则插件安装成功
软件版本管理
- 可以在git中使用tag标记将某一次commit提交标识为某一版本
[root@develop ~]# cd myproject/ # 进入项目目录
[root@develop myproject]# git tag # 查看标记,默认没有标记
[root@develop myproject]# git tag 1.0 # 将当前提交,标识为1.0
[root@develop myproject]# git tag
1.0
[root@develop myproject]# echo 'hello world' > index.html
[root@develop myproject]# git add .
[root@develop myproject]# git commit -m "add index.html"
[root@develop myproject]# git tag 1.1
# 将本地文件和tag推送到gitlab服务器
[root@develop myproject]# git push # 只推送文件,不推送标记
[root@develop myproject]# git push --tags
在gitlab上查看标记:
配置jenkins访问gitlab代码仓库
参数化构建过程中,“名称”是自己定义的变量名,用于标识tag或分支
git仓库地址,在gitlab上找到myproject仓库的http地址,注意将gitlab名称改为IP地址
指定分支构建的时候,使用上面步骤创建的变量$web
点击保存。
在项目页面, 可以进行构建测试。
测试下载
构建过程中,边栏左下角会有一个闪烁的灰球,构建成功是蓝球,失败是红球。点击它,可以看详情。
在jenkins上查看下载的内容:
[root@jenkins ~]# ls /var/lib/jenkins/workspace/myproject/
README.md hosts passwd
下载到子目录
- jenkins下载不同的版本到自己的子目录,不共享相同目录
新增时,如果没有中文,英文是“checkout to a sub directory”
点击保存。
测试:
# 删除之前下载的内容
[root@jenkins ~]# rm -rf /var/lib/jenkins/workspace/myproject/
执行多次构建,构建不同版本:
查看下载目录:
[root@jenkins ~]# ls /var/lib/jenkins/workspace/myproject/
myproject-1.0 myproject-1.1
准备两台web服务器
- web1:192.168.4.100,配置YUM,关闭SELINUX/防火墙
- web2:192.168.4.200,配置YUM,关闭SELINUX/防火墙
部署代码到web服务器
自动化部署流程
- 程序员编写代码,推送到gitlab服务器
- Jenkins服务器从gitlab上下载代码
- Jenkins处理下载的代码
- 删除下载目录的版本库
- 将下载的代码打包
- 计算程序压缩包的md5值
- 在Jenkins上安装httpd服务,共享程序压缩包
- web服务器下载软件包,并应用(通过脚本实现)
- 访问测试
在Jenkins上安装、配置httpd共享服务器
[root@jenkins ~]# yum -y install httpd # 安装apache的软件包
[root@jenkins ~]# mkdir -p /var/www/html/deploy/packages # 创建jenkins从gitlab上下载的打包代码存放的目录
[root@jenkins ~]# chown -R jenkins:jenkins /var/www/html/deploy/ # 修改权限,因为是jenkins自动下载的,需要修改存放的权限
[root@jenkins ~]# systemctl start httpd
[root@jenkins ~]# systemctl enable httpd
配置jenkins把gitlab下载的代码打包
在jenkins上修改myproject项目
pkg_dir=/var/www/html/deploy/packages # 定义存储软件包路径的变量
cp -r myproject-$web $pkg_dir # 将下载的代码目录拷贝到下载目录
rm -rf $pkg_dir/myproject-$web/.git # 删除下载目录的版本库,不是必须的,只是为了严谨
cd $pkg_dir # 切换到下载目录
tar -zcf myproject-$web.tar.gz myproject-$web # 将下载的目录打包
rm -rf myproject-$web # 下载目录已打包,目录就不需要了,删除它
md5sum myproject-$web.tar.gz | awk '{print $1}' > myproject-$web.tar.gz.md5 # 计算压缩包的md5值,保存到文件
cd ..
echo -n $web > ver.txt # 将版本号写入文件
以上步骤改好后,保存。
测试修改的任务。
web服务自动部署
安装httpd服务
[root@web1 ~]# yum install -y httpd tar wget python38*
[root@web1 ~]# mkdir /var/www/download # 存储jenkins主机上下载的应用代码
[root@web1 ~]# mkdir /var/www/deploy # 部署应用代码
[root@web1 ~]# systemctl enable httpd --now
[root@web1 ~]# ss -tlnp | grep :80
LISTEN 0 128 *:80 *:* users:(("httpd",pid=9721,fd=4),("httpd",pid=9720,fd=4),("httpd",pid=9719,fd=4),("httpd",pid=9717,fd=4))
编写自动上线脚本
- 下载软件包
- 检查软件包是否损坏
- 解压、部署到web服务器
[root@web1 ~]# vim web.py
import os
import requests
import hashlib
import tarfile
def has_new_ver(web1_ver_path, ver_url):
# web1_ver_path 为应用服务器web1主机的当前版本文件路径
# 如果文件不存在,返回True, 提示没有新版本
if not os.path.exists(web1_ver_path):
return True
# 当web1_ver_path存在时,先获取当前应用的版本号
with open(web1_ver_path, mode="r") as fr:
local_ver = fr.read()
# 通过requests获取jenkins服务器上的最新版本号
r = requests.get(ver_url)
# 当web1上的版本号和Jenkins服务器上的版本号不相等时,返回True, 即有新的版本
if local_ver != r.text:
return True
return False
# 声明函数file_ok(), 功能:如果下载的包文件未损坏,则返回True,否则返回False
def file_ok(web1_tar_path, jenkins_tar_md5_url):
m = hashlib.md5()
with open(web1_tar_path, mode="rb") as fw:
while True:
data = fw.read(4096)
if len(data) == 0:
break
m.update(data)
# jenkins_tar_md5_url 为jenkins服务器上的压缩包的md5值文件链接地址
r = requests.get(jenkins_tar_md5_url)
if m.hexdigest() == r.text.strip():
# 相等,代表文件未损坏,返回True
return True
return False
# 声明函数deploy(), 功能:用于部署软件到 web1 服务器
def deploy(web1_tar_path, web1_deploy_dir, dest):
tar = tarfile.open(web1_tar_path) # 打开压缩包web1_tar_path
tar.extractall(path=web1_deploy_dir) # 解压到web1_deploy_dir目录下
tar.close() # 关闭tar
# 获取web1_tar_path变量中,最后一个'/',右边的内容,然后做切片,去除".tar.gz",只留下文件名
file_name = os.path.basename(web1_tar_path)[:-7]
# 将变量web1_deploy_dir和变量file_name拼接在一起
app_dir = os.path.join(web1_deploy_dir, file_name)
# 创建链接,如果软链接dest存在,删除软连接,然后为app_dir创建新的软链接
if os.path.exists(dest):
os.remove(dest)
os.symlink(app_dir, dest)
if __name__ == "__main__":
### 判断jenkins服务器上是否有新版本
# ver_url 为jenkins服务器的当前版本文件路径
# web1_ver_path 为应用服务器web1主机的当前版本文件路径
ver_url = "http://192.168.4.30/deploy/ver.txt"
web1_ver_path = "/var/www/deploy/ver.txt"
if not has_new_ver(web1_ver_path, ver_url):
print("no new version~")
exit(1)
# ==========================================
# 如果服务器上有新版本,则下载新版本
# r.text 为jenkins服务器的当前版本内容
# jenkins_tar_url 为jenkins服务器上的压缩包链接地址
# web1_tar_path 为应用服务器web1主机的压缩包路径
r = requests.get(ver_url)
jenkins_tar_url = f"http://192.168.4.30/deploy/packages/myproject-{r.text}.tar.gz"
web1_tar_path = f"/var/www/download/myproject-{r.text}.tar.gz"
with open(web1_tar_path, mode="wb") as fw:
fw.write(requests.get(jenkins_tar_url).content)
# 校验下载的软件包是否损坏,如果损坏则删除 os.remove()
# jenkins_tar_md5_url 为jenkins服务器上的压缩包的md5值文件链接地址
jenkins_tar_md5_url = jenkins_tar_url + ".md5"
if not file_ok(web1_tar_path, jenkins_tar_md5_url):
print("File has been broken~")
os.remove(web1_tar_path)
exit(2)
# =========================================
web1_deploy_dir = '/var/www/deploy'
dest = '/var/www/html/current'
deploy(web1_tar_path, web1_deploy_dir, dest)
#更新本地的版本文件
if os.path.exists(web1_ver_path):
os.remove(web1_ver_path)
with open(web1_ver_path, mode="w") as fw:
fw.write(requests.get(ver_url).text)
[root@web1 ~]# python3 web.py
# 访问http://192.168.4.100/current 可以看到部署的文件
[root@web1 html]# ls /var/www/deploy
myproject-1.1 ver.txt
- 完整测试流程:
- 程序员编写新版本并推送到服务器
- Jenkins上构建新版本
- web服务器上执行web.sh部署新版本
# 程序员编写新版本
[root@develop myproject]# vim index.html
<marquee>Welcome to tedu</marquee>
[root@develop myproject]# git add .
[root@develop myproject]# git commit -m "modify index.html"
[root@develop myproject]# git tag 2.0
# 程序员推送到服务器
[root@develop myproject]# git push
[root@develop myproject]# git push --tags
[root@web1 ~]# python3 web.py
# 访问http://192.168.4.100/current 可以看到重新部署的文件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)