天天看點

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"

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

我在生産環境中是使用 ansible 替代的,個人感覺對于這個腳本來說,就是個并行、串行的差別。

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

3、復原

1.列出復原版本

2.目标伺服器移除叢集

3.執行復原

4.重新開機和測試

5.加入叢集

===========

如果是遇到重大bug

2.執行復原(重新開機)

==========

非常緊急

1.直接復原到上個版本(重新開機)

自動化部署的核心是建立軟連結,同樣在復原的時候也能實作秒級復原。

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