设为首页 收藏本站
查看: 599|回复: 0

shell实现代码自动化部署

[复制链接]

尚未签到

发表于 2018-8-25 06:40:30 | 显示全部楼层 |阅读模式
  通过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>
  -rwx------ 1 www www  397 Jul 31 22:44>  将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;
  [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打开页面空白,这点需要注意。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-556089-1-1.html 上篇帖子: 获取wiki某网页信息shell即获取wiki子目录信息-shell 下篇帖子: Jmeter之Bean shell使用(一)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表