Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(四):发布与回滚

写在前面

我们以前windows跑.net Framework程序的时候,发布,自己乖乖的替换程序;备份,也是自己一个一个的重命名备份;回滚,发布遇到问题的回滚更是不用说了;运维很是怕我们 这些用windows的啊;

那全面拥抱linux的一一.net core 时代 ,是如何处理这些个问题的呢?

噔噔蹬蹬~请往下看。

运行环境

centos:7.2
cpu:1核 2G内存 1M带宽

Jenkins ver. 2.150.1

一台安装jenkins的机器。

(本文例子不一定要安装jenkins,但实际项目是要用jenkins的)

背景

我们目前的应用部署环境是这样划分的(暂定):

开发环境

环境变量:Development

开发环境就是我们平时的开发用的机器,错误、异常尽可能多的报出来这种。css、js、页面文件等各种静态资源也不做压缩处理,连接测试库;

开发环境的部署:开发人员按自己习惯自己部署;

测试环境

环境变量:Staging

测试环境也就是测试同学测试用的环境,为了贴合生产环境的多机器部署,我们测试机器也有多台,目前我们搭建了jenkins可由测试同学自己部署;错误信息已做捕捉处理,静态文件同样不压缩,连接测试库;

测试环境的部署:docker+docker-compose部署,我们在项目里面编写好了Staging.Dockerfile、docker-compose.yml还有对应的测试环境发布的shell脚本,借助jenkins来进行参数化的构建。参数包括程序运行的端口、绑定的ip,consul配置等等。哦对了,我们目前的构建步骤大概是:

  1. 去gitlab拉取最新程序代码;
  2. 执行单元测试和集成测试,只有通过单元测试和集成测试才能继续步骤3,否则部署失败终止
  3. dotnet restore->build->publish,将生成产品打包成一个镜像;
  4. 使用docker-compose down 停止、移除上次的构建;
  5. 使用docker-compose up 这个强大的命令,构建新的镜像、启动容器;
  6. 清除临时镜像,构建完成;

单元测试用dotnet test 命令;

这里我们还可以看到,配置文件也一并被打包到镜像里面了,修改配置文件也需要重新构建的;

预生产环境

环境变量:Staging

预生产环境是相对于测试环境来说,无论数据、配置还是架构都是更加接近生产环境的存在了。一般还是连接的数据库是预生产环境的数据库(同步了生产环境的数据的),甚至有的使用会直接连接生产环境的库(一般不练、只读账号等控制);不过我们公司还是连接的测试库

然后静态文件压缩啊、什么的这些,生产环境怎么处理,这里也怎么处理;

通过测试环境测试的程序才可以部署到这里,这里测试通过后,才可以部署到生产环境;

预生产环境的部署:由项目负责人或者运维部署,需要比较大权限才可以;

生产环境

环境变量:Production

生产环境一般应配置为最大限度地提高安全性、性能和应用可靠性,包括但不限于以下举措:

  1. 全面启用分布式缓存
  2. 客户端资源被捆绑和缩小,并可能从 CDN (网络分发)提供。
  3. 必须禁用诊断错误页。
  4. 启用友好错误页、一致的错误响应。
  5. 启用生产记录和监视。

生产环境的部署:运维部署,我们开发没有权限了;

部署的背景我们的条件等等大概讲完了,下面我们说说生产环境我们怎么设计容器的。

生产环境的容器设计

由于生产环境经常需要修改配置、保留日志信息、需考虑程序的备份与回滚等等,我们不能像上面的测试环境一样,把整个发布的产品打包成一个镜像了,我们需要做特殊的处理;

熟悉docker的同学,肯定会想到:挂载

对的,我们就这么处理,我们用docker -v 处理这头痛的问题;

程序的目录结构

我们程序的目录结构是这样的:

backs:放历史版本的程序文件,按备份日期压缩命名;

logs:程序的运行日志文件;

program:当前运行的程序;

logs 和 program 目录,使用 docker -v 挂载;

backs目录截图:

发布

发布步骤

  1. 同步通过测试的预生产环境的程序文件;
  2. 压缩、备份上一版本的程序文件;
  3. 通过更改文件夹名称的方式,当前运行程序替换为最新的;
  4. 重启程序;
  5. 心跳检测:通过输出部署成功,未通过执行回滚操作。

发布脚本(Production.Publish.sh)

#!/bin/bash

function success()
{
  echo -e "\033[32m $1 \033[0m"
}
function error()
{
   echo -e "\033[31m\033[01m $1 \033[0m"
}

echo "publish beging。。。。。。"
remotePath=$1
healthCheckUrl=$2
defaulPaht= $3;
bashPath=${defaulPaht:=`pwd`}

if [ ! $remotePath ]; then
    echo "warn:remotePath should't be empty!"
    exit
fi

if [ ! $bashPath ]; then
    error "error:bashPath should't  be empty!"
    exit
fi
echo "bashpath is ${bashPath}"
programPath="${bashPath}/program"
logPath="${bashPath}/logs"
backPath="${bashPath}/backs"
publisTemp="${bashPath}/publisTemp"
mkdir -p $programPath
mkdir -p $logPath
mkdir -p $backPath
mkdir -p $publisTemp

#remote git or scp
#这里同步预生产环境的程序文件,这里写死了ip只是示例,scp也只是示例
#大家可以采用更安全,更有效率的同步文件方式
scp -r  root@139.199.196.67:${remotePath}"/.*"  ${publisTemp}

if [ $? ]; then
    echo "info:copy successful!"
    #压缩、备份当前运行程序到backs文件夹
    backFileName=`date +%Y%m%d%H%M%S`".tar.gz"
    `cd ${programPath} && tar -zcPf ${backPath}/${backFileName} *`  

    #replace
    #替换程序
    if [ $? ]; then
        mv $programPath ${programPath}"Old"
        mv $publisTemp ${programPath}
        rm -r ${programPath}"Old"

        #publis fail ,then Production.Rollback
        if [ $healthCheckUrl ]; then
            curl $healthCheckUrl
            if [ $? -ne 0 ]; then
                error "error:public failed!"
                #心跳检测失败,执行回滚
                if [ -f "Production.Rollback.sh" ];then
                    echo "************************************ exec Rollbacking...... ************************************"
                    ./Production.Rollback.sh ${backPath}
                else
                    error "error:Production.Rollback.sh is not existing!";
                fi
                exit
            fi
        fi
        success "publish Successful!"
    else
        error "error:file tar failed!"
    fi
else
    error "error:remote files copy failed,Maybe you should checkout your ssh auth!"
fi 

Dockerfile

Dockerfile比较简单

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
ARG RUN_PORT=${RUN_PORT:-""}
ARG CONSUL_TO_NETCOREHOST=${CONSUL_TO_NETCOREHOST:-""}
ARG ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-""}
ENV RUN_PORT=${RUN_PORT} CONSUL_TO_NETCOREHOST=${CONSUL_TO_NETCOREHOST} ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
ENTRYPOINT ["dotnet", "Member.WebApi.dll"]

docker-compose

version: '3.4'

services:
  member.webapi:
    image: memberwebapi${RUN_PORT}
    build:
      context: .
      dockerfile: ${ASPNETCORE_ENVIRONMENT}.Dockerfile
    network_mode: "host"
    restart: always

    environment:
      - RUN_PORT=${RUN_PORT}
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
      - CONSUL_TO_NETCOREHOST=${CONSUL_TO_NETCOREHOST}

    command:
      - "--port"
      - "${RUN_PORT}"

    #就是这里挂载
    volumes:
      - ../program/:/app/
      - ../logs/:/app/logs

回滚

回滚其实就是发布的逆操作;

发布是:同步最新程序->备份当前运行程序->替换;

回滚是->找到上一次的备份->删掉的当前运行程序->替换;

Production.Rollback.sh

#!/bin/bash

echo "rollback beging。。。。。。"
defaulPaht= $1;
bashPath=${defaulPaht:=`pwd`}
programPath="${bashPath}/program"
backPath="${bashPath}/backs"
lastFile=`cd ${backPath} &&ls -t |head -n1|awk '{print $0}'`

if [ ! $lastFile ];then
    echo "error:none backup program!"
fi

lastFilePath="${backPath}/${lastFile}"
echo $lastFilePath
if [ -f $lastFilePath ];then
    echo "rollback program:${lastFilePath}"
    programOldPath="${programPath}Old"
    mkdir -p ${programOldPath}
    tar zxvf ${lastFilePath} -C ${programOldPath}

    #replace
    if [ $? ]; then
        rm -r ${programPath}
        mv ${programOldPath} ${programPath}
        echo  "rollback Successful!"
    else
        echo "error:backup program is not existing!"
    fi
else
    echo "error:backup program is not existing!"
fi

最后贴一个运行截图:

总结

毫不夸张地说,Jenkins + Dockor 让.net 完全从一个刀耕火种的原始人一下子穿越到了全自动化的现代;

文章的思路可以借鉴,脚本改改也可以用,但需理解思路;

有的同学可能会问,为什么生产环境的部署,不能像测试环境一样直接拉取master的代码构建,我这里的回答是涉及到配置的权限问题、devops的学习到位问题。历史原因等,我们暂定这样,后面实践,我乐于分享;

本文的实践都有很大的局限性,比如有现成的工具、有更强大的插件等等可以更简单的去解决这个问题之类的,我可能还不知道;比如我的shell写的一塌糊涂等等。。欢迎沟通,不理赐教。

晚安~

原文地址:https://www.cnblogs.com/xiaxiaolu/p/10468612.html

时间: 2024-10-06 17:05:37

Asp.net Core 使用Jenkins + Dockor 实现持续集成、自动化部署(四):发布与回滚的相关文章

Jenkins从零开始搭建持续集成+自动化部署详细说明

说明:该说明文档的案例是:在windows上部署Jenkins服务,最终将持续集成的war包自动部署到远程服务器(Centos 7)上. 一.Jenkins安装 1. Jenkins下载地址:https://jenkins.io/download/,如图,我现在的是windows版本的: 2. 下载之后,解压点击msi文件运行,如图: 3. 我已经安装过一次了,这儿就不详细描述,安装教程请参考百度经验:https://jingyan.baidu.com/article/cbcede077f62b

持续集成+自动化部署[代码流水线管理及Jenkins和gitlab集成]

持续集成+自动化部署[代码流水线管理及Jenkins和gitlab集成] 标签(空格分隔): Jenkins 一.代码流水线管理 Pipeline名词顾名思义就是流水线的意思,因为公司可能会有很多项目.如果使用jenkins构建完成后,开发构建项目需要一项一项点击,比较麻烦.所以出现pipeline名词. 代码质量检查完毕之后,我们需要将代码部署到测试环境上去,进行自动化测试 新建部署代码项目 点击新建 这里只需要写一下描述 执行Shell脚本 温馨提示:执行命令主要涉及的是权限问题,我们要搞明

Linux-GitLab+Jenkins持续集成+自动化部署

GitLab+Jenkins持续集成+自动化部署 什么是持续集成? (1)Continuous integration (CI) 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过自动化的构建(包括编译.发布.自动化测试)来验证,从而尽快地发现集成错误.许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件. (2)没有持续集成 项目做模块集成的时候,发现很多接口都不通==>浪费大量时间 需

Jenkins+SVN+Maven持续集成一键部署环境

一.jenkins介绍 Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作. Jenkins拥有的特性: a. 易于安装:只要把jenkins.war部署到servlet容器,不需要数据库的支持. b. 易于配置:所有配置都是通过其提供的web界面实现. c. 集成RSS/E-mail通过RSS发布构建结果或当构建完成时通过e-mail通知. d. 生成JUnit/TestNG测试报告. e. 分

jenkins + Git 搭建持续集成环境

jenkins + Git 搭建持续集成环境 持续集成通过自动化构建.自动化测试以及自动化部署加上较高的集成频率保证了开发系统中的问题能迅速被发现和修复,降低了集成失败的风险,使得系统在开发中始终保持在一个稳定健康的集成状态.jenkins是目前广泛应用的持续集成工具,本文记录我使用jenkins+Git配置持续集成环境的整个流程以及踩到的坑(jenkins过程的坑往往不是在第一次配置,而是在配置结束后更改某些配置项的时候踩到). 总体流程如下: tomcat8.0下载地址:http://tom

基于 Jenkins 快速搭建持续集成环境

持续集成是一种软件开发实践,对于提高软件开发效率并保障软件开发质量提供了理论基础.Jenkins 是一个开源软件项目,旨在提供一个开放易用的软件平台,使持续集成变成可能.本文正是从持续集成的基本概念入手,通过具体实例,介绍了如何基于 Jenkins 快速搭建持续集成环境. 持续集成概述 什么是持续集成 随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题.尤其是近些年来,敏捷(Agile) 在软件工程领域越来越红火,如何能再不断变

CentOS6.8 部署Tomcat+jenkins+git+maven 持续集成

CentOS6.8 部署Tomcat+jenkins+git+maven 持续集成 一.环境介绍: 1.操作系统:CentOS 6.8  IP:192.168.1.100 2.JDK版本:jdk1.8.0_101 3.Tomcat版本:tomcat-9.0.0.M21 4.jenkins版本: Jenkins ver. 2.46.3 5.git版本:git version 2.9.4 6.maven版本:3.5.0 二.环境部署 1.下载所需软件包 # mkdir /tmp/soft ; cd

Linux下Jenkins+git+gradle 持续集成环境搭建

一.项目介绍 和 linux 环境搭建 本教程讲解 Linux下Jenkins+git+gradle 持续集成环境搭建,后续会加入 gerrit代码审核 和 robotium自动化测试 1.基本流程如下: androidstudio--  gerrit  --- git(github)   ----jenkins ---gradle ----  robotium  结果 使用AndroidStudio 开发,提交到gerrit进行代码审核,审核后提交给git(可以自己搭建git服务也可以使用gi

构建基于Jenkins + Github的持续集成环境

搭建持续集成首先要了解什么是持续集成,带着明确的目标去搭建持续集成环境才能让我们少走很多弯路.持续集成(Continuous integration)简称CI,是一种软件开发的实践,可以让团队在持续集成的基础上收到反馈并加以改进,不必等到开发的后期才寻找和修复缺陷.当然要明白的是持续集成环境的搭建也不是一劳永逸的,随着软件项目复杂度的增加,持续集成的环境同样要加以维护以确保集成环境的可靠性. 持续集成的重要要素:1.统一的代码库. 2.CI服务器 3.自动化测试和构建的脚本 4.Slaves 持