1. 程式人生 > >自動化部署實踐

自動化部署實踐

失誤 phrase ima 指定版本 rod name gin rontab 創建

1.1 早期手動部署代碼

方式

1、純手工scp上傳

2、純手工登錄,git pull、svn update

3、純手工xftp往上拉

4、開發給打一個壓縮包,rz 上去然後解壓

缺點

1、運維全程參與,占用大量時間

2、上線速度太慢

3、人為失誤過多,管理混亂

4、回滾的太慢、不及時、並且難以回滾

1.2 如何設計自動代碼部署系統

1、規劃

2、實現

3、總結和擴展

4、在生產環境中應用

1.2.1 自動化部署環境

1、開發環境

開發者本地有自己的環境,然後運維需要配置公共的開發環境,大家可公用的服務,例如開發數據庫mysql redis等

2、測試環境

功能測試環境和性能測試環境

3、預生產環境

生產環境集群中的某一個節點擔任

4、生產環境

直接對用戶提供的環境

1.2.2 自動化部署規劃

  • 有一個可以上線代碼的git倉庫
  • 一個集群中有10個節點,實現一鍵部署、秒級回滾
  • 所有的web服務都應該使用普通用戶
  • 所有的web服務都不應該監聽80端口,除了負載均衡

1.2.3 自動化部署實現思路

  • 代碼放在那裏

    代碼放在svn、git(優先選擇)上

  • 編譯(可選 java環境需要)
  • 獲取什麽版本的代碼

1、svn+git:直接拉取某個分支

2、svn:指定版本號

3、git:指定tag

  • 差異解決

1、各個代碼直接差異,配置文件未必一樣

2、代碼倉庫和實際的差異,代碼是否放在代碼倉庫中(配置單獨進行存放)短信接口、支付,等敏感信息不能讓所有的開發知道

-項目名設計
web-demo_456_2018-09-02-15-32-14

  • 如何更新

php、tomcat需要重新啟動

  • 測試

1、測試關鍵的頁面、API、後臺等

2、測試一個與生產環境、通過則繼續部署,失敗則進行回滾

  • 日誌記錄

1、對部署進行設計

成功多少次

失敗多少次

回滾多少次

  • 多人同時執行腳本

防止多人同時操作,導致重復上線失敗,通過lock鎖文件進行控制

  • 串行和並行

1、若集群中機器少,則串行看不出什麽問題、若機器多則串行會非常的慢

2、分組部署、並行部署

3、測試預生產環境,成功則繼續部署,失敗則進行回滾

  • 如何執行

1、shell執行

2、web界面進行操作

1.2.4 自動話部署實踐

1、獲取最新代碼

2、編譯(可選)

3、配置文件(軟連接或者cp)

4、打包

5、scp到目標服務器

6、解壓

7、放置到webroot

8、scp差異文件

9、重啟(可選)

10、測試

11、加入集群

自動化部署代碼的精髓在於創建軟連接

1.2.5 回退實踐

1.2.5.1 正常回退實踐

1、列出回滾版本

2、目標服務器移除集群

3、執行回滾(刪除軟連接、重建軟連接)

4、重啟和測試

5、加入集群

1.2.5.2 緊急回退實踐

1、列出回滾版本

2、執行回滾(刪除軟連接、重建軟連接)

3、重啟對應服務

1.2.5.3 更緊急回退實踐

1、執行回滾

2、重啟

1.3 自動化部署系統構建實踐

1.3.1 環境準備

linux_node1 10.0.0.7

linux_node2 10.0.0.8

1、創建普通用戶(兩臺同時進行)

useradd -u 1000 lzh

echo ‘123456‘|passwd --stdin lzh

2、配置密鑰

[root@linux_node1 ~]# su - lzh  切換至普通用戶

[lzh@linux_node1 ~]$ ssh-keygen -t dsa  生成密鑰

Generating public/private dsa key pair.

Enter file in which to save the key (/home/lzh/.ssh/id_dsa): 默認一路回車

Created directory ‘/home/lzh/.ssh‘.

Enter passphrase (empty for no passphrase): 

Enter same passphrase again:

Your identification has been saved in /home/lzh/.ssh/id_dsa. 鑰匙

Your public key has been saved in /home/lzh/.ssh/id_dsa.pub. 鎖

The key fingerprint is:

f9:bb:3a:7f:e3:17:56:12:d3:8a:7b:78:79:ab:e2:de lzh@linux_node1

The key‘s randomart image is:

+--[ DSA 1024]----+
|               . |
|              o .|
|             . + |
|         .  . o .|
|        S    o + |
|         .  o * .|
|          .  + o.|
|        .  o+ .. |
|        .+**oE.  |
+-----------------+

[lzh@linux_node1 ~]$ ssh-copy-id  -i ~/.ssh/id_dsa.pub [email protected]
The authenticity of host ‘172.16.1.8 (172.16.1.8)‘ can‘t be established.
RSA key fingerprint is c2:34:59:81:a2:a7:9c:0a:23:9b:cf:1d:bb:d4:8e:ad.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘172.16.1.8‘ (RSA) to the list of known hosts.
[email protected]‘s password: 
Now try logging into the machine, with "ssh ‘[email protected]‘", and check in:

  .ssh/authorized_keys

to make sure we haven‘t added extra keys that you weren‘t expecting.

[lzh@linux_node1 ~]$ ssh 172.16.1.8
[lzh@linux_node2 ~]$    

3、創建相關目錄

mkdir -p /deploy/code/web-demo 
mkdir -p /deploy/config/web-demo/base
mkdir -p /deploy/config/web-demo/other
mkdir -p /deploy/tar
mkdir -p /deploy/tmp 
[root@linux_node1 ~]# tree /deploy/
/deploy/
├── code
│?? └── web-demo
├── config
│?? └── web-demo
│??     ├── base
│??     └── other
├── tar
└── tmp

8 directories, 0 files

chown -R lzh.lzh /deploy
chown -R lzh.lzh /opt/webroot/
chown -R lzh.lzh /webroot/

1.3.2 自動化腳本

查看腳本

#!/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 -p /deploy/tar
#mkdir -p /deploy/tmp 
#mkdir -p /opt/webroot
#chown -R lzh.lzh /deploy
#chown -R lzh.lzh /opt/webroot
#chown -R lzh.lzh /webroot

#Node List
PRE_LIST="172.16.1.7"
GROUP1_LIST="172.16.1.8"
ROLLBACK_LIST="172.16.1.7 172.16.1.8"
#Date/Time Veriables
LOG_DATE=‘date "+%Y-%m-%d"‘
LOG_TIME=‘date "+%H-%M-%S"‘

CDATE=`date "+%Y-%m-%d"`
CTIME=`date "+%H-%M-%S"`

#PKG_NAME
TEST=pre
PRODUCT=master

# Shell Env 
SHELL_NAME="deploy.sh"
SHELL_DIR="/home/lzh"
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(){
    LOG_INFO=$1
    echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOG_INFO} " >> ${SHELL_LOG}
}

shell_lock(){
    touch ${LOCK_FILE}
}

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

shell_unlock(){
    rm -f ${LOCK_FILE}
}

code_get(){
    writelog " code_get";
    cd $CODE_DIR && echo "git pull"
    cp -r ${CODE_DIR} ${TMP_DIR}/
    API_VER="456"
}

code_build(){
    echo code_build

}

code_config(){
    writelog "code_config"
    /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}"
    PKG_NAME="${PRO_NAME}"_"$API_VER"_"$TEST"_"${CDATE}-${CTIME}"
    cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}
}

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

code_scp(){
    writelog "code_scp"
    for node in $PRE_LIST;do
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
    done
    for node in $GROUP1_LIST;do
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
    done
}

pre_deploy(){
    writelog "remove from cluster"
                ssh $PRE_LIST "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
        ssh $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"
    echo "add to cluster"
}

group1_deploy(){
    writelog "remove from cluster"
        for node in $GROUP1_LIST;do
                ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
        ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
        done
    scp ${CONFIG_DIR}/other/172.16.1.8.crontab.xml 172.16.1.8:/webroot/web-demo/crontab.xml
}

group1_test(){
    url_test "http://172.16.1.8/index.html"
    echo "add to cluster"
}

cluster_node_in(){
    echo cluster_node_in

}

rollback_fun(){
if [ -z $1 ];then
        shell_unlock
        echo "Pls input rollback version" && exit
fi
        for node in $ROLLBACK_LIST;do
            ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo"
        done
}

rollback_list(){
    find /opt/webroot/*.tar.gz -mtime +1|tail -1 |awk -F "[/ .]" ‘{print$4}‘
}

rollback(){
if [ -z $1 ];then
    shell_unlock
    echo "Pls input rollback version" && exit
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;
   fi
    DEPLOY_METHOD=$1
    ROLLBACK_VER=$2
    case "$DEPLOY_METHOD" in
        deploy)
        shell_lock;
        code_get;
        code_build;
        code_config;
        code_tar;
        code_scp;
        pre_deploy;
        pre_test;
        group1_deploy;
        group1_test;
        shell_unlock;
        ;;
    list)
        rollback_list;
        ;;
       rollback)
        shell_lock;
        rollback $ROLLBACK_VER;
        shell_unlock;
        ;;
       *)
        usage;
  esac
}
main $1 $2

執行部署上線

[lzh@linux_node1 ~]$ ./deploy.sh deploy
git pull
code_build
web-demo_456_pre_2018-09-02-16-06-52.tar.gz                                                        100%  218     0.2KB/s   00:00    
web-demo_456_pre_2018-09-02-16-06-52.tar.gz                                                        100%  218     0.2KB/s   00:00    
HTTP/1.1 200 OK
pre add to cluster
172.16.1.8.crontab.xml                                                                             100%    0     0.0KB/s   00:00    
HTTP/1.1 200 OK
group1 add to cluster

查看當前版本

[lzh@linux_node1 ~]$ ./deploy.sh list
web-demo_456_2018-09-02-15-10-13
web-demo_456_2018-09-02-15-10-13

執行回滾操作

[lzh@linux_node1 ~]$ ./deploy.sh rollback 
Pls input rollback version
[lzh@linux_node1 ~]$ ./deploy.sh 配合list使用  web-demo_456_pre_2018-08-30-00-00-06

查看日誌

[lzh@linux_node1 ~]$ tail deploy.sh.log 
2018-09-02 16-45-23: deploy.sh : code_scp 
2018-09-02 16-45-23: deploy.sh : remove from cluster 
2018-09-02 16-45-23: deploy.sh : remove from cluster 
2018-09-02 17-29-54: deploy.sh :  code_get 
2018-09-02 17-29-54: deploy.sh : code_config 
2018-09-02 17-29-54: deploy.sh : code_tar 
2018-09-02 17-29-54: deploy.sh : web-demo_456_pre_2018-09-02-17-29-54.tar.gz 
2018-09-02 17-29-54: deploy.sh : code_scp 
2018-09-02 17-29-54: deploy.sh : remove from cluster 
2018-09-02 17-29-54: deploy.sh : remove from cluster

自動化部署實踐