shell實現代碼自動化部署

通過shell腳本實現代碼自動化部署

通過shell腳本實現代碼自動化部署

一、傳統部署方式及優缺點
1.傳統部署方式
(1)純手工scp

(2)純手工登錄git pull、svn update

(3)純手工xftp往上拉

(4)開發給打一個壓縮包,rz上去;解壓

2.缺點
(1)全程運維參與,佔用大量時間

(2)上線速度慢

(3)人爲失誤多,管理混亂

(4)回滾慢,不及時

二、環境規劃
1、開發環境--開發者本地有自己的環境。

運維需要設置的開發環境,大家共用的服務。

2、測試環境:功能測試環境和性能測試環境。

3、預生產環境:生產環境集羣中的某一個節點。

4、生產環境:直接對用戶提供服務的環境。

測試環境與生產環境的數據庫不一致時,可能會導致測試的功能不全面,在測試環境測無問題,放在線上可能出現問題

三、需求分析
一、功能需求需求
一個集羣有十個節點

1.實現 一鍵部署10個節點

2.一鍵回滾到任意版本

3.一鍵回滾到上個版本

二、部署需求
部署:

1.代碼在哪裏:svn、git

2.獲取什麼版本代碼?

svn/git:直接拉去某個分支

svn:指定版本號

git:指定tag

3.差異解決:

(1)各個節點直接差異:配置文件未必一致(crontab.xml)。預生產節點。

(2)代碼倉庫和實際的差異。配置文件是否放在代碼倉庫中。

4.如何更新

更新時需要考慮是否重啓。例如java代碼,需要考慮重啓tomcat。重啓過程中,用戶就不能訪問了。

5.測試

部署多個節點,某個節點由於配置問題導致部署不成功。如何測試。

6.串行和並行

部署多個節點,串行部署還是並行部署,視具體業務需求決定。

7.如何執行

1.shell腳本,直接執行

2.web界面

三、部署流程
1.獲取代碼(直接拉取)----》 2.編譯(可選)----》 3.配置文件放進去----》 4.打包 ----》

5.SCP到目標服務器----》 6.將目標服務器移除集羣----》 7.解壓 ----》 8.放置到webroot ----》

9.SCP差異文件 ----》 10.重啓(可選) ----》 11.測試 ----》 12.加入集羣

四、代碼實現
1、設置無交互訪問
通過ssh-keygen將部署機的公鑰發送給應用服務器。

注意,這裏通常是用普通用戶登陸部署機,生成公鑰後,再把公鑰發給應用服務器

ssh-keygen -t rsa

切換到.ssh目錄下

[www@linux-node1 ~/.ssh]$ ll

total 16

-rwx------ 1 www www 397 Jul 31 22:45 authorized_keys

-rwx------ 1 www www 1679 Jul 31 22:44 id_rsa

-rwx------ 1 www www 397 Jul 31 22:44 id_rsa.pub

將id_rsa.pub中的內容複製粘貼到應用服務器的www用戶的.ssh目錄下,

文件名稱爲authorized_keys

[www@linux-node2 .ssh]$ cat authorized_keys

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqT3VwY9Wo7tKsXa4Ce1zXGLT/Iygy30tDBKnV4HW4g5BdUS48urTvYljL9cwJ/HWvoqbtJ5mc7PMmhDMOAjIh1CRZtGxKEkQFB/Xp5cLeAsE7iH+WfkNqavFHD75+YuM2mbNBvisDXO+/pJ/QfbmYwWJ6CW6uLpQKpitdJwrLpQDJGQv5H3aV0kHKZdoA+twdXm0LmQcWWJt7zruPq19CAXG5b93KTdgyt/1x4BfcT5/+PCaEd9suYwEneI2Io8CX9oTAe3MRyRPtlN0szT89qP/q+Q4sktVjc1nkxHhdP2mahqeiBLUGULfkgUBtEjaGAFSWb+ejFV0fRDHk6bSJ www@linux-node1

注意,修改authorized_keys的權限

chmod 600 authorized_keys

另外,將.ssh目錄的權限設置成700

chmod 700 .ssh

2、詳細代碼

複製代碼
1 #!/bin/bash
2
3 #Node List
4
5 PRE_LIST="192.168.56.11"
6
7 GROUP1_LIST="192.168.56.12"
8
9 ROLLBACK_LIST="192.168.56.11 192.168.56.12"
10
11 #Date/Time Variable
12
13 LOG_DATE='date "+%Y-%m-%d"'
14
15 LOG_TIME='date "+%H-%M-%S"'
16
17 CDATE=$(date "+%Y-%m-%d")
18
19 CTIME=$(date "+%H-%M-%S")
20
21 #Shell env
22
23 SHELL_NAME="/deploy1.sh"
24
25 SHELL_DIR="/home/www/"
26
27 SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
28
29 #Code ENV
30
31 PRO_NAME="web-demo"
32
33 CODE_DIR="/deploy/code/web-demo"
34
35 CONFIG_DIR="/deploy/config/web-demo"
36
37 TMP_DIR="/deploy/tmp"
38
39 TAR_DIR="/deploy/tar"
40
41 LOCK_FILE="/tmp/deploy.lock"
42
43
44
45 usage(){
46
47 echo $"Usage: $0 {deploy | rollback [ list | version ]} "
48
49 }
50
51
52
53 writelog(){
54
55 LOGINFO=$1
56
57 echo "${CDATE}${CTIME}: ${SHELL_NAME}: ${LOGINFO} " >> ${SHELL_LOG}
58
59 }
60
61
62
63
64
65 shell_lock(){
66
67 touch ${LOCK_FILE}
68
69 }
70
71
72
73 shell_unlock(){
74
75 rm -f ${LOCK_FILE}
76
77 }
78
79
80
81 code_get(){
82
83 writelog "code_get";
84
85 cd $CODE_DIR && echo "git pull";
86
87 cp -r ${CODE_DIR} ${TMP_DIR}/
88
89 API_VER="456"
90
91 }
92
93
94
95 code_build(){
96
97 echo code_build
98
99 }
100
101
102
103 code_config(){
104
105 writelog "code_config"
106
107 /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}"
108
109 PKG_NAME="${PRONAME}""$APIVER""${CDATE}-${CTIME}"
110
111 cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}
112
113 }
114
115
116
117 code_tar(){
118
119 writelog "code_tar"
120
121 cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz $PKG_NAME
122
123 writelog "${PKG_NAME}.tar.gz"
124
125 }
126
127
128
129 code_scp(){
130
131 writelog "code_scp"
132
133 for node in $PRE_LIST;do
134
135 scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot
136
137 done
138
139 for node in $GROUP1_LIST;do
140
141 scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot
142
143 done
144
145 }
146
147
148
149 cluster_node_remove(){
150
151 writelog "cluster_node_remove"
152
153 }
154
155
156
157 pre_deploy(){
158
159 writelog "remove from cluster"
160
161 ssh $PRE_LIST "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
162
163 ssh $PRE_LIST "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
164
165 }
166
167 url_test(){
168
169 URL=$1
170
171 curl -s --head $URL|grep "200 OK"
172
173 if [ $? -ne 0 ];then
174
175 shell_unlock;
176
177 writelog "test error" && exit;
178
179 fi
180
181 }
182
183 pre_test(){
184
185 url_test "http://${PRE_LIST}/index.html"
186
187 echo "add to cluster"
188
189 }
190
191
192
193 group1_deploy(){
194
195 writelog "remove from cluster"
196
197
198
199 for node in $GROUP1_LIST;do
200
201 ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
202
203 ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
204
205 done
206
207 scp ${CONFIG_DIR}/other/192.168.56.12.crontab.xml 192.168.56.12:/webroot/web-demo/crontab.xml
208
209 }
210
211
212
213 group1_test(){
214
215 url_test "http://192.168.56.12/index.html"
216
217 echo "add to cluster"
218
219 }
220
221 rollback_fun(){
222
223 for node in $ROLLBACK_LIST;do
224
225 ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo"
226
227 done
228
229 }
230
231 rollback(){
232
233 if [ -z $1 ];then
234
235 shell_unlock;
236
237 echo "please input rollback version" && exit;
238
239 fi
240
241 case $1 in
242
243 list)
244
245 ls -l /opt/webroot/.tar.gz
246
247 ;;
248
249
)
250
251 rollback_fun $1
252
253 esac
254
255 }
256
257
258
259 main(){
260
261 if [ -f $LOCK_FILE ];then
262
263 echo "Deploy is running" && exit;
264
265 fi
266
267 DEPLOY_METHON=$1
268
269 ROLLBACK_VER=$2
270
271 case $DEPLOY_METHON in
272
273 deploy)
274
275 shell_lock;
276
277 code_get;
278
279 code_build;
280
281 code_config;
282
283 code_tar;
284
285 code_scp;
286
287 pre_deploy;
288
289 pre_test;
290
291 group1_deploy;
292
293 group1_test;
294
295 shell_unlock;
296
297 ;;
298
299 rollback)
300
301 shell_lock;
302
303 rollback $ROLLBACK_VER;
304
305 shell_unlock;
306
307 ;;
308
309 *)
310
311 usage;
312
313 esac
314
315 }
316
317 main $1 $2
複製代碼
測試方式

[www@linux-node1 ~]$ curl --head http://192.168.56.11/index.html

HTTP/1.1 200 OK

Date: Mon, 01 Aug 2016 09:42:23 GMT

Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5

Last-Modified: Mon, 01 Aug 2016 09:39:52 GMT

ETag: "17-538ff61ca0a00"

Accept-Ranges: bytes

Content-Length: 23

Content-Type: text/html; charset=UTF-8

[www@linux-node1 ~]$ curl -s --head http://192.168.56.11/index.html|grep "200 OK"

HTTP/1.1 200 OK

上面腳本遠程執行命令或者拷貝 是使用ssh/scp完成的。當服務器稍多的時候,效率並不高。

我在生產環境中是使用 ansible 替代的,個人感覺對於這個腳本來說,就是個並行、串行的區別。

進一步的發展,還可以開發一些WEB界面去結合這個腳本,做到WEB化自動部署,當然也可以使用開源的jenkis。

3、回滾
1.列出回滾版本

2.目標服務器移除集羣

3.執行回滾

4.重啓和測試

5.加入集羣

===========

如果是遇到重大bug

1.列出回滾版本

2.執行回滾(重啓)

==========

非常緊急

1.直接回滾到上個版本(重啓)

自動化部署的核心是創建軟鏈接,同樣在回滾的時候也能實現秒級回滾。

但是在生產環境中,使用軟連接可能會造成WEB打開頁面空白,這點需要注意。

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