本文共 6637 字,大约阅读时间需要 22 分钟。
通过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/bash2 3 #Node List4 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 Variable12 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 env22 23 SHELL_NAME="/deploy1.sh"24 25 SHELL_DIR="/home/www/"26 27 SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"28 29 #Code ENV30 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=$156 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_build98 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_NAME122 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;do134 135 scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot136 137 done138 139 for node in $GROUP1_LIST;do140 141 scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot142 143 done144 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=$1170 171 curl -s --head $URL|grep "200 OK"172 173 if [ $? -ne 0 ];then174 175 shell_unlock;176 177 writelog "test error" && exit;178 179 fi180 181 }182 183 pre_test(){ 184 185 url_test ""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;do200 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.xml208 209 }210 211 212 213 group1_test(){ 214 215 url_test ""216 217 echo "add to cluster"218 219 }220 221 rollback_fun(){ 222 223 for node in $ROLLBACK_LIST;do224 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 ];then234 235 shell_unlock; 236 237 echo "please input rollback version" && exit;238 239 fi240 241 case $1 in242 243 list)244 245 ls -l /opt/webroot/.tar.gz246 247 ;;248 249 )250 251 rollback_fun $1252 253 esac 254 255 }256 257 258 259 main(){ 260 261 if [ -f $LOCK_FILE ];then262 263 echo "Deploy is running" && exit;264 265 fi266 267 DEPLOY_METHON=$1268 269 ROLLBACK_VER=$2270 271 case $DEPLOY_METHON in272 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/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 "200 OK"
HTTP/1.1 200 OK
上面脚本远程执行命令或者拷贝 是使用ssh/scp完成的。当服务器稍多的时候,效率并不高。
我在生产环境中是使用 ansible 替代的,个人感觉对于这个脚本来说,就是个并行、串行的区别。
进一步的发展,还可以开发一些WEB界面去结合这个脚本,做到WEB化自动部署,当然也可以使用开源的jenkis。
3、回滚
1.列出回滚版本2.目标服务器移除集群
3.执行回滚
4.重启和测试
5.加入集群
===========
如果是遇到重大bug
1.列出回滚版本
2.执行回滚(重启)
==========
非常紧急
1.直接回滚到上个版本(重启)
自动化部署的核心是创建软链接,同样在回滚的时候也能实现秒级回滚。
但是在生产环境中,使用软连接可能会造成WEB打开页面空白,这点需要注意。
转载于:https://blog.51cto.com/dreamgirl1314/2046582