cicd 07--构建前后端一体化自动化发布流程

2023-10-26

1 介绍

cicd 04–构建自动化发布流程 介绍了一种通用的自动化发布流程,其适用于单个前端或者后端的服务,若某个服务同时包括前后端,且前后端代码分离,那么改方法就不适用了。为此需要设计一种同时包括前后端的自动化发布流程,其思路是分别先后clone 前端、后端代码,然后对前端编译|预处理后将其和后端一起打包为线上可用的镜像,最后发布到集群中。本文介绍 构建前后端一体化自动化发布流程, 贴在此处以便于自己和有需要的小伙伴查阅学习,后续会在此处更新相关优化方法和注意事项。

2 构建过程

2.1 功能说明

主要功能模块:
清理空间(Clean workspace)
下载代码(Clone frontend )
下载后端代码(Clone backend )
同步代码(Scp to sre-cicd)
build前端(generate frontend)
同步前端到后端(copy frontend to backend)
build镜像(Build docker images)
打tag(Set tag)
检查deploy(check deploy exists)
发布到k8s(deploy to k8s)
告警通知(Declarative: Post Actions)

2.2 jenkins & gitlab 配置

jenkins 基础配置:

GitLab Repository Name: 填写gitlab 的url
Build Trigger-> Accepted Merge Request Events: True
Filter branches by regex: Target Branch Regex	填写 .*master 或者 .*your_branch_name
Secret token: 自动生成即可

gitlab 配置:

分别在前后端 repo 中配置jenkins 的webhook:
在 settings->integrations 中新加Webhooks,
URL: 填写jenkins 中build Triggers的url
Secret Token:填写jenkins中生成的 Secret token
Trigger: Merge request events(可按需增加其它方式)

涉及的参数说明:

cluster = 'yourCluster'
namespace = 'sre-test'
deployment = 'xg-nginx-prod'
container_name = 'xg-nginx'
docker_repo = 'yourDockerRepoNamespace/yourDockerImageName'
branch = '${gitlabTargetBranch}'
repo_url_frontend = "git@yourGitlabUrl/test_flask_frontend.git"
repo_url_backend = "git@yourGitlabUrl/test_flask_backend.git"
work_dir_frontend = 'gitlab_test_flask_two_repo_frontend'
work_dir_backend = 'gitlab_test_flask_two_repo_backend'
build_front_docker = 'your_docker_image_repo/repo_name:ubuntu_20.04'

涉及的节点:

SRE_BUILD_NODE: 用于build镜像,并将其推送到阿里云镜像仓库
slave: 该节点用于clone git代码,并将其rsync到 docker build机器上
SRE_NODE: 用于执行kubectl或helm操作

jenkinsfile 配置:

cluster = 'yourCluster'
namespace = 'sre-test'
deployment = 'xg-nginx'
container_name = 'xg-nginx'
docker_repo = 'yourDockerRepoNamespace/yourDockerImageName'
print("branch=${gitlabTargetBranch}")
branch = '${gitlabTargetBranch}'
repo_url_frontend = "git@yourGitlabUrl/test_flask_frontend.git"
repo_url_backend = "gityourGitlabUrl/test_flask_backend.git"
work_dir_frontend = 'gitlab_test_flask_two_repo_frontend'
work_dir_backend = 'gitlab_test_flask_two_repo_backend'
build_front_docker = 'your_docker_image_repo/repo_name:ubuntu_20.04'

def get_tag_dir() {
    echo "${gitlabSourceRepoURL}"
    if ("${gitlabSourceRepoURL}" == "${repo_url_frontend}") {
        return "${work_dir_frontend}"
    }
    return "${work_dir_backend}"
}
tag_dir = get_tag_dir() // tag_dir is work_dir_frontend or work_dir_backend according to the trigger repo

def date = new Date()
image_version = date.format('yy.w.yyMMddHHmm')

default_description = "${namespace}/${deployment}:${image_version}"
currentBuild.description = "${default_description}"

pipeline {
    agent { 
        node { 
            label 'SRE_BUILD_NODE' 
        } 
    }
    
    environment {
        para = "para_just_for_test"
    }
    
    stages {
        stage('Clean workspace') {
        agent { 
            node { 
                label 'SRE-Build01-Server' 
            } 
        }
         steps {
            sh """
            echo 'clean workspace'
            rm -fr /data/nas-sre-prod/jenkins/apps/${work_dir_frontend}
            rm -fr /data/nas-sre-prod/jenkins/apps/${work_dir_backend}
            """
        }
      }

stage("Clone frontend"){
          agent { 
             node { 
                 label 'slave' 
             } 
         }
         steps {
            sh """
                echo "Clone frontend repo: ${repo_url_frontend} ${branch}"
                pwd
            """
            dir("${work_dir_frontend}"){
                deleteDir()
                    git(
                        url: "${repo_url_frontend}",
                        credentialsId: '13*yourGitCredentialsId*14',
                        branch: "${branch}"
                    )
            }
            sh """
            pwd
            ls
            """
         }
      }

      stage("Clone backend"){
          agent { 
             node { 
                 label 'slave' 
             } 
         }
         steps {
            sh """
                echo "Clone frontend repo: ${repo_url_frontend} ${branch}"
                pwd
            """
            dir("${work_dir_backend}"){
                deleteDir()
                    git(
                        url: "${repo_url_backend}",
                        credentialsId: '13*yourGitCredentialsId*14',
                        branch: "${branch}"
                    )
            }
            sh """
            pwd
            ls
            """
         }
      }

      stage('Scp to sre-cicd') {
         agent { 
             node { 
                 label 'slave' 
             } 
         }
         steps {
            sh """
                pwd
                echo "rsync frontend"
                rsync -Lrap ${work_dir_frontend} --exclude ${work_dir_frontend}/.git 106.yourSre-cicdMachine.148:/data/nas-sre-prod/jenkins/apps/
                if [ \$? -ne 0 ]
                then
                    echo "Found some error when copy the frontend repo"
                    exit 1
                fi
                echo "rsync backend"
                rsync -Lrap ${work_dir_backend} --exclude ${work_dir_backend}/.git 106.yourSre-cicdMachine.148:/data/nas-sre-prod/jenkins/apps/
                if [ \$? -ne 0 ]
                then
                    echo "Found some error when copy the backend repo"
                    exit 1
                fi
            """
         }
      }
      
      stage('generate frontend') {
         agent { 
             node { 
                 label 'SRE_BUILD_NODE' 
             } 
         }
         steps {
             sh """
                echo 'generate frontend files'
                pwd
                ls
                docker rm -f ${work_dir_frontend} || pwd
                docker run --name=${work_dir_frontend} -v /data/nas-sre-prod/jenkins/apps/${work_dir_frontend}:/home/ ${build_front_docker} bash /home/build.sh
                docker rm -f ${work_dir_frontend} || pwd
                ls
            """
        }
      }
      
      stage('copy frontend to backend') {
         agent { 
             node { 
                 label 'SRE_BUILD_NODE' 
             } 
         }
         steps {
             sh """
                echo 'copy frontend to backend'
                pwd 
                ls
                cp /data/nas-sre-prod/jenkins/apps/${work_dir_frontend}/src/get_item.html /data/nas-sre-prod/jenkins/apps/${work_dir_backend}/src/templates/
            """
        }
      }

      stage('Build docker images') {
         agent { 
             node { 
                 label 'SRE_BUILD_NODE' 
             } 
         }
         steps {
             sh """
                echo 'build docker image'
                pwd 
                ls
                cd /data/nas-sre-prod/jenkins/apps/${work_dir_backend}/
                if [ ! -f Dockerfile ]
                then
                    echo "No available dockerfile in workspace"
                fi
                if [ ! -f build_docker.sh ]
                then
                    echo "No available build_docker.sh in workspace"
                fi
                bash build_docker.sh ${docker_repo} ${image_version}
                pwd 
                ls
            """
        }
      }

      stage('Set tag') {
         agent { 
             node { 
                 label 'slave' 
             } 
         }
         steps {
             dir("${tag_dir}"){
                sh """
                    pwd
                    ls
                    echo "${branch}  => ${image_version}"
                    git tag -m "Build docker image ${image_version} for ${branch}/${image_version}" ${branch}/${image_version} && git describe && git push origin ${branch}/${image_version}
                    ls
                """
             }
         }
      }

      stage('check deploy exists') {
         agent { 
             node { 
                 label 'SRE_NODE'
             } 
         }
         steps {
            echo 'Hello, check deployment ${cluster} ${namespace}/${deployment} exists'
            sh "/usr/local/bin/kubectl --kubeconfig /home/yourHome/.kube/config-${cluster} -n ${namespace} get deploy ${deployment}"
         }
      }
      
      stage('deploy to k8s') {
         agent { 
             node { 
                 label 'SRE_NODE'
             } 
         }
         steps {
            echo 'deploy to k8s'
            sh """
            /usr/local/bin/kubectl --kubeconfig /home/yourHome/.kube/config-${cluster} -n ${namespace} set image deployment/${deployment} ${container_name}=your_docker_image_repo/${docker_repo}:${image_version}
            """
         }
      }
    }
    
    post {
        always {
            echo 'I have finished'
        }
        success {
            echo "all in one, succeed!"
            sh """
            curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"gitlab_test_flask_two_repo notify, ${namespace}/${deployment}:${image_version}, succeed!"}}' https://open.feishu.cn/open-apis/bot/v2/hook/46xxx-xxx-xxx05
            """
        }
        failure {
            echo "all in one, failed!"
            sh """
            curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"gitlab_test_flask_two_repo notify, ${namespace}/${deployment}:${image_version}, failed!"}}' https://open.feishu.cn/open-apis/bot/v2/hook/46xxx-xxx-xxx05
            """
        }
    }
}

2.3 测试结果

前端修改代码:
在这里插入图片描述
在这里插入图片描述
后端代码修改:
在这里插入图片描述
在这里插入图片描述

jenkins 执行结果:
在这里插入图片描述
k8s 镜像效果:
在这里插入图片描述

3 注意事项

  1. 前后端一体化的cicd流程,可能由前端触发,也可能有后端触发,因此需要判断是哪个触发的,并在对应的git repo 中打上tag。
  2. 实际项目中,可能不同用户想通过不同分支触发并发布到不同的环境中,此时可以主动获取gitlab 触发分支,不同分支配置不同的命名空间即可。
  3. 本案例中的场景需要build 前端生成核心文件,此处使用ubuntu:20.04作为演示案例,实际中可能为node:13|14|15 等镜像。

4 说明

软件环境:
Docker: 20.10.*
K8s: 1.12
jenkins 版本:2.299
参考文档:
jenkins 官方文档

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cicd 07--构建前后端一体化自动化发布流程 的相关文章

随机推荐

  • DC-DC与电感

    作者 AirCity 2020 2 16 Aircity007 sina com 本文所有权归作者Aircity所有 DC DC即直流 直流转换器 输入是直流电压 输出也是直流电压 DC DC有升压型boost 降压型buck和升降压型bu
  • 基于SSM的海外代购系统设计与实现

    摘 要 近年来 我国的互联网方面发展十分的迅速 短短20年 信息时代就已经展现在了我们的面前 电商 是信息时代中出现的一大产物 电商的发展在很大程度上来说的的确确的方便了我们日常的部分的生活购物行为 从1997年电商的萌芽开始发展直至今日
  • 类的公有类型(public)和私有类型(private)

    数据成员可以为公有 函数成员也可以为私有 如果数据成员为公有 那么在对象的作用域内的任何函数都可以通过对象名使用该数据成员 如果函数成员为公有 那么该函数成员只能被公有的函数通过对象名调用
  • python二元函数图像在线绘制_“绘图,让科学生动起来”:Python-matplotlib绘图(多元函数拟合-3D绘图专题)...

    作者简介 85后一名分析化学工作者及科学爱好者 深爱着北京的老北京人 爱好运动 科学 旅行 个人微信公众号 科学是什么东东 欢迎关注 搭建python matplotlib绘图平台的四个要素是什么 它们是 python软件主体 pip库管理
  • ReentrantLock 源码分析

    ReentrantLock简单使用demo如下 Lock lock new ReentrantLock lock lock try 业务逻辑 finally lock unlock 注 获取的锁代码要放到try块之外 防止获得锁代码异常 抛
  • Chrome开发者工具详解

    Chrome开发者工具详解 1 Elements Console Sources面板 Chrome开发者工具面板 面板上包含了Elements面板 Console面板 Sources面板 Network面板 Timeline面板 Profi
  • adb MacBook Pro上使用adb命令:Command not found或者每次使用前要source .bash_profile文件

    前言 adb MacBook Pro上使用adb命令报错 Command not found 或者每次使用前要source bash profile文件 一 解决问题1 在根路径配置 bash profile文件 如果没有 touch ba
  • python-面向对象基础-类属性&实例属性-构造&析构

    一 类的定义 class 类名 类体 class Person object pass 二 类中成员的定义 class Person object 属性 name tom age 18 height 180 方法 def eat self
  • C++堆和栈的区别和联系

    2017年09月16日 10 39 33 阅读数 1605 参考博客地址 http blog csdn net hairetz article details 4141043 http blog csdn net handsomesunsh
  • C#学习之ASP.NET概述

    ASP NET的应用 网络应用程序开发 学习ASP NET的优势 易学 设计人员和后台代码人员专注于自己的工作 原因 ASP NET将HTML页面代码和脚本代码分离 高效地创建大规模的网络应用程序 背景 自从互联网的出现 各种网络开发技术层
  • 关于ehcache使用rmi方式实现分布式缓存时遇到的问题

    业务场景 一个架构较老的系统 由于在正式环境中需要搭建集群环境 目前使用echcache来作为缓存 为了减少代码修改 使用了RMI方式来实现集群 使用了被动发现和注册的方式 配置如下
  • Ansible Lookup

    1 文件内容的读取 hosts all vars contents lookup file etc foo txt tasks debug msg the value of foo txt is contents Note 切记读取的是本地
  • 使用gpt绘制奥特曼

    public class Ultraman extends JPanel public void paint Graphics g Color silver new Color 192 192 192 画头 g setColor Color
  • C语言顺序表中删除值为x的元素

    要求时间复杂度为O n 空间复杂度为O 1 实现代码如下 删除线性表中为x的元素 void deleteX SqList L int x int k 0 for i 0 i
  • 全球及中国工业互联网产业运行态势与布局状况调研报告2022-2028年

    全球及中国工业互联网产业运行态势与布局状况调研报告2022 2028年 修订日期 2022年4月 出版单位 鸿晟信合研究院 对接人员 周文文 报告价格 纸质版6500元 电子版6800元 纸质 电子版7000元 有折扣 内容部分有删减 了解
  • 1、网络隧道技术

    网络隧道技术简介 隧道技术 Tunneling 是一类网络协议 它是一种数据包封装技术 它将原始IP包 其报头包含原始发送者和最终目的地 封装在另外一个数据包 称为封装的IP包 的数据净荷中进行传输 使用隧道的原因是在不兼容的网络上传输数据
  • CVE20190708复现

    一 实验环境 基于虚拟机运行 VMware 1 靶机 ip 192 168 8 2 测试机 192 168 8 3 将两个虚拟机设置于同一个网段中 a 在虚拟网络编辑器中 将VMnet0采用桥接模式 并桥接到网线网上 b 设置win7为动态
  • 动态规划浅析

    leetcode53 最大子序和 leetcode62 不同路径 leetcode300 最长递增子序列 动态规划要解决的都是一些问题的最优解 即从很多解决问题的方案中找到最优的一个 当我们在求一个问题最优解的时候 如果可以把这个问题分解成
  • npm install 错误 安装 chromedriver 失败的解决办法

    npm 安装 chromedriver 失败的解决办法 npm 安装 chromedriver 时 偶尔会出错 错误提示类似于 npm ERR chromedriver 2 35 0 install node install js 经分析发
  • cicd 07--构建前后端一体化自动化发布流程

    cicd 07 构建前后端一体化自动化发布流程 1 介绍 2 构建过程 2 1 功能说明 2 2 jenkins gitlab 配置 2 3 测试结果 3 注意事项 4 说明 1 介绍 cicd 04 构建自动化发布流程 介绍了一种通用的自