1. 程式人生 > >自動化部署(二)

自動化部署(二)

自動化部署腳本

2 自動化部署流程設計

2.1 需求分解

一個集群有10個節點:

  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

自動化部署(二)