百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Jenkins+Docker+git实现多环境快速交付-compose优化升级

bigegpt 2024-10-03 14:55 3 浏览


Jenkins+Docker+git多分支实现springboot项目多环境快速交付一文我们介绍了CI/CD交付springboot项目过程中的环境校验发版/回滚/重启、操作校验等步骤,在实际应用过程中有几点思考:

  1. 构建前的运行参数定义

构建前我们只按规范定义了APP_NAME(项目名)、IMAGE_NAME(镜像名)、MONITOR_URL(健康检查URL),相关的JVM参数、端口映射等与实际运行的参数仍然需要在后续的容器运行时手动修改,增加了配置难度,因此我们考虑将其提取到环境变量统一设置,以降低出问题的概率。

  1. 繁琐的pull/start/stop/rm操作


在构建过程中需要在远程服务器上频繁的docker pull/start/stop/rm等操作来更新镜像,有没有更好的方式来简化这些操作,来让整个过程更加简洁。因此,我们使用容器编排工具docker-compose来更新镜像、管理容器

以上两点是本文重点解决的问题,我们使用docker-compose+环境变量来实现下。

docker-compose配置

  1. compose模板文件
version: '3.7'
services:
  helloworld:
    image: harbor.test.cn/${IMAGE_NAME}:${VERSION}
    container_name: ${CONTAINER_NAME}
    restart: always
    environment:
      - JAVA_OPTS=${JAVA_OPTS}
    ports:
      - $PORT
    volumes:
      - /App/java_app/${APP_NAME}/logs:/logs
    healthcheck:
      test: ["CMD", "curl", "-fs", "$MONITOR_URL"]
      interval: 8s
      timeout: 10s
      retries: 3

我们主要提取了以下几个变量:

镜像名:${IMAGE_NAME}

镜像tag:${VERSION},用于版本回滚

容器名:${CONTAINER_NAME}

JVM参数:${JAVA_OPTS}

端口映射:${PORT}

项目名:${APP_NAME}

健康检查URL:${MONITOR_URL}

其中:镜像tag是我们在回滚时需要输入的参数,其他都是构建前根据实际情况插入到全局环境变量中。

  1. .env环境变量配置文件

docker-compose默认使用同级目录下的.env文件作为环境变量配置文件,借助此文件我们可以在构建前将jenkins中的全局环境变量写入此文件,以便docker-compose使用。

#vim .env
IMAGE_NAME=helloworld/helloworld
CONTAINER_NAME=helloworld
APP_NAME=helloworld
MONITOR_URL=http://127.0.0.1:8080
PORT=9080:8080
JAVA_OPTS=-Xmx129m -Xms129m -Dspring.profiles.active=test
VERSION=5f06985aa4ed91a417ecd9b02abddb6efdbfd1b5
  1. 更新镜像并启动容器

每次构建前修改.env文件后,我们可以通过docker-compose来pull指定的镜像并启动容器了。

docker-compose up -d --build

通过--build参数,在启动容器前,都会更新使用的镜像。

优化实现(加粗处是优化点)

  1. jenkins新建自由风格的job,名称为docker-test-helloworld
  2. 参数化构建
  1. 插入全局环境变量及设置Build Name
APP_NAME=helloworld
IMAGE_NAME=helloworld/helloworld
MONITOR_URL="http://127.0.0.1:8080"
JAVA_OPTS="-Xmx129m -Xms129m -Dspring.profiles.active=$(echo ${JOB_NAME}|awk -F'-' '{print $2}')"
PORT=9080:8080

以上是插入的全局环境变量,整个项目我们只需在此处集中修改,以减少配置错误为目的。

  1. Build-环境校验、操作校验

Build过程主要进行环境校验、操作校验操作,用于

(1)环境校验,判断git分支与当前job-test/prod是否一致,不一致则停止后续发版操作;

(2)操作校验

发版:git对应分支是否有更新,防止在没有更新时构建多次,导致应用多次重启;

主要利用jenkins内置变量:

GIT_PREVIOUS_SUCCESSFUL_COMMIT 上次构建成功后的git版本号

GIT_COMMIT 当前构建任务的git版本号

回滚:判断远程分支是否有与参数匹配的版本号,没有则说明不合法,停止回滚;

代码如下:

#!/bin/bash
CHECK_ENV(){
#判断git分支是否与项目匹配,避免环境与项目混用
ENV=`echo ${JOB_NAME}|awk -F'-' '{print $2}'`
#测试分支develop,生产分支master
BRANCH=${GIT_BRANCH}
if [ $BRANCH = "origin/develop" ];then 
    [ $ENV="test" ] &&  echo -e "\033[34m$ENV environment is in building \033[0m" || {
        echo -e "\033[31m git branch is $BRANCH, not match environment $ENV \033[0m"
        exit 1
    }
else
    echo -e "\033[31m git branch is $BRANCH, not match environment $ENV \033[0m"
    exit 1
fi
}

#环境校验
CHECK_ENV


#操作校验
if [ "${deploy_env}" = "deploy" ];then
    echo -e "\033[34mstart ${deploy_env}\033[0m"
    echo ${GIT_PREVIOUS_SUCCESSFUL_COMMIT}
    echo ${GIT_COMMIT}
    [ "${GIT_PREVIOUS_SUCCESSFUL_COMMIT}" != "${GIT_COMMIT}" ] && echo -e "\033[34mstart maven package\033[0m" || {
        #版本未更新,停止发版
        echo -e "\033[31mRepositories not update, stop ${deploy_env}\033[0m"
        exit 1
    }
      
    /usr/local/maven/bin/mvn clean package docker:build -DdockerImageTags=${GIT_COMMIT} -Dmaven.test.skip=true -DpushImageTag
    [ $? -eq 0 ] && echo -e "\033[32mmaven package success\033[0m" || {
    	echo -e "\033[31mmaven package fail\033[0m"
    	exit 1
    } 
elif [ "${deploy_env}" = "rollback" ];then
    echo -e "\033[34mstart ${deploy_env}\033[0m"
    echo ${GIT_PREVIOUS_SUCCESSFUL_COMMIT}
    echo ${GIT_COMMIT}
    #查看远程分支是否有此版本
    git branch -r --contains $version
    [ $? -eq 0 ] && echo -e "\033[34mstart docker steps\033[0m" || {
        echo -e "\033[31mverison is wrong,please check version\033[0m"
        exit 1
    }
fi
  1. Build-远程服务器构建

通过“SSH Publishers”插件登录远程服务器执行docker相关操作

#!/bin/bash
IN_FACE=`/sbin/route -n |awk '{if($4~/UG/){print $8}}'|head -n 1`
LOCAL_IP=`/sbin/ip addr show "${IN_FACE}" | grep -w 'inet' | awk '{print $2}'`

CONTAINER_NAME=`echo ${IMAGE_NAME} | awk -F/ '{print $2}'`
#ENV=`echo ${JOB_NAME}|awk -F'-' '{print $2}'`

#删除老镜像
DEL_IMAGE() {
    echo -e "\033[34mrm image ${IMAGE_NAME}:$1\033[0m"
    sudo docker image rm harbor.test.cn/${IMAGE_NAME}:$1  --no-prune
    [ $? -eq 0 ] && echo -e "\033[32mrm ${IMAGE_NAME}:$1 succss \033[0m" || { 
        echo -e "\033[31mrm ${IMAGE_NAME}:$1 fail \033[0m"
        exit 1
    }
}

#健康检查
HEALTHCHECK() {
    timeout=180
    echo -e "\033[34mhealth check\033[0m"
    for (( i=1;i<=$timeout;i++ ))
    do
        status=$(sudo docker inspect --format='{{json .State.Health}}' ${CONTAINER_NAME}|grep -Po '"Status[":]+\K[^"]+')
        echo $status
        if [ $status = 'healthy' ];then
           echo -e "\033[32m${LOCAL_IP} ${CONTAINER_NAME}  status is ${status}\033[0m"
           DEL_IMAGE ${OLD_VERSION}
           exit 0
        elif [ $status = 'starting' ];then
           sleep 23
        else
           echo -e "\033[31m${LOCAL_IP} ${CONTAINER_NAME} status is ${status}\033[0m"  
           exit 1  
        fi
    done
}


#定义docker-compose变量,注意第一步清空env,后续追加env
INIT_VAR() {
    echo -e "\033[34minit docker-compose variable\033[0m"
    echo "IMAGE_NAME=${IMAGE_NAME}" > .env
    echo "CONTAINER_NAME=${CONTAINER_NAME}" >> .env
    echo "APP_NAME=${APP_NAME}" >> .env
    echo "ENV=${ENV}" >> .env
    echo "MONITOR_URL=${MONITOR_URL}" >> .env
    echo "PORT=${PORT}" >> .env
    echo "JAVA_OPTS=${JAVA_OPTS}" >> .env
}

#进入项目目录
cd /App/java_app_tmp/${APP_NAME}
#提前读取env文件中的老版本号,用于删除老镜像
OLD_VERSION=$(grep VERSION .env|awk -F= '{print $2}')
echo $OLD_VERSION

case ${deploy_env} in
deploy)
    echo -e "\033[34mstart ${deploy_env} steps\033[0m"
    INIT_VAR
    echo "VERSION=${GIT_COMMIT}" >> .env
    sudo docker-compose up -d --build
    HEALTHCHECK
    ;;
rollback)
    echo -e "\033[34mstart ${deploy_env} steps\033[0m"
    INIT_VAR
    echo "VERSION=${version}" >> .env
    sudo docker-compose up -d --build
    HEALTHCHECK
    ;;
restart)
    sudo docker-compose restart
    HEALTHCHECK
    ;;
*)
    exit 1
    ;;
esac

通过docker-compose将之前的pull/stop/rm/start等一系列的docker操作全部用"docker-compose up -d --build"代替,大大简化了代码。

注意:每次构建前通过">"清除.env文件并重启添加,之所以保留便于我们排查问题。

  1. Post-build Actions
#删除jenkins slave服务上的虚悬镜像
echo -e "\033[34mrm old image on jenkins slave\033[0m"
if [ $(docker image ls harbor.test.cn/${IMAGE_NAME} -q|wc -l) -ne 0 ];then 
   docker image rm `docker image ls harbor.test.cn/${IMAGE_NAME} -q` -f --no-prune
fi
docker image prune -f

删除jenkins slave服务上新构建的镜像及虚悬镜像,保持slave上的环境纯净。


通过以上步骤我们只在第3、5步配合docker-compose做了优化,其他不变仍可参考Jenkins+Docker+git多分支实现springboot项目多环境快速交付


总结

本文之所以是优化升级,因为在配置过程中提高可读性、集中配置、简化操作可以有效的减少出错的概率,另外在DevOps中交付的效率问题也是非常重要的一个环节。

最重要的是目前的Docker实践我们需要一步一个脚印的走过来,在这过程中要不断的思考、总结。


我是【木讷大叔爱运维】,欢迎关注,与你分享运维路上的点点滴滴。

相关推荐

有些人能留在你的心里,但不能留在你生活里。

有时候,你必须要明白,有些人能留在你的心里,但不能留在你生活里。Sometimes,youhavetorealize,Somepeoplecanstayinyourheart,...

Python学不会来打我(34)python函数爬取百度图片_附源码

随着人工智能和大数据的发展,图像数据的获取变得越来越重要。作为Python初学者,掌握如何从网页中抓取图片并保存到本地是一项非常实用的技能。本文将手把手教你使用Python函数编写一个简单的百度图片...

软网推荐:图像变变变 一“软”见分晓

当我们仅需要改变一些图片的分辨率、裁减尺寸、添加水印、标注文本、更改图片颜色,或将一种图片转换为另一种格式时,总比较讨厌使用一些大型的图像处理软件,尤其是当尚未安装此类软件时,更是如此。实际上,只需一...

首款WP8.1图片搜索应用,搜照片得资料

首款WP8.1图片搜索应用,搜照片得资料出处:IT之家原创(天际)2014-11-1114:32:15评论WP之家报道,《反向图片搜索》(ReverseImageSearch)是Window...

分享一组美图(图片来自头条)(头条美女头像)

...

盗墓笔记电视剧精美海报 盗墓笔记电视剧全集高清种子下载

出身“老九门”世家的吴邪,因身为考古学家的父母在某次保护国家文物行动时被国外盗墓团伙杀害,吴家为保护吴邪安全将他送去德国读书,因而吴邪对“考古”事业有着与生俱来的兴趣。在一次护宝过程中他偶然获得一张...

微软调整Win11 24H2装机策略:6月起36款预装应用改为完整版

IT之家7月16日消息,微软公司今天(7月16日)发布公告,表示自今年6月更新开始,已默认更新Windows1124H2和WindowsServer2025系统中预装...

谷歌手把手教你成为谣言终结者 | 域外

刺猬公社出品,必属原创,严禁转载。合作事宜,请联系微信号:yunlugongby贾宸琰编译、整理11月23日,由谷歌新闻实验室(GoogleNewsLab)联合Bellingcat、DigD...

NAS 部署网盘资源搜索神器:全网资源一键搜,免费看剧听歌超爽!

还在为找不到想看的电影、电视剧、音乐而烦恼?还在各个网盘之间来回切换,浪费大量时间?今天就教你如何在NAS上部署aipan-netdisk-search,一款强大的网盘资源搜索神器,让你全网资源...

使用 Docker Compose 简化 INFINI Console 与 Easysearch 环境搭建

前言回顾在上一篇文章《搭建持久化的INFINIConsole与Easysearch容器环境》中,我们详细介绍了如何使用基础的dockerrun命令,手动启动和配置INFINICon...

为庆祝杜特尔特到访,这个国家宣布全国放假?

(观察者网讯)近日,一篇流传甚广的脸书推文称,为庆祝杜特尔特去年访问印度,印度宣布全国放假,并举办了街头集会以示欢迎。菲媒对此做出澄清,这则消息其实是“假新闻”。据《菲律宾世界日报》2日报道,该贴子...

一课译词:毛骨悚然(毛骨悚然的意思是?)

PhotobyMoosePhotosfromPexels“毛骨悚然”,汉语成语,意思是毛发竖起,脊梁骨发冷;形容恐惧惊骇的样子(withone'shairstandingonend...

Bing Overtakes Google in China&#39;s PC Search Market, Fueled by AI and Microsoft Ecosystem

ScreenshotofBingChinahomepageTMTPOST--Inastunningturnintheglobalsearchenginerace,Mic...

找图不求人!6个以图搜图的识图网站推荐

【本文由小黑盒作者@crystalz于03月08日发布,转载请标明出处!】前言以图搜图,专业说法叫“反向图片搜索引擎”,是专门用来搜索相似图片、原始图片或图片来源的方法。常用来寻找现有图片的原始发布出...

浏览器功能和“油管”有什么关联?为什么要下载

现在有没有一款插件可以实现全部的功能,同时占用又小呢,主题主要是网站的一个外观,而且插件则主要是实现wordpress网站的一些功能,它不仅仅可以定制网站的外观,还可以实现很多插件的功能,搭载chro...