zoukankan      html  css  js  c++  java
  • 通过shell脚本实现代码自动化部署

    通过shell脚本实现代码自动化部署

    一、传统部署方式及优缺点

    1.传统部署方式

    1)纯手工scp

    2)纯手工登录git pullsvn update

    3)纯手工xftp往上拉

    4)开发给打一个压缩包,rz上去;解压

    2.缺点

    1)全程运维参与,占用大量时间

    2)上线速度慢

    3)人为失误多,管理混乱

    4)回滚慢,不及时

    二、环境规划

    1、开发环境--开发者本地有自己的环境。

    运维需要设置的开发环境,大家共用的服务。

    2、测试环境:功能测试环境和性能测试环境。

    3、预生产环境:生产环境集群中的某一个节点。

    4、生产环境:直接对用户提供服务的环境。

    测试环境与生产环境的数据库不一致时,可能会导致测试的功能不全面,在测试环境测无问题,放在线上可能出现问题

    三、需求分析

    一、功能需求需求

    一个集群有十个节点

    1.实现 一键部署10个节点

    2.一键回滚到任意版本

    3.一键回滚到上个版本

    二、部署需求

    部署:

    1.代码在哪里:svngit

    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="${PRO_NAME}"_"$API_VER"_"${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
    View Code

    测试方式

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

     





  • 相关阅读:
    消息中间件(一)MQ详解及四大MQ比较
    SIP协议
    PAT (Basic Level) Practice 1008 数组元素循环右移问题
    LeetCode-Algorithms 1. 两数之和
    PAT (Basic Level) Practice 1040 有几个PAT
    PAT (Basic Level) Practice 1023 组个最小数
    PAT (Basic Level) Practice 1021 个位数统计
    PAT (Basic Level) Practice 1007 素数对猜想
    PAT (Basic Level) Practice 1006 换个格式输出整数
    PAT (Basic Level) Practice 1004 成绩排名
  • 原文地址:https://www.cnblogs.com/yangliheng/p/5783852.html
Copyright © 2011-2022 走看看