您现在的位置是:首页 >其他 >A8. Jenkins Pipeline自动化部署过程,多模块远程服务协调实战网站首页其他

A8. Jenkins Pipeline自动化部署过程,多模块远程服务协调实战

smart_ljh 2025-02-11 12:01:03
简介A8. Jenkins Pipeline自动化部署过程,多模块远程服务协调实战

下面我们接着上一篇文章《A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战》继续往下分析,编写Pipeline容器自动化部署脚本。

环境配置

  • 部署主机
    • 同样部署主机也需要安装xmlstarlet和jq工具

      #主要用于项目的pom.xml文件解析
      apt install xmlstarlet
      #主要用于harbor仓库检测镜像时返回json数据的解析
      apt install jq
      
    • Docker容器管理工具安装,这个可以参考我前面的文章《Liunx安装Docker容器化管理工具(记录篇)

部署前需要解决什么

  • 如何建立与部署服务器的连接?
  • 如何将服务打包好的容器分发到不同的服务器上?
  • 怎样让服务在尽可能短的时间内部署好?
  • 目标主机的垃圾与日志文件如何解决?

下面我们带着问题分析部署的过程

  1. 解决jenkins执行环境与shell不一致问题
    这一步可以参数上一篇文章《A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战》中相应位置,利用withCredentials切换到同一环境解决;

  2. 如何建立与部署服务器的连接?
    试想一下当我们想要部署一个服务是否需要先将容器推送到对应的目标服务器呢?这里我们可以用scp命令建立,那么在推送文件前务必免密连接并且通过非admin用户连接后最终可以操作root相关权限。

    • 首先需要生成一个目标服务之间免密登录的证书,用于文件copy与远程连接;

    这一步证书生成可考虑我前面写的《Liunx PEM证书生成与远程登录(记录篇)》文章来完成配置

    • 有了授信证书我们就可以通过scp和ssh进行远程操作了(部署过程中会使用以下命令行)
    #通过scp上传本地文件至远程
    scp -P <远程端口> -i <xxx.pem> </path/local/xxx> user@ip:/path/remote/xxx
    
    #通过ssh登录远程服务器
    ssh -i <xxx.pem> user@ip
    

构建过程信息存储

首先将数据存储工具类(deploy_module_store.py)copy到目标服务上,用于存储服务的基本信息,在批处理过程中记录哪个服务正常部署(通过以下命令同步)

scp -i xxx.pem -P <port> /path/deploy_module_store.py user@host:remote_dir

服务批处理部署

这一步与上一篇文章《A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战》服务构建过程对应,需要部署哪些服务;

source "${project_dir}/servers.sh" #导入项目根目录下servers.sh文件,并读取要部署文件的数组

for service in "${service_array[@]}"; do
    #部署逻辑
done

验证服务镜像合法

开始部署前校验镜像是否存在于harbor镜像仓库中,如果因构建失败或在此期间镜像仓库中的镜像包都不存在了,那么就直接跳出本次构建;根据名称、版本号匹配后,从镜像错误码是否等于NOT_FOUND 和 镜像ID是否小于0这两个因素来是否合法,若不合法则直接跳出本次部署;

#获取服务实际的名称,因为项目在命名的有可能会带有前缀
last_element=$(echo "$service" | cut -d'-' -f2-)

#获取项目对应模块服务的版本号,主要是匹配对应镜像的版本
source "${project_dir}/server_version.sh" "${project_dir}" "${service}"

#利用harbor对外开放api查询harbor仓库中的镜像,是否存在镜像名称+版本号匹配的包
remote_image=$(curl -u "${harbor_user}":"${harbor_password}" -X GET "https://${harbor_host}/api/v2.0/projects/${organization}-${env}/repositories/${last_element}-${env}/artifacts/${server_actual_version}?page=1&page_size=10&with_tag=true&with_label=false&with_scan_overview=false&with_sbom_overview=false&with_accessory=false&with_signature=false&with_immutable_status=false")

#【校验1】解析remote_image返回结果中errors[].code错误码,如果值为NOT_FOUND即视为不存在;
remote_image_code=$(echo "${remote_image}" | jq -r '.errors[].code' 2>/dev/null)

#【校验2】解析remote_image返回结果中tags[].id数据ID,如果值小于0即视为不存在;
image_id=$(echo "${remote_image}" | jq -r '.tags[].id' 2>/dev/null)

if [[ $remote_image_code == "NOT_FOUND" || ${image_id} -le 0 ]]; then
    echo "镜像资源不存在"
else
    #服务部署逻辑
fi 

进行远程自动化部署

这一步需要连接到远程主机将相应的脚本和文件同步到远程之后再执行自动化容器部署;

  • 通过ssh连接到远程:ssh -i xxx.pem user@host -p
  • 将本地的部署脚本同步到远程:‘bash -s’ < /path/remote_deploy.sh并传入构建过程必要的参数
#动态获取服务版本号
source "${project_dir}/server_port.sh" "${project_dir}/${service}" "${env}" "${project_dir}"

ssh -i ${JENKINS_DEPLOY_HOME}/certificates/deploy-${env}.pem ${ssh_user}@${ssh_host} -p ${ssh_port} 'bash -s' < ${JENKINS_DEPLOY_HOME}/remote_deploy.sh "${last_element}" "
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。