運維與自動化系列④自動化部署基礎與git

運維與自動化系列④自動化部署基礎與githtml

自動化部署基礎與git前端

一:上一篇的代碼是保存在本地,可是在生產環境當中是由版本控制進行代碼管理,以便於發佈代碼和回滾,通常是使用gitlib比較多,另外還有用svn的公司,趨勢是git爲主,所以本文以git爲使用對象node

1.1:在git服務器新建一個web組和項目web-demo:git

準備web頁面並提交至git服務器(此處我用一個簡單的html項目,你們若是沒有現成的項目能夠本身建一個簡單的index.html頁面便可):
#準備提交代碼目錄web

# mkdir /source/web/web-demo -p

# 準備一個項目而後提交至git服務器
將項目上傳到/source/web/web-demo目錄shell

[www@master web-demo]$ pwd
/source/web/web-demo
[www@master web-demo]$ ll
total 20
drwxr-xr-x 6 www www 4096 Jun 6 13:46 assets
-rw-r--r-- 1 www www 1150 Jun 6 17:59 favicon.ico
drwxr-xr-x 2 www www 4096 Jun 6 15:32 images
-rw-r--r-- 1 www www 4323 Jun 6 16:19 index.html
# chown -R www.www /source
# su - www
cd /source/web

git config --global user.name "reblue520"
git config --global user.email "reblue520@163.com"
git config --global color.ui true
cd /source/web/web-demo
git init
git add *
git commit -m 'web-demo all'
git remote add origin git@192.168.3.198:web/web-demo.git
git push -u origin master # 確認代碼提交成功

 

1.2:使用ssh key受權www用戶能夠更新和提交代碼:vim

#在admin area–web-demo-profile settings-ssh keys將www用戶的公鑰放在gitlab的web界面:

[www@master ~]$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArALvWj9fYnDtZxOue7OXvznI02QAyQgeR1SkjnlE3YwZIfjOJU1x2n7jPUxRuPR+wQPRZ9/AQUD5mNzYGLGxXY0Tpjw7zRQ8HFEmZSm4NgMNfYedyHpWbbJLrYTR4vg5pNFtJm7vmZdaV6JP6WLtyDkC83pKK8oOOha8PhNwXKcMMUMjS9NGhbaR0I8cDsgOOo0wAZl8oNGD/6FWc4XsDAfvWLac4a9BUtisn14YZcTqjEwkEv0DxnXZ2yVtGwPNmiPEhdfvyDM6kPtBL0BptWEVWvqD0bBS31Ro8FH3BPWunrgDQA/XAkjhHChF+A0mU+lVYncqjtSG9HsKvMUU1Q== www@master

 

1.3在部署機準備目錄環境:bash

mkdir -p /deploy/code/web-demo -p
mkdir -p /deploy/config/web-demo/base
mkdir -p /deploy/config/web-demo/other
mkdir -p /deploy/tar
mkdir -p /deploy/tmp
mkdir -p /opt/webroot
mkdir /webroot
chown -R www:www /deploy
chown -R www:www /opt/webroot
chown -R www:www /webroot
# su - www # 切換到www用戶
$ rm -rf /deploy/code/web-demo # 刪除原目錄,改用git倉庫管理代碼
$ cd /deploy/code/
$ git clone git@192.168.3.198:web/web-demo.git # 克隆後會生成deb-demo目錄,裏面的代碼即咱們在1.1中準備的代碼

 

1.4:編輯部署腳本並準備相關目錄:
1.4.1:或git提交的代碼版本號,用戶記錄提交的版本,作部署或代碼回滾使用:服務器

[www@master web-demo]$ pwd
/source/web/web-demo

$ git show #獲取最近更新的版本信息
[www@master web-demo]$ git show |grep commit | cut -d ' ' -f2 # 只獲取版本號
91d09cc28f48803d8795f62d925de70f192daeda
[www@master web-demo]$ VERSION_L=$(git show |grep commit | cut -d ' ' -f2)
[www@master web-demo]$ echo ${VERSION_L:0:8} # 切片取固定長度
91d09cc2

 

1.4.3:在各web服務器準備如下目錄:
#web服務器操做網絡

# mkdir /opt/webroot #保存代碼的目錄
# chown www.www /opt/webroot/ -R
# mkdir /webroot #生成配置文件的web主目錄,下面是項目的工做目錄,好比/webroot/web-demo
# chown www.www /webroot/ -R
$ touch /webroot/web-demo

1.4.4:腳本改造以下,主要實現從git拉取代碼再部署至服務器:

#!/bin/bash

#Dir List 部署節點(即部署節點須要作的操做)
# mkdir -p /deploy/code/web-demo
# mkdir -p /deploy/config/web-demo/base
# mkdir -p /deploy/config/web-demo/other
# mkdir /deploy/tmp
# mkdir /deploy/tar

# chown -R www.www /deploy
# chown -R www.www /webroot
# chown -R www.www /opt/webroot/
# chown -R www.www /webroot

# 須要在客戶端節點作的操做
# mkdir /opt/webroot
# mkdir /webroot
# chown -R www.www /webroot
# chown -R www.www /opt/webroot/
# chown -R www.www /webroot
# [www@ ~]$ touch /webroot/web-dem

# Node List 服務器節點
PRE_LIST="192.168.3.12"        # 預生產節點
GROUP1_LIST="192.168.3.12 192.168.3.13"
GROUP2_LIST="192.168.3.13"
ROLLBACK_LIST="192.168.3.12 192.168.3.13"

# 日誌日期和時間變量
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/web-demo"    # 從版本管理系統更新的代碼目錄
CONFIG_DIR="/deploy/config/web-demo"    # 保存不一樣項目的配置文件,一個目錄裏面就是一個項目的一個配置文件或多個配置文件
TMP_DIR="/deploy/tmp"            # 臨時目錄
TAR_DIR="/deploy/tar"            # 打包目錄
LOCK_FILE="/tmp/deploy.lock" # 鎖文件路徑

usage(){ # 使用幫助函數
    echo $"Usage: $0 [ deploy | rollback [ list | version ]"
}

writelog(){ # 寫入日誌的函數
    LOGINFO=$1 # 將參數做爲日誌輸入
    echo "${CDATE} ${CTIME} : ${SEHLL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
}

# 鎖函數
shell_lock(){
    touch ${LOCK_FILE}
}

# 解鎖函數
shell_unlock(){
    rm -f ${LOCK_FILE}
}

# 獲取代碼的函數
code_get(){
    echo "code_get"
    writelog code_get
    cd $CODE_DIR && git pull # 進入到代碼目錄更新代碼,此處必須免密碼更新,此目錄僅用於代碼更新不能放其餘任何文件
    cp -rf ${CODE_DIR} ${TMP_DIR}/ # 臨時保存代碼並重命名,包名爲時間+版本號,準備複製到web服務器
    API_VERL=$(git show | grep commit | cut -d ' ' -f2)  
    API_VER=$(echo ${API_VERL:0:8})        # 版本號
}

code_build(){ # 代碼編譯函數
    echo code_build
}

code_config(){ # 配置文件函數
    writelog "code_config"
    /bin/cp -rf ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}" # 將配置文件放在本機保存配置文件的臨時目錄,用於暫時保存代碼項目
    PKG_NAME="${PRO_NAME}"_"$API_VER"_"${CDATE}-${CTIME}"    # 定義代碼目錄名稱
    cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}    # 重命名代碼文件爲web-demo_123-20170629-11-19-10格式
    
}

code_tar(){    # 對代碼打包函數
    writelog code_tar
    cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} --exclude=".git" # 將目錄打包成壓縮文件,便於網絡傳輸
    writelog "${PKG_NAME}.tar.gz packaged success"    # 記錄打包成功的日誌
}

code_scp(){ # 代碼壓縮包scp到客戶端的函數
    writelog  "code_scp"
    for node in $PRE_LIST;do # 循環服務器節點列表
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ # 將壓縮後的代碼包複製到web服務器的/opt/webroot
    done

    for node in $GROUP1_LIST;do # 循環服務器節點列表
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ # 將壓縮後的代碼包複製到web服務器的/opt/webroot
    done
}

cluster_node_add(){ #將web服務器添加至前端負載
    echo cluster_node_add
}

cluster_node_remove(){ # 將web服務器從集羣移除函數(正在部署的時候應該不處理業務)
    writelog "cluster_node_remove"
}

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

pre_deploy(){ # 代碼解壓部署函數,預生產節點
    writelog "pre_deploy"
    for node in ${PRE_LIST};do # 循環預生產服務器節點列表
        cluster_node_remove  ${node} # 部署以前將節點從前端負載刪除
        echo  "pre_deploy, cluster_node_remove ${node}"
        ssh ${node} "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" #分別到web服務器執行壓縮包解壓命令
        ssh ${node} "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" # 整個自動化的核心,建立軟鏈接
        done
}

pre_test(){ # 預生產主機測試函數
    for node in ${PRE_LIST};do # 循環預生產主機列表
        curl -s --head http://${node}:9999/index.html | grep "200 OK" # 測試web界面訪問
            if [ $? -eq 0 ];then  # 若是訪問成功
                writelog " ${node} Web Test OK!" # 記錄日誌
                echo " ${node} Web Test OK!"
                cluster_node_add ${node} # 測試成功以後調用添加函數把服務器添加至節點,
                writelog "pre,${node} add to cluster OK!" # 記錄添加服務器到集羣的日誌
            else # 若是訪問失敗
                writelog "${node} test no OK" # 記錄日誌
                echo "${node} test not OK"
                shell_unlock # 調用刪除鎖文件函數
            break # 結束部署
        fi
    done

}

group1_deploy(){ # 代碼解壓部署函數
    writelog "group1_code_deploy"
    for node in ${GROUP1_LIST};do # 循環生產服務器節點列表
        cluster_node_remove $node  
        echo "group1, cluster_node_remove $node"
        ssh ${node} "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" # 分別到各web服務器節點執行壓縮包解壓命令
        ssh ${node} "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" # 整個自動化的核心,建立軟鏈接
    done
    scp ${CONFIG_DIR}/other/192.168.3.13.server.xml 192.168.3.13:/webroot/web-demo/server.xml  # 將差別項目的配置文件scp到此web服務器並以項目結尾
}    

group1_test(){ # 生產主機測試函數
    for node in ${PRE_LIST};do # 循環生產主機列表
        curl -s --head http://${node}:9999/index.html | grep "200 OK" #測試web界面訪問
        if [ $? -eq 0 ];then  #若是訪問成功
            writelog " ${node} Web Test OK!" #記錄日誌
            echo "group1_test,${node} Web Test OK!"
            cluster_node_add
            writelog " ${node} add to cluster OK!" #記錄將服務器 添加至集羣的日誌
        else #若是訪問失敗
            writelog "${node} test no OK" #記錄日誌
            echo "${node} test no OK"
            shell_unlock # 調用刪除鎖文件函數
            break # 結束部署
        fi
    done
}

rollback_fun(){ 
    for node in $ROLLBACK_LIST;do # 循環服務器節點列表
        # 注意必定要加"號,不然沒法在遠程執行命令
        ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo" # 當即回滾到指定的版本,$1即指定的版本參數
        echo "${node} rollback success!"
        done
}

rollback(){ # 代碼回滾主函數
    if [ -z $1 ];then
        shell_unlock # 刪除鎖文件
        echo "Please input rollback version" && exit 3;
    fi
    case $1 in # 把第二個參數作當本身的第一個參數 
        list)
            ls -l /opt/webroot/*.tar.gz
            ;;
        *)
            rollback_fun $1
    esac
            
}

main(){
    if [ -f $LOCK_FILE ] ;then # 先判斷鎖文件在不在,若是有鎖文件直接退出
        echo "Deploy is running" && exit 10
    fi
    DEPLOY_METHOD=$1 # 避免出錯誤將腳本的第一個參數做爲變量
    ROLLBACK_VER=$2
    case $DEPLOY_METHOD in
        deploy) # 若是第一個參數是deploy就執行如下操做
            shell_lock; # 執行部署以前建立鎖。若是同時有其餘人執行則提示鎖文件存在
            code_get; # 獲取代碼
            code_build; # 若是要編譯執行編譯函數
            code_config; # cp配置文件
            code_tar;    # 打包
            code_scp;    # scp到服務器
            pre_deploy;  # 預生產環境部署
            pre_test;    # 預生產環境測試
            group1_deploy; # 生產環境部署
            group1_test;   # 生產環境測試
            shell_unlock; # 執行完成後刪除鎖文件
            ;;
        rollback) # 若是第一個參數是rollback就執行如下操做
            shell_lock; # 回滾以前也是先建立鎖文件
            rollback $ROLLBACK_VER;
            shell_unlock; # 執行完成刪除鎖文件
            ;;
        *)
            usage;
    esac
}
main $1 $2

 

1.5 運行部署腳本:

[www@master ~]$ ./deploy.sh deploy
code_get
Already up-to-date.
code_build
web-demo_75463f1b_2017-06-30-15-05-57.tar.gz 100% 1207KB 1.2MB/s 00:00 
web-demo_75463f1b_2017-06-30-15-05-57.tar.gz 100% 1207KB 1.2MB/s 00:00 
web-demo_75463f1b_2017-06-30-15-05-57.tar.gz 100% 1207KB 1.2MB/s 00:00 
pre_deploy, cluster_node_remove 192.168.3.12
HTTP/1.1 200 OK
192.168.3.12 Web Test OK!
cluster_node_add
group1, cluster_node_remove 192.168.3.12
group1, cluster_node_remove 192.168.3.13

/deploy/config/web-demo/other/192.168.3.13.server.xml: No such file or directory
HTTP/1.1 200 OK
group1_test,192.168.3.12 Web Test OK!
cluster_node_add

 

1.5.2測試修改代碼後可否正常獲取最新代碼,並部署成功
# 在本身的項目裏面修改代碼而後提交至git服務器

[www@master web-demo]$ pwd
/source/web/web-demo
[www@master web-demo]$ vim index.html 
[www@master web-demo]$ git add "index.html"
[www@master web-demo]$ git commit -m "edit index.html add www.chinasoft.com"
[master 7886914] edit index.html add www.chinasoft.com
1 file changed, 2 insertions(+), 2 deletions(-)
[www@master web-demo]$ git push origin master
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 324 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@192.168.3.198:web/web-demo.git
75463f1..7886914 master -> master

 

# 再次部署
[www@master ~]$ ./deploy.sh deploy

能夠看到客戶端已經更新了
http://192.168.3.13:9999/

相關文章
相關標籤/搜索