自動化部署shell01

自動化部署--shell腳本--1

傳統部署方式
1、純手工scp
2、純手工登錄git pull 、svn update
3、純手工xftp往上拉
4、開發給打一個壓縮包,rz上去。解壓

 

傳統部署缺點:
1、全程運維參與,佔用大量時間
2、上線速度慢。
3、認爲失誤多。管理混亂
4、回滾慢,不及時

 

新項目上線,規劃排在第一位
一般銀行都不提供測試接口。比如一些電商公司測試的話,經常把商品調節成1分,只能特定賬號能看到。

環境的規劃
1、開發環境-開發者本地有自己的環境,然後運維需要設置的開發環境,放的是大家共用的服務。如開發數據庫mysql,其它:redis、Memcached。
2、測試環境:功能測試環境和性能測試環境
3、預生產環境:一般可以用生產環境中的某個節點擔任
4、生產環境:直接對用戶提供服務的環境

預生產環境產生的原因:
1、數據庫不一致:測試環境和生產環境數據庫肯定不一樣的。
2、使用生產環境的聯調接口。例如,支付接口

 

預生產環境--生產環境--灰度發佈

 

灰度發佈:

阿里雲產品上線,都是一個區一個區上的。肯定不是一下子都上的

qq彈窗:恭喜你獲得某某版本資格,請下載新版本享用,你就是小白鼠,這個也是一種灰度發佈

 

規劃

已經有一個可以上線的代碼在代碼倉庫。我們如何設計一套生產自動化部署系統。

1、規劃

2、實現

3、總結和擴展。PDCA

4、在生產環境應用

 

自動化部署系統的規劃

 

需求: 

1個集羣有10個節點。一鍵部署這10個節點。

2、一鍵回滾到任意版本

3、一鍵回滾到上個版本

 

部署:

1、代碼放在哪裏:svn,git
2、獲取什麼版本代碼?
svn+git直接拉去某個分支
svn:指定版本號
git:指定tag
3、差異解決:
(1)、各個節點直接差異:
(2)、代碼倉庫和實際的差異。配置文件是否在代碼倉庫中
(3)、配置文件未必一樣:crontab.xml預生產節點
4、如何更新。java tomcat。需要重啓。
5、測試。
6、串行和並行 分組部署
7如何執行。(1)shell執行。(2)web界面

 

關於配置文件存放:

配置文件放代碼倉庫裏,豈不是所有開發都能連數據庫了。

因此配置文件不能放git裏。

有的人把配置文件放某個分支裏。讓一些人沒法看到

我覺得可以單獨有個放配置文件的git

 

騰訊藍鯨:我幫你做個平臺,你寫個腳本,我幫你發佈到某個機器上,你通過平臺幫你執行

一些公司現在的運維,不管任何發佈,都是做好界面,讓項目負責人去通過界面管理

 

關於差異文件:

可能有些節點有特殊的差異性文件

 

 

自動化部署流程設計

 

 

自動化部署實戰-shell函數

 環境準備

系統版本

[root@linux-node1 ~]# cat /etc/redhat-release 
CentOS Linux release 7.1.1503 (Core) 
[root@linux-node1 ~]# uname -rm
3.10.0-229.el7.x86_64 x86_64
[root@linux-node1 ~]#

主機名和IP

node1
[root@linux-node1 ~]# hostname
linux-node1.nmap.com
[root@linux-node1 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.11 linux-node1 linux-node1.nmap.com
192.168.56.12 linux-node2 linux-node2.nmap.com
[root@linux-node1 ~]# 

node2
[root@linux-node2 ~]# hostname
linux-node2.nmap.com
[root@linux-node2 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.11 linux-node1 linux-node1.nmap.com
192.168.56.12 linux-node2 linux-node2.nmap.com
[root@linux-node2 ~]#

    

兩臺web服務器,node1和node2作爲兩個web服務器,同時node1也作爲部署分發服務器,去管理2個node節點上的web包

 

兩個節點添加普通用戶www,作爲web服務器管理用戶。

[root@linux-node1 scripts]# useradd -u 1001 www
[root@linux-node1 scripts]# id www
uid=1001(www) gid=1001(www) groups=1001(www)
[root@linux-node1 scripts]# 

[root@linux-node2 ~]# useradd -u 1001 www
[root@linux-node2 ~]# id www
uid=1001(www) gid=1001(www) groups=1001(www)
[root@linux-node2 ~]#

 

配置www用戶登錄其他機器不用密碼。密鑰認證。以後www用戶作爲管理其它機器的用戶

[root@linux-node1 .ssh]# su - www
[www@linux-node1 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/www/.ssh/id_rsa): 
Created directory '/home/www/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/www/.ssh/id_rsa.
Your public key has been saved in /home/www/.ssh/id_rsa.pub.
The key fingerprint is:
70:37:ff:d0:17:e0:74:1d:c9:04:28:bb:de:ec:1f:7f [email protected]
The key's randomart image is:
+--[ RSA 2048]----+
|            .++++|
|         . .o oo.|
|      . . =  . . |
|       o o o .  .|
|        S . o . .|
|         .   o . |
|        . o  ..  |
|         . o  o E|
|          .... ..|
+-----------------+
[www@linux-node1 ~]$

 

查看公鑰

[www@linux-node1 ~]$ cd .ssh/
[www@linux-node1 .ssh]$ ll
total 8
-rw------- 1 www www 1679 Apr  5 03:41 id_rsa
-rw-r--r-- 1 www www  406 Apr  5 03:41 id_rsa.pub
[www@linux-node1 .ssh]$ cat id_rsa.pub 
ssh-rsa 
AAAAB3NzaC1yc2EAAAADAQABAAABAQDcZh8EEk2/rS6B/tLHnRpZGrGIJYFHg7zRFvuT3N9jvOFhYJdWv+8WSQuT0pvxNM4eR0N5Ma9wVvKPo/lVjCaFK+M0dENJVhi6m9OKMtoo2u
jvvuyinNPP4pyoK6ggG5jOlEkHoLcbWCRG/j3pN1rZYV+1twET9xi2IA4UQkgPvKKYWjq7NUR0v5BWsgEQt7VvjcLWTlltTVeGb3FDVKIjDnioIBmLmVwJS64N+GGgAj5YQ+bKHTwY
anEMD39JGKxo0RXTZB5sa734yfNjc3hTZXB4RCcGdzgcMJs/Rt5VeZ277zF86xr4Hd5cioAbV6Y1RvELjmpvrqUUz3tcaKId [email protected]
[www@linux-node1 .ssh]$

  

node2也添加node1的公鑰

改成600權限才能正常登錄

[www@linux-node2 ~]$ cd .ssh/
[www@linux-node2 .ssh]$ vim authorized_keys
[www@linux-node2 .ssh]$ cat authorized_keys 
ssh-rsa 
AAAAB3NzaC1yc2EAAAADAQABAAABAQDcZh8EEk2/rS6B/tLHnRpZGrGIJYFHg7zRFvuT3N9jvOFhYJdWv+8WSQuT0pvxNM4eR0N5Ma9wVvKPo/lVjCaFK+M0dENJVhi6m9OKMtoo2u
jvvuyinNPP4pyoK6ggG5jOlEkHoLcbWCRG/j3pN1rZYV+1twET9xi2IA4UQkgPvKKYWjq7NUR0v5BWsgEQt7VvjcLWTlltTVeGb3FDVKIjDnioIBmLmVwJS64N+GGgAj5YQ+bKHTwY
anEMD39JGKxo0RXTZB5sa734yfNjc3hTZXB4RCcGdzgcMJs/Rt5VeZ277zF86xr4Hd5cioAbV6Y1RvELjmpvrqUUz3tcaKId [email protected]
[www@linux-node2 .ssh]$ chmod 600 authorized_keys 
[www@linux-node2 .ssh]$

 

登錄測試--成功

[www@linux-node1 .ssh]$ ssh 192.168.58.12
Last login: Mon Apr 10 00:31:23 2017 from 192.168.58.11
[www@linux-node2 ~]$

 

讓node1的www用戶ssh自己也不需要輸入密碼。

node1添加公鑰

本地也放自己的密鑰,這樣可以假裝模擬成3臺機器。2個ssh免密鑰的機器

node1同時作爲部署機

[www@linux-node1 .ssh]$ ll
total 12
-rw------- 1 www www 1679 Apr  5 03:41 id_rsa
-rw-r--r-- 1 www www  406 Apr  5 03:41 id_rsa.pub
-rw-r--r-- 1 www www  175 Apr  5 03:43 known_hosts
[www@linux-node1 .ssh]$ vim authorized_keys
[www@linux-node1 .ssh]$ chmod 600 authorized_keys 
[www@linux-node1 .ssh]$ ssh 192.168.58.11
The authenticity of host '192.168.58.11 (192.168.58.11)' can't be established.
ECDSA key fingerprint is 8b:4e:2f:cd:37:89:02:60:3c:99:9f:c6:7a:5a:29:14.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.58.11' (ECDSA) to the list of known hosts.
Last login: Wed Apr  5 03:40:47 2017
[www@linux-node1 ~]$ exit
logout
Connection to 192.168.58.11 closed.
[www@linux-node1 .ssh]$ ssh 192.168.58.11
Last login: Wed Apr  5 03:46:21 2017 from 192.168.58.11
[www@linux-node1 ~]$

  

開始寫自動化部署腳本

根據上面的流程圖,先把大體框架寫出來

先把框架寫出來,然後每個函數裏寫echo

看看腳本執行流程是否有問題

 

code_diff 拷貝差異部署文件

這是面向過程的一種開發方式

 

[root@linux-node1 ~]# mkdir /scripts -p
[root@linux-node1 ~]# cd /scripts/
[root@linux-node1 scripts]# vim deploy.sh
[root@linux-node1 scripts]# chmod +x deploy.sh 
[root@linux-node1 scripts]# ./deploy.sh 
Usage: ./deploy.sh [ deploy | rollback ]
[root@linux-node1 scripts]# cat deploy.sh 
#!/bin/bash

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

#Code Env
CODE_DIR="/deploy/code/deploy"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="/deploy/tar"

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

code_get(){
    echo code_get
}

code_build(){
    echo code_build
}

code_config(){
    echo code_config
}

code_tar(){
    echo code_tar
}

code_scp(){
    echo code_scp
}

cluster_node_remove(){
    echo cluster_node_remove
}

code_deploy(){
    echo code_deploy
}

config_diff(){
    echo config_diff
}

code_test(){
    echo code_test
}

cluster_node_in(){
    echo cluster_node_in
}

rollback(){
    echo rollback
}

main(){
    case $1 in
    deploy)
            code_get;
            code_build;
            code_config;
            code_tar;
            code_scp;
            cluster_node_remove;
            code_deploy;
            config_diff;
            code_test;
            cluster_node_in;
            ;;
    rollback)
            rollback;
            ;;
    *)
            usage;
    esac

}
main $1
[root@linux-node1 scripts]#

最末尾還要加個main,否則無法執行

 

腳本再優化下

儘量不要讓$1來回傳,否則可能會亂

main(){
    DEPLOY_METHOD=$1
    case $DEPLOY_METHOD in
    deploy)
            code_get;
            code_build;
            code_config;
            code_tar;
            code_scp;
            cluster_node_remove;
            code_deploy;
            config_diff;
            code_test;
            cluster_node_in;
            ;;

  

 

繼續完善腳本--添加日誌和鎖
1、凡是不記錄日誌的腳本就是刷流氓,執行到哪一步失敗的啊?
2、腳本是否可以多個人一起執行?(最好不要多個人一起執行)不允許多人執行的話可以上鎖

 

一般鎖文件放下面目錄下

[root@linux-node1 ~]# cd /var/run/lock/
[root@linux-node1 lock]# ls
iscsi lockdev lvm ppp subsys
[root@linux-node1 lock]#

我們可以單獨添加個目錄,給它用,因爲權限問題,需要授權改變屬組,我們使用tmp目錄

主函數執行之前,應該先判斷鎖文件是否存在,執行的時候也應該生成這個lock文件
既然2個地方用到了它,是否可以把它製作成變量

新的腳本如下,主要添加了鎖的功能

[root@linux-node1 scripts]# cat deploy.sh 
#!/bin/bash

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

#Code Env
CODE_DIR="/deploy/code/deploy"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="/deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

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

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

code_get(){
    echo code_get
    sleep 60;
}

code_build(){
    echo code_build
}

code_config(){
    echo code_config
}

code_tar(){
    echo code_tar
}

code_scp(){
    echo code_scp
}

cluster_node_remove(){
    echo cluster_node_remove
}

code_deploy(){
    echo code_deploy
}

config_diff(){
    echo config_diff
}

code_test(){
    echo code_test
}

cluster_node_in(){
    echo cluster_node_in
}

rollback(){
    echo rollback
}

main(){
    if [ -f ${LOCK_FILE} ];then
	echo "Deploy is running"  && exit;
    fi
    DEPLOY_METHOD=$1
    case $DEPLOY_METHOD in
    deploy)
            shell_lock;
            code_get;
            code_build;
            code_config;
            code_tar;
            code_scp;
            cluster_node_remove;
            code_deploy;
            config_diff;
            code_test;
            cluster_node_in;
	    shell_unlock;
            ;;
    rollback)
	    shell_lock;
            rollback;
	    shell_unlock;
            ;;
    *)
            usage;
    esac

}
main $1
[root@linux-node1 scripts]#

  

先執行下檢查語法錯誤

[root@linux-node1 scripts]# ./deploy.sh deploy
code_get
code_build
code_config
code_tar
code_scp
cluster_node_remove
code_deploy
config_diff
code_test
cluster_node_in
[root@linux-node1 scripts]# ./deploy.sh rollback
rollback

  

加個sleep測試下鎖的功能
給一個函數加下sleep 測試下執行中,另外的人是否可以執行這個腳本

code_get(){
    echo code_get
    sleep 60;
}

  

運行腳本

[root@linux-node1 scripts]# ./deploy.sh deploy
code_get

新打開一個窗口執行測試

正常情況下一個窗口執行部署,再開一個窗口肯定執行不了

[root@linux-node1 scripts]# ./deploy.sh deploy
Deploy is running
[root@linux-node1 scripts]# ./deploy.sh deploy
Deploy is running
[root@linux-node1 scripts]# ./deploy.sh rollback
Deploy is running
[root@linux-node1 scripts]#

  

 

增加日誌功能

其實就是echo一行到日誌文件中,每個函數寫加echo 寫到日誌裏,這樣比較low
能不能寫個日誌函數,加時間戳。以後日誌函數可以複製到其它腳本里

[www@linux-node1 scripts]$ date "+%Y-%m-%d"
2017-04-23
[www@linux-node1 scripts]$ date "+%H-%M-%S"
22-10-34
[www@linux-node1 scripts]$

  

腳本默認從上到下執行,遇到函數先加載,但是不執行

繼續優化下。如下

#!/bin/bash

# Date/Time Veriables
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
CODE_DIR="/deploy/code/deploy"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="/deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

 

還不能這麼寫,不然以後的時間都是一樣的
可以改成這樣,它不會執行

#!/bin/bash

# Date/Time Veriables
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
CODE_DIR="/deploy/code/deploy"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="/deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

打包的時候,也用到時間戳命名了。還得用一個固定不變的時間用於打包
因爲解壓的時候,scp的時候用必須知道確定的包名字。
這裏用到了2個時間,log-date是讓它不執行的,cdate是讓它執行的

#!/bin/bash

# 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")

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

#Code Env
CODE_DIR="/deploy/code/deploy"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="/deploy/tar"

 

自己先測試下

[root@linux-node1 ~]# LOG_DATE='date "+%Y-%m-%d"'
[root@linux-node1 ~]# LOG_TIME='date "+%H-%M-%S"'
[root@linux-node1 ~]# echo $LOG_DATE
date "+%Y-%m-%d"
[root@linux-node1 ~]# echo $LOG_TIME
date "+%H-%M-%S"
[root@linux-node1 ~]#

  

eval的用法

[root@linux-node1 ~]# eval $LOG_TIME
22-21-05
[root@linux-node1 ~]# eval $LOG_DATE
2017-04-23
[root@linux-node1 ~]#

 

怎麼可以讓它在一行呢。暫時沒找到辦法(倒是可以單獨定義一個時間變量)

[root@linux-node1 ~]# eval $LOG_DATE && eval $LOG_TIME
2017-04-23
22-22-48
[root@linux-node1 ~]#   

單獨定義一個時間變量(這裏用不到,但是可以實現)

[root@linux-node1 ~]# D_T='date "+%Y-%m-%d-%H-%M-%S"'
[root@linux-node1 ~]# echo $D_T
date "+%Y-%m-%d-%H-%M-%S"
[root@linux-node1 ~]# eval $D_T
2017-04-26-19-33-01
[root@linux-node1 ~]#

  

編寫記錄日誌函數

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

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

shell_lock(){
        touch ${LOCK_FILE}
}

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

  

這樣code_get函數就記錄日誌了

shell_lock(){
        touch ${LOCK_FILE}
}

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

code_get(){
    writelog code_get;
}

code_build(){
    echo code_build
}

  

規範點,加上雙引號,分號可要可不要,寫上不會報錯

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

code_get(){
   writelog "code_get";
}

code_build(){
    echo code_build
}

  

獲取代碼

把代碼放哪裏?

爲什麼創建這些目錄,寫着寫着你就知道了

[root@linux-node1 scripts]# mkdir /deploy/config -p
[root@linux-node1 scripts]# mkdir /deploy/tmp -p
[root@linux-node1 scripts]# mkdir /deploy/tar -p
[root@linux-node1 scripts]# mkdir /deploy/code -p
[root@linux-node1 scripts]# cd /deploy/
[root@linux-node1 deploy]# ll
total 0
drwxr-xr-x 2 root root 6 Apr 23 22:37 code
drwxr-xr-x 2 root root 6 Apr 23 22:37 config
drwxr-xr-x 2 root root 6 Apr 23 22:37 tar
drwxr-xr-x 2 root root 6 Apr 23 22:37 tmp
[root@linux-node1 deploy]#

  

 

最終目錄建立成這種

[root@linux-node1 deploy]# cd code/
[root@linux-node1 code]# mkdir web-demo -p
[root@linux-node1 code]# cd ..
[root@linux-node1 deploy]# tree 
.
├── code
│   └── web-demo
├── config
├── tar
└── tmp

5 directories, 0 files
[root@linux-node1 deploy]#

  

修改腳本

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

#Code Env
CODE_DIR="/deploy/code/web-demo"
CONFIG_DIR="/deploy/config"
TMP_DIR="/deploy/tmp"
TAR_DIR="/deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

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

  

有的不需要編譯,拉下代碼之後,可以先把配置文件放進去

code_get(){
    writelog "code_get";
    cd $CODE_DIR  && git pull
}

  

配置文件不要放這個目錄下,這個目錄只用來更新---git pull.你不好判斷配置文件是倉庫裏面的,還是你專門下載下來的(最佳實踐)
規劃的時候,只讓這裏目錄執行git pull

下面這個目錄用於整合配置文件。

TMP_DIR="/deploy/tmp"

  

繼續優化獲取代碼的函數

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

  

配置操作的函數時候,覺得不合適,應該區分項目,標準化。比如web-demo可以理解爲一個項目包名字

#Code Env
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"

  

目錄新建

[root@linux-node1 scripts]# cd /deploy/
[root@linux-node1 deploy]# cd config/
[root@linux-node1 config]# mkdir web-demo
[root@linux-node1 config]# cd ..
[root@linux-node1 deploy]# tree
.
├── code
│   └── web-demo
├── config
│   └── web-demo
├── tar
└── tmp

6 directories, 0 files
[root@linux-node1 deploy]#

  

模擬下,在裏面寫上hehe

[root@linux-node1 deploy]# cd config/
[root@linux-node1 config]# cd web-demo/
[root@linux-node1 web-demo]# vim config.ini
[root@linux-node1 web-demo]# cat config.ini 
hehe
[root@linux-node1 web-demo]#

  

因爲web-demo項目出現頻繁,把它弄成變量

#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"

  

調整下腳本,優化code_config函數

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

code_build(){
    echo code_build
}

code_config(){
    echo code_config
    /bin/cp -r $CONFIG_DIR/* $TMP_DIR/$PRO_NAME
}

  

規範下,給變量加大括號

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

code_build(){
    echo code_build
}

code_config(){
    echo code_config
    /bin/cp -r ${CONFIG_DIR}/* ${TMP_DIR}/"${PRO_NAME}"
}

注意是/bin/cp ,這樣原先有配置文件,這裏可以直接替換了
如果開發把配置文件打包進去了。連接的是測試的庫,假如你部署生產環境了,連接測試的庫。出了問題,誰背黑鍋
運維是最後一道防線。開發和測試沒遇到。你背黑鍋

 

該給包重命名了

code_config(){
    echo code_config
    /bin/cp -r ${CONFIG_DIR}/* ${TMP_DIR}/"${PRO_NAME}"
    PKG_NAME="${PRO_NAME}"_"${API_VER}"-"${CDATE}-${CTIME}"
}

  

繼續優化

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

  

添加版本號,先隨便定義個版本

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

  

現在沒有git pull 假裝以echo 代替git pull

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

  

屬組授權

[root@linux-node1 scripts]# chown -R www:www /deploy/
[root@linux-node1 scripts]#

  

內容爲hehe,生成代碼(頁面)

[root@linux-node1 scripts]# cd /deploy/code/web-demo/
[root@linux-node1 web-demo]# echo hehe>>index.html
[root@linux-node1 web-demo]# cat index.html 
hehe
[root@linux-node1 web-demo]#

  

文件和目錄結構如下

[root@linux-node1 deploy]# tree 
.
├── code
│   └── web-demo
│       └── index.html
├── config
│   └── web-demo
│       └── config.ini
├── tar
└── tmp

6 directories, 2 files
[root@linux-node1 deploy]#

  

以www用戶測試腳本

[root@linux-node1 deploy]# cd /scripts/
[root@linux-node1 scripts]# chown -R www:www /scripts/deploy.sh 
[root@linux-node1 scripts]# ll
total 12
-rw-r--r-- 1 root root  234 Apr  3 23:51 cobbler_list.py
-rw-r--r-- 1 root root 1533 Apr  4 00:01 cobbler_system_api.py
-rwxr-xr-x 1 www  www  1929 Apr 23 23:04 deploy.sh
[root@linux-node1 scripts]# su - www
Last login: Sun Apr 23 22:06:44 CST 2017 on pts/0
[www@linux-node1 scripts]$ ./deploy.sh  deploy
git pull
code_build
code_config
code_tar
code_scp
cluster_node_remove
code_deploy
config_diff
code_test
cluster_node_in
[www@linux-node1 scripts]$

  

測試結果

[www@linux-node1 scripts]$ tree /deploy/
/deploy/
├── code
│   └── web-demo
│       └── index.html
├── config
│   └── web-demo
│       └── config.ini
├── tar
└── tmp
    ├── web-demo_123-2017-04-23-23-12-15
    │   ├── config.ini
    │   └── index.html
    └── web-demo_123-2017-04-23-23-13-20
        ├── config.ini
        └── index.html

8 directories, 6 files
[www@linux-node1 scripts]$

  

版本和時間之間改成下劃線

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

  

再次執行

[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_config
code_tar
code_scp
cluster_node_remove
code_deploy
config_diff
code_test
cluster_node_in
[www@linux-node1 scripts]$ tree /deploy/
/deploy/
├── code
│   └── web-demo
│       └── index.html
├── config
│   └── web-demo
│       └── config.ini
├── tar
└── tmp
    ├── web-demo_123-2017-04-23-23-12-15
    │   ├── config.ini
    │   └── index.html
    ├── web-demo_123-2017-04-23-23-13-20
    │   ├── config.ini
    │   └── index.html
    └── web-demo_123_2017-04-23-23-17-20
        ├── config.ini
        └── index.html

9 directories, 8 files
[www@linux-node1 scripts]$

  

 

可以看到tmp目錄需要定期清理

給下面2個函數加寫日誌功能

code_config(){
    writelog "code_config"
    /bin/cp -r ${CONFIG_DIR}/* ${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"
}

  

打包,記錄日誌

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

  

再次測試腳本

[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_scp
cluster_node_remove
code_deploy
config_diff
code_test
cluster_node_in
[www@linux-node1 scripts]$ tree /deploy/
/deploy/
├── code
│   └── web-demo
│       └── index.html
├── config
│   └── web-demo
│       └── config.ini
├── tar
└── tmp
    ├── web-demo_123-2017-04-23-23-12-15
    │   ├── config.ini
    │   └── index.html
    ├── web-demo_123-2017-04-23-23-13-20
    │   ├── config.ini
    │   └── index.html
    ├── web-demo_123_2017-04-23-23-17-20
    │   ├── config.ini
    │   └── index.html
    ├── web-demo_123_2017-04-23-23-22-09
    │   ├── config.ini
    │   └── index.html
    └── web-demo_123_2017-04-23-23-22-09.tar.gz

10 directories, 11 files
[www@linux-node1 scripts]$

  

 

 

準備拷貝到目標服務器

前4步都完畢,開始第五步--拷貝到目標服務器

 

 遍歷節點

[www@linux-node1 scripts]$ node_list="192.168.58.11 192.168.58.12"
[www@linux-node1 scripts]$ for node in $node_list;do echo $node;done
192.168.58.11
192.168.58.12
[www@linux-node1 scripts]$

  

腳本里添加node_list

#!/bin/bash

#Node List
NODE_LIST="192.168.58.11 192.168.58.12"

# 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")

  

 分發到目標節點

code_scp(){
    echo code_scp
    for node in $NODE_LIST;do
      scp ${TMP_DIR}/${PKG_NAME}.tar.gz   $node:/opt/webroot/
      done
}

  

2臺機器建立webroot

[root@linux-node1 scripts]# mkdir /opt/webroot -p
[root@linux-node1 scripts]# chown -R www:www /opt/webroot
[root@linux-node1 scripts]# 
[root@linux-node2 ~]# mkdir /opt/webroot -p
[root@linux-node2 ~]# chown -R www:www /opt/webroot
[root@linux-node2 ~]#

  

 完善拷貝函數

code_scp(){
    echo code_scp
    for node in $NODE_LIST;do
      scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
      done
}

  

 

再次部署測試下

[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_scp
web-demo_123_2017-04-23-23-33-50.tar.gz                100%  204     0.2KB/s   00:00    
web-demo_123_2017-04-23-23-33-50.tar.gz                100%  204     0.2KB/s   00:00    
cluster_node_remove
code_deploy
config_diff
code_test
cluster_node_in
[www@linux-node1 scripts]$

  

檢查

[www@linux-node1 scripts]$ tree /opt/webroot/
/opt/webroot/
└── web-demo_123_2017-04-23-23-33-50.tar.gz

0 directories, 1 file
[www@linux-node1 scripts]$ 
[root@linux-node2 ~]# tree /opt/webroot/
/opt/webroot/
└── web-demo_123_2017-04-23-23-33-50.tar.gz

0 directories, 1 file
[root@linux-node2 ~]#

  

 該第6步了,寫個日誌代替

cluster_node_remove(){
writelog "cluster_node_remove"
}

 

解壓完畢,拷貝差異文件。你要把差異文件單獨放一個目錄下。不要和配置文件放一起

修改上面,上面是相同配置目錄文件

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

改成如下

code_config(){
    writelog "code_config"
    /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}
}

  

創建配置文件目錄,base存放相同的配置,other存放差異配置

[www@linux-node1 scripts]$ cd /deploy/config/web-demo/
[www@linux-node1 web-demo]$ mkdir base
[www@linux-node1 web-demo]$ mkdir other
[www@linux-node1 web-demo]$ ll
total 4
drwxrwxr-x 2 www www 6 Apr 23 23:38 base
-rw-r--r-- 1 www www 5 Apr 23 22:46 config.ini
drwxrwxr-x 2 www www 6 Apr 23 23:38 other
[www@linux-node1 web-demo]$

 

調整下配置文件所在目錄

[www@linux-node1 web-demo]$ mv config.ini base/
[www@linux-node1 web-demo]$ cd other/
[www@linux-node1 other]$ echo 192.168.58.12-config >>192.168.58.12.crontab.xml
[www@linux-node1 other]$ ll
total 4
-rw-rw-r-- 1 www www 21 Apr 23 23:39 192.168.58.12.crontab.xml
[www@linux-node1 other]$

  

拷貝差異文件到目標服務器的目標目錄

code_deploy(){
    echo code_deploy
    cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz
}

config_diff(){
    echo config_diff
    scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/opt/webroot/${PKG_NAME}
}

  

再次測試

[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_scp
web-demo_123_2017-04-23-23-43-48.tar.gz                       100%  204     0.2KB/s   00:00    
web-demo_123_2017-04-23-23-43-48.tar.gz                       100%  204     0.2KB/s   00:00    
code_deploy
config_diff
192.168.58.12.crontab.xml                                     100%   21     0.0KB/s   00:00    
code_test
cluster_node_in
[www@linux-node1 scripts]$

  

上面還有不足的地方,scp到目標服務器並解壓,應該使用ssh遠程執行、。上面腳本遠程node2上解壓是失敗的
腳本再次改造下,把部署的函數和差異配置合併到一起

cluster_node_remove(){
    writelog "cluster_node_remove"
}

code_deploy(){
    echo code_deploy
    for node in $NODE_LIST;do
      ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
    done
    scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/opt/webroot/${PKG_NAME}/crontab.xml
}

code_test(){
    echo code_test
}

  

創建webroot

[root@linux-node1 ~]# mkdir /webroot
[root@linux-node1 ~]# chown -R www:www /webroot
[root@linux-node1 ~]# 


[root@linux-node2 ~]# mkdir /webroot
[root@linux-node2 ~]# chown -R www:www /webroot
[root@linux-node2 ~]#

  

再次對部署函數優化,添加使用軟鏈接參數(這個是秒級回滾的關鍵)

cluster_node_remove(){
    writelog "cluster_node_remove"
}

code_deploy(){
    echo code_deploy
    for node in $NODE_LIST;do
      ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
    done
    scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/opt/webroot/${PKG_NAME}/crontab.xml
    ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo
}

code_test(){
    echo code_test
}

  

再次對腳本優化

cluster_node_remove(){
    writelog "cluster_node_remove"
}

code_deploy(){
    echo code_deploy
    for node in $NODE_LIST;do
      ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
    done
    scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/opt/webroot/${PKG_NAME}/crontab.xml
    rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo
}

code_test(){
    echo code_test
}

  

自動化部署的精髓,創建軟鏈接

對腳本優化,每個服務器要執行相同的操作,因此放在循環裏

cluster_node_remove(){
    writelog "cluster_node_remove"
}

code_deploy(){
    echo code_deploy
    for node in $NODE_LIST;do
      ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
      rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo
    done
    scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/opt/webroot/${PKG_NAME}/crontab.xml
}

code_test(){
    echo code_test
}

  

拷貝差異文件應該創建軟鏈接之後拷貝,其實就是路徑寫的少點

cluster_node_remove(){
    writelog "cluster_node_remove"
}

code_deploy(){
    echo code_deploy
    for node in $NODE_LIST;do
      ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
      rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo
    done
    scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

code_test(){
    echo code_test
}

 

第一次沒軟鏈接,會報錯。需要先手動創建個軟連接,或者先創建web-demo目錄

其實我覺的完全可以在上面腳本里加入mkdir /webroot/web-demo -p 這樣永遠不會錯

[www@linux-node1 scripts]$ cd /webroot/
[www@linux-node1 webroot]$ mkdir web-demo -p
[www@linux-node1 webroot]$ 
[root@linux-node2 webroot]# mkdir web-demo -p
[root@linux-node2 webroot]#

  

再次執行部署腳本。node1完成了

繼續優化腳本,rm -rf 這裏要寫爲-rf

cluster_node_remove(){
    writelog "cluster_node_remove"
}

code_deploy(){
    echo code_deploy
    for node in $NODE_LIST;do
      ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
      ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
    done
    scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

code_test(){
    echo code_test
}

  

測試腳本

[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_scp
web-demo_123_2017-04-24-00-01-24.tar.gz                       100%  204     0.2KB/s   00:00    
web-demo_123_2017-04-24-00-01-24.tar.gz                       100%  204     0.2KB/s   00:00    
code_deploy
192.168.58.12.crontab.xml                                     100%   21     0.0KB/s   00:00    
./deploy.sh: line 113: config_diff: command not found
code_test
cluster_node_in
[www@linux-node1 scripts]$

主函數裏,刪除這個 config_diff

 

繼續測試和檢查

測試
[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_scp
web-demo_123_2017-04-24-00-02-44.tar.gz                       100%  205     0.2KB/s   00:00    
web-demo_123_2017-04-24-00-02-44.tar.gz                       100%  205     0.2KB/s   00:00    
code_deploy
192.168.58.12.crontab.xml                                     100%   21     0.0KB/s   00:00    
code_test
cluster_node_in
[www@linux-node1 scripts]$ 
檢查
[www@linux-node1 scripts]$ ll /webroot/
total 0
lrwxrwxrwx 1 www www 45 Apr 24 00:02 web-demo -> /opt/webroot/web-demo_123_2017-04-24-00-02-44
[www@linux-node1 scripts]$ 

[root@linux-node2 webroot]# ll /webroot/
total 0
lrwxrwxrwx 1 www www 45 Apr 24 00:02 web-demo -> /opt/webroot/web-demo_123_2017-04-24-00-02-44
[root@linux-node2 webroot]#

  

模擬版本更新,把版本寫成456

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

  

繼續測試

[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_scp
web-demo_456_2017-04-24-00-04-05.tar.gz                       100%  204     0.2KB/s   00:00    
web-demo_456_2017-04-24-00-04-05.tar.gz                       100%  204     0.2KB/s   00:00    
code_deploy
192.168.58.12.crontab.xml                                     100%   21     0.0KB/s   00:00    
code_test
cluster_node_in
[www@linux-node1 scripts]$ ll /webroot/
total 0
lrwxrwxrwx 1 www www 45 Apr 24 00:04 web-demo -> /opt/webroot/web-demo_456_2017-04-24-00-04-05
[www@linux-node1 scripts]$

檢查

鏈接 到了新的版本


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章