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

3 #Node List

5 PRE_LIST="192.168.56.11"

7 GROUP1_LIST="192.168.56.12"

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打开页面空白,这点需要注意。



本文转自 xxl714 51CTO博客,原文链接:http://blog.51cto.com/dreamgirl1314/2046582,如需转载请自行联系原作者

相关文章
|
15天前
|
监控 安全 测试技术
在实施自动化和持续集成的过程中,如何确保代码的安全性和合规性?
在实施自动化和持续集成的过程中,如何确保代码的安全性和合规性?
|
2月前
|
运维 持续交付 开发工具
基础设施即代码(IaC):自动化基础设施管理的未来
基础设施即代码(IaC):自动化基础设施管理的未来
45 0
|
4月前
|
Java Devops 持续交付
探索Java中的Lambda表达式:简化代码,提升效率DevOps实践:持续集成与部署的自动化之路
【8月更文挑战第30天】本文深入探讨了Java 8中引入的Lambda表达式如何改变了我们编写和管理代码的方式。通过简化代码结构,提高开发效率,Lambda表达式已成为现代Java开发不可或缺的一部分。文章将通过实际例子展示Lambda表达式的强大功能和优雅用法。
|
4月前
|
Shell 开发工具 git
使用 Shell 代码简化 Git 步骤
【8月更文挑战第23天】本文介绍通过Shell脚本简化Git操作的方法:1) 使用`gitc "提交信息"`可一键完成代码提交与推送至远程仓库;2) 执行`gitpull`即可从远程仓库拉取最新代码并合并到当前分支;3) 输入`gitnewbranch 分支名称`快速创建并切换到新分支。将这些自定义函数加入`.bashrc`或`.zshrc`等配置文件后,即可随时调用简化版Git命令。
|
4月前
|
C# 开发者 Windows
WPF遇上Office:一场关于Word与Excel自动化操作的技术盛宴,从环境搭建到代码实战,看WPF如何玩转文档处理的那些事儿
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的重要组件,以其强大的图形界面和灵活的数据绑定功能著称。本文通过具体示例代码,介绍如何在 WPF 应用中实现 Word 和 Excel 文档的自动化操作,包括文档的读取、编辑和保存等。首先创建 WPF 项目并设计用户界面,然后在 `MainWindow.xaml.cs` 中编写逻辑代码,利用 `Microsoft.Office.Interop` 命名空间实现 Office 文档的自动化处理。文章还提供了注意事项,帮助开发者避免常见问题。
251 0
|
4月前
|
前端开发 IDE 测试技术
自动化测试中的代码魔法:使用Python和Selenium框架
【8月更文挑战第31天】在软件开发的海洋中,自动化测试是一艘能够带领团队穿越波涛的帆船。本文将引导读者了解如何利用Python语言结合Selenium框架,编写简洁而强大的自动化测试脚本。我们将从搭建开发环境开始,逐步深入到实际案例,最后通过一个简单示例展示如何实现端到端的自动化测试流程。文章不仅提供实用的代码片段,还旨在激发读者对于软件测试深层次思考的热情。
|
5月前
|
Shell Linux
Linux Shell 脚本入门教程:开启你的自动化之旅
Shell是一种计算机程序,它充当了用户与操作系统之间的接口。在Linux系统中,Shell允许用户通过命令行界面(CLI)来控制计算机。Shell脚本则是一种使用Shell语言编写的脚本,它可以自动执行一系列的命令,帮助用户实现任务自动化,提高工作效率。
140 2
|
6月前
|
运维 监控 Devops
基础设施即代码(IaC):自动化运维的新纪元
【6月更文挑战第21天】基础设施即代码(IaC)是将基础设施配置转为代码,实现自动化和标准化运维的实践。它通过文本文件描述基础设施,保证重复性、一致性和自动化部署。IaC提升效率,降低成本,加速产品上市,增强安全性和可移植性,在配置管理、环境管理、CI/CD及监控告警中发挥关键作用,推动DevOps和云时代的创新。
|
6月前
|
Shell UED Python
Shell 循环语句:重复任务的自动化利器
在Shell脚本中,循环语句如`while`和`for`是自动化任务的关键。`while`循环在条件满足时执行,例如计算1到100的和;`for-in`循环遍历列表,可用于迭代指定数值或命令输出,如求1到100的和。`select-in`循环提供交互式菜单,增强脚本用户体验。理解并运用这些循环能提升脚本效率和可读性。现在,动手试试吧!
57 2
|
5月前
|
Kubernetes Serverless 开发工具
代码提交即部署:Argo Workflows与EventBridge构建自动化CI
ACK One Serverless Argo工作流和EventBridge简单快速、高效、低成本地交付您的应用,为您实现代码提交即构建/交付的自动化CI系统。
下一篇
无影云桌面