持續集成與自動化部署 - 自動化部署流程設計(二)

2 自動化部署流程設計

2.1 需求分解

一個集羣有10個節點:html

  1. 一鍵部署10個節點。
  2. 一鍵回滾到任意版本。
  3. 一鍵回滾到上個版本。

2.2 部署流程分解

2.2.1 準備

  1. 代碼放在哪裏? git/svn
  2. 獲取什麼版本的代碼?
    svn: 指定版本號
    git: 指定tag
  3. 差別解決:
    • 各個節點的配置文件差別:列如crontab.xml 只須要由一臺機器來執行或者是預生產節點和生產節點的配置文件有差別。
    • 代碼倉庫和實際的差別,配置文件是放在代碼倉庫中。
  4. 如何更新?tomcat 部署事後須要重啓。
  5. 測試。
  6. 串行部署仍是並行部署。
  7. 如何執行?shell仍是web界面。

2.2.2 上線流程

  1. 獲取代碼(直接拉取)
  2. 編譯(可選,java代碼須要編譯)
  3. 替換配置文件》
  4. 打包
  5. scp到指定的服務器
  6. 將目標服務器移除集羣
  7. 解壓
  8. 放置到webroot
  9. scp差別文件
  10. 重啓應用(可選,tomcat須要重啓)
  11. 測試
  12. 加入集羣

2.2.3 回滾流程 - 普通流程

  1. 列出回滾的腳本
  2. 將目標服務器從集羣中移除
  3. 執行回滾版本
  4. 重啓和測試
  5. 加入集羣

2.2.4 回滾流程 - 緊急流程

  1. 列出回滾版本
  2. 執行回滾
  3. 重啓

2.2.5 回滾流程 - 最

  1. 回滾上個版本
  2. 重啓

2.3 部署腳本

2.3.1 部署準備

  1. 全部的web服務都應該使用普通用戶運行。(用root用戶運行web服務,系統若是被黑,那就無法玩了。)
  2. 全部的web服務都不該該監聽80端口,負載均衡器除外。

2.3.1 部署腳本內容

#!/bin/bash

#NODE LIST
NODE_LIST="10.0.0.205 10.0.0.203"

# 生產中有預熱節點,通常預熱節點爲一臺。
PRE_LIST="10.0.0.203"
GROUP2_LIST="10.0.0.205"
ROLLBACK_LIST="10.0.0.205 10.0.0.203"

# Date/Time variables
LOG_DATE='date +"%Y-%m-%d"'
LOG_TIME='date +"%H-%M-%S"'

CDATE=$(date +"%Y-%m-%d")
CTIME=$(date +"%H-%M-%S")

# shell env
SHELL_NAME="deploy.sh"
SHELL_DIR="/home/www"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"

# CODE ENV
PRO_NAME="web_demo"
CODE_DIR="/deploy/code/${PRO_NAME}"
CONFIG_DIR="/deploy/config/${PRO_NAME}"
TMP_DIR="/deploy/tmp"
TAR_DIR="deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

# FUNCTION

url_test(){
    URL=$1
    curl -s -I "$URL"|grep '200 OK'
    if [ $? -ne 0 ];then
        shell_unlock;
        writelog "test error" && exit
    fi
}

usage(){
    echo "usage: $0 { deploy | rollback [list | version]}"
}

writelog(){
    LOGINFO=$1
    echo "${CDATE} ${CTIME}: ${SHELL_NAME} :${LOGINFO}" >> ${SHELL_LOG}

}

shell_lock(){
    touch ${LOCK_FILE} 

}

shell_unlock(){
    rm -f $LOCK_FILE
}

code_get(){
    writelog 'code_get';
    # $CODE_DIR目錄下只能進行git pull
    cd $CODE_DIR && git pull
    # git pull 以後就copy走
    cp -r ${CODE_DIR} ${TMP_DIR}/
    # 定義版本號,下面的PKG_NAME須要用到。
    API_VER=`git show|grep commit|cut -d " " -f 2|head -c 6`
}

code_build(){
echo code_build

}

code_config(){
    writelog  code_config
    # 加 -r 參數 ,覆蓋原來的老文件。
    # 這裏爲何是/bin/cp ??  後面爲何加「」
    /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}"
    PKG_NAME="${PRO_NAME}"_"$API_VER"_"${CDATE}-${CTIME}"   
    cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}
}

code_tar(){
    writelog "code_tar"
    cd ${TMP_DIR} && tar -cf ${PKG_NAME}.tar.gz $PKG_NAME
}

code_scp(){
    writelog "code_scp"
    for  node in $NODE_LIST
    do
        # /opt/webroot 目錄要存在
        scp -P52113 ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot
    done
}

cluster_node_remove(){
    writelog "cluster_node_remove"
}

pre_deploy(){
# 先上預熱節點,當他測試沒問題的時候再接着上下面的節點。

    writelog 'remove from cluster'
    ssh -p52113 ${PRE_LIST} "cd  /opt/webroot && tar xf ${PKG_NAME}.tar.gz"   
    ssh -p52113 ${PRE_LIST} "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
}

pre_test(){
    url_test http://${PRE_LIST}/index.html
}

group2_deploy(){
# 包含
        writelog 'remove from cluster.'
        for node in $GROUP2_LIST
        do
                ssh -p52113 $node "cd  /opt/webroot && tar xf ${PKG_NAME}.tar.gz"
                ssh -p52113 $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
        done
        # 差別配置文件,應該放到最後去完成。若是軟鏈接沒完成,而配置文件拷貝過去就尷尬了。
        scp -P52113 ${CONFIG_DIR}/other/10.0.0.205.crontab.xml 10.0.0.205:/webroot/web-demo/crontab.xml
}

group2_test(){
    for node in $GROUP2_LIST
    do
        url_test http://${node}/index.html
    done
}

cluster_node_in(){
    echo cluster_node_in
}

rollback_fun(){
    ROLLBACK_VER=$1
    for node in $ROLLBACK_LIST
    do
        ssh -p52113 $node "[ -d /opt/webroot/"$ROLLBACK_VER" ] && rm -f /webroot/web-demo && ln -s /opt/webroot/${ROLLBACK_VER} /webroot/web-demo || echo rollback failed."
    done
}

rollback(){
    ROLLBACK_VER=$1
    [ -z "$ROLLBACK_VER" ] && echo "exit! no version." && shell_unlock && exit

    case $ROLLBACK_VER in
    list)
        #ssh -p52113 10.0.0.203 'ls -l /opt/webroot/*.tar.gz |awk -F "[/.]" "{print $(NF-2)}"'
        ssh -p52113 10.0.0.203 "find /opt/webroot/ -maxdepth 1 -type d|cut -d "/" -f 4"
        ;;
    *)
        rollback_fun $ROLLBACK_VER          
    esac
}

main(){
    # 進程鎖
    [ -f "$LOCK_FILE" ] && echo "deploy is running " && exit
    DEPLOY_METHOD=$1
    ROLLBACK_VER=$2
    case $DEPLOY_METHOD in
      deploy)
        shell_lock;
        code_get;
        code_build;
        code_config;
        code_tar;
        code_scp;
        cluster_node_remove;
        pre_deploy;
        pre_test;
        group2_deploy;
        group2_test;
        cluster_node_in;
        shell_unlock;
        ;;
      rollback)
        shell_lock;
        rollback $ROLLBACK_VER;
        shell_unlock;
        ;;
      *)
        usage;
    esac

}

# $1: deploy | rollback
# $2: rollback version

main $1 $2
相關文章
相關標籤/搜索