cicd的部署--Jenkins及自动部署

CI(持续集成)/CD(持续交付)

在这里插入图片描述

软件程序上线流程

  1. 程序员将代码上传到gitlab服务器
  2. 云计算工程师,通过jenkins服务器自动下载gitlab上的代码
  3. 云计算工程师编写自动部署到服务器上的脚本
  • 启动之前准备好的机器: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服务器

  • jenkins的IP地址是:192.168.4.30(jenkins服务器,以自己的ip为准)。它必须能与其他主机通信
  • 关闭selinux/防火墙
  • 安装jenkins
# 安装依赖包
# jenkins需要通过git下载代码,所以装git。
# jenkins是java程序,所以装java
# postfix和mailx是邮件程序,jenkins可以通过它们给管理员发邮件
[root@jenkins ~]# yum install -y git postfix mailx java-11-openjdk

# 把jenkins软件包拷贝到192.168.4.30的/root目录下
[root@jenkins ~]# ls
jenkins-2.263.1-1.1.noarch.rpm jenkins_plugins.tar.gz

# 在192.168.4.30上安装jenkins
[root@jenkins ~]# yum install -y jenkins-2.263.1-1.1.noarch.rpm

# 启动服务,并设置为开机自启
[root@jenkins ~]# systemctl enable jenkins
jenkins.service is not a native service, redirecting to systemd-sysv-install.   # 注意:这里不是错误,忽略即可
Executing: /usr/lib/systemd/systemd-sysv-install enable jenkins
[root@jenkins ~]# systemctl start jenkins
# 查看初始化密码
[root@jenkins ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
2c58512973be4a44aec3ef5c1463d00a

把查看到的密码粘贴到文本框中,如下:

在这里插入图片描述

不用创建管理员,使用自带的admin
在这里插入图片描述
在这里插入图片描述

  • 修改admin密码

在这里插入图片描述

在这里插入图片描述

CI(持续集成)/CD(持续交付)

在这里插入图片描述

配置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地址

http://192.168.88.20/devops/myproject.git
在这里插入图片描述

指定分支构建的时候,使用上面步骤创建的变量$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服务器

自动化部署流程

  1. 程序员编写代码,推送到gitlab服务器

  2. Jenkins服务器从gitlab上下载代码

  3. Jenkins处理下载的代码

      • 删除下载目录的版本库
      • 将下载的代码打包
      • 计算程序压缩包的md5值
      • 在Jenkins上安装httpd服务,共享程序压缩包
  4. web服务器下载软件包,并应用(通过脚本实现)

  5. 访问测试

在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
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 可以看到重新部署的文件

猜你喜欢

转载自blog.csdn.net/m0_52508197/article/details/127348080